[Commits] 352c7e0: MDEV-15905 select json_value('{"b":true}', '$.b')=1 --> false with
by holyfootï¼ askmonty.org 17 Jun '18
by holyfootï¼ askmonty.org 17 Jun '18
17 Jun '18
revision-id: 352c7e0dfaa0f121c5b35e1d9fafb9ec8897e768 (mariadb-10.2.15-61-g352c7e0)
parent(s): b8514c94f61f37757a24df1c6b9a7dd530b3de12
committer: Alexey Botchkov
timestamp: 2018-06-17 17:15:21 +0400
message:
MDEV-15905 select json_value('{"b":true}','$.b')=1 --> false with
"Truncated incorrect DOUBLE value: 'true'".
JSON_VALUE_TRUE and JSON_VALUE_FALSE should be handled specifically
in Item_json_value.
---
mysql-test/r/func_json.result | 3 +++
mysql-test/t/func_json.test | 7 +++++++
sql/item_jsonfunc.cc | 21 ++++++++++++++++++++-
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/mysql-test/r/func_json.result b/mysql-test/r/func_json.result
index 2ffeb83..77a4241 100644
--- a/mysql-test/r/func_json.result
+++ b/mysql-test/r/func_json.result
@@ -739,3 +739,6 @@ drop table t1;
select json_extract('{"test":8.437e-5}','$.test');
json_extract('{"test":8.437e-5}','$.test')
8.437e-5
+select json_value('{"b":true}','$.b')=1;
+json_value('{"b":true}','$.b')=1
+1
diff --git a/mysql-test/t/func_json.test b/mysql-test/t/func_json.test
index a6ae934..b74915c 100644
--- a/mysql-test/t/func_json.test
+++ b/mysql-test/t/func_json.test
@@ -398,3 +398,10 @@ drop table t1;
select json_extract('{"test":8.437e-5}','$.test');
+#
+# MDEV-15905 select json_value('{"b":true}','$.b')=1 --> false with
+# "Truncated incorrect DOUBLE value: 'true'"
+#
+select json_value('{"b":true}','$.b')=1;
+
+
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index 72aeac5..c8cda66 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -513,6 +513,10 @@ String *Item_func_json_value::val_str(String *str)
bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res,
int *error)
{
+ CHARSET_INFO *json_cs;
+ const uchar *js;
+ uint js_len;
+
if (!json_value_scalar(je))
{
/* We only look for scalar values! */
@@ -521,7 +525,22 @@ bool Item_func_json_value::check_and_get_value(json_engine_t *je, String *res,
return true;
}
- return st_append_json(res, je->s.cs, je->value, je->value_len);
+ if (je->value_type == JSON_VALUE_TRUE ||
+ je->value_type == JSON_VALUE_FALSE)
+ {
+ json_cs= &my_charset_utf8mb4_bin;
+ js= (const uchar *) ((je->value_type == JSON_VALUE_TRUE) ? "1" : "0");
+ js_len= 1;
+ }
+ else
+ {
+ json_cs= je->s.cs;
+ js= je->value;
+ js_len= je->value_len;
+ }
+
+
+ return st_append_json(res, json_cs, js, js_len);
}
1
0
15 Jun '18
revision-id: 0f00072a585b7ef02f02aa73b9e622a3b4deacca
parent(s): 4461b0f9b301233b245853b9b71b3770c24c5aac
committer: Sergei Petrunia
branch nick: 10.3-r2
timestamp: 2018-06-15 17:13:31 +0300
message:
Fix a typo in get_best_ror_intersect
cpk_scan should not be used if using it increases the cost of the query
plan.
---
sql/opt_range.cc | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 8422917..d3f8acd 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -6529,6 +6529,8 @@ TRP_ROR_INTERSECT *get_best_ror_intersect(const PARAM *param, SEL_TREE *tree,
if (ror_intersect_add(intersect, cpk_scan, TRUE) &&
(intersect->total_cost < min_cost))
intersect_best= intersect; //just set pointer here
+ else
+ cpk_scan= 0; // Don't use cpk_scan
}
else
cpk_scan= 0; // Don't use cpk_scan
1
0
[Commits] 87e97b6: MDEV-16420 View stop working after upgrade from 10.1.15 to 10.3.7
by IgorBabaev 14 Jun '18
by IgorBabaev 14 Jun '18
14 Jun '18
revision-id: 87e97b6c74359e3d2fe9094f1198d37b6e68792e (mariadb-10.3.7-48-g87e97b6)
parent(s): 4787913db0b49b4a48e337e6b76b8b6c8233a941
author: Igor Babaev
committer: Igor Babaev
timestamp: 2018-06-14 15:48:57 -0700
message:
MDEV-16420 View stop working after upgrade from 10.1.15 to 10.3.7
This bug happened for queries that used a materialized view that
renamed columns of the specifying query in an inner table of
an outer join. For such a query name resolution for a column
belonging the view could fail if the underlying column was
non-nullable.
When creating the defintion of the the temporary table for
the materialized view used in the inner part of an outer join
the definition of the non-nullable columns are created by the
function create_tmp_field_from_item() that names the columns
according to the names of the underlying columns. So these names
should be changed for the view column names.
This bug cannot be reproduced in 10.2 because there setup_fields()
called when preparing joins in the view specification effectively
renames the underlying columns in the function find_field_in_view().
In 10.3 this renaming was removed as improper
(see Monty's commit b478276b04d4dd122e2ed4d4e2cd7eb69c0fb2d2).
---
mysql-test/main/derived_view.result | 40 +++++++++++++++++++++++++++++++++++++
mysql-test/main/derived_view.test | 24 ++++++++++++++++++++++
sql/sql_select.cc | 3 +++
3 files changed, 67 insertions(+)
diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result
index 6c4b331..86dd73f 100644
--- a/mysql-test/main/derived_view.result
+++ b/mysql-test/main/derived_view.result
@@ -2977,5 +2977,45 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 /* select#1 */ select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#3 */ select `test`.`t2`.`c2` from `test`.`t2` where <cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`))
DROP TABLE t1, t2;
+#
+# Bug mdev-16420: materialized view that renames columns
+# in inner part of outer join
+#
+CREATE TABLE t1 (id int, PRIMARY KEY (id));
+INSERT INTO t1 VALUES (2), (3), (7), (1);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v2 AS SELECT v1.id AS order_pk FROM v1 GROUP BY v1.id;
+CREATE VIEW v3 AS
+SELECT t.id AS order_pk FROM (SELECT * FROM t1) AS t GROUP BY t.id;
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+id order_pk
+1 1
+2 2
+3 3
+7 7
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00
+2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v2`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v2` on(`v2`.`order_pk` = `test`.`t1`.`id`) where 1
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+id order_pk
+1 1
+2 2
+3 3
+7 7
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00
+2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v3`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v3` on(`v3`.`order_pk` = `test`.`t1`.`id`) where 1
+DROP VIEW v1,v2,v3;
+DROP TABLE t1;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test
index 9b0cf9d..68f334e 100644
--- a/mysql-test/main/derived_view.test
+++ b/mysql-test/main/derived_view.test
@@ -1949,6 +1949,30 @@ eval EXPLAIN EXTENDED $q;
DROP TABLE t1, t2;
+--echo #
+--echo # Bug mdev-16420: materialized view that renames columns
+--echo # in inner part of outer join
+--echo #
+
+CREATE TABLE t1 (id int, PRIMARY KEY (id));
+INSERT INTO t1 VALUES (2), (3), (7), (1);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v2 AS SELECT v1.id AS order_pk FROM v1 GROUP BY v1.id;
+CREATE VIEW v3 AS
+SELECT t.id AS order_pk FROM (SELECT * FROM t1) AS t GROUP BY t.id;
+
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+
+DROP VIEW v1,v2,v3;
+DROP TABLE t1;
+
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 52041cc..0bc19ad 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -16811,7 +16811,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
if (result && modify_item)
field->result_field= result;
if (orig_item)
+ {
item->maybe_null= save_maybe_null;
+ result->field_name= orig_item->name;
+ }
}
else if (table_cant_handle_bit_fields && field->field->type() ==
MYSQL_TYPE_BIT)
1
0
[Commits] d816a24: MDEV-16420 View stop working after upgrade from 10.1.15 to 10.3.7
by IgorBabaev 14 Jun '18
by IgorBabaev 14 Jun '18
14 Jun '18
revision-id: d816a2485dc9ee17c51f9b14d356d9f8445f098d (mariadb-10.3.7-47-gd816a24)
parent(s): b52bb6eb82db8f3bff88efbf0876d364a3826cc1
author: Igor Babaev
committer: Igor Babaev
timestamp: 2018-06-14 14:30:38 -0700
message:
MDEV-16420 View stop working after upgrade from 10.1.15 to 10.3.7
This bug happened for queries that used a materialized view that
renamed columns of the specifying query in an inner table of
an outer join. For such a query name resolution for a column
belonging the view could fail if the underlying column was
non-nullable.
When creating the defintion of the the temporary table for
the materialized view used in the inner part of an outer join
the definition of the non-nullable columns are created by the
function create_tmp_field_from_item() that names the columns
according to the names of the underlying columns. So these names
should be changed for the view column names.
---
mysql-test/main/derived_view.result | 40 +++++++++++++++++++++++++++++++++++++
mysql-test/main/derived_view.test | 24 ++++++++++++++++++++++
sql/sql_select.cc | 3 +++
3 files changed, 67 insertions(+)
diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result
index 6c4b331..86dd73f 100644
--- a/mysql-test/main/derived_view.result
+++ b/mysql-test/main/derived_view.result
@@ -2977,5 +2977,45 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 /* select#1 */ select straight_join `test`.`t1`.`c1` AS `c1` from `test`.`t1` where <in_optimizer>(`test`.`t1`.`c1`,<exists>(/* select#3 */ select `test`.`t2`.`c2` from `test`.`t2` where <cache>(`test`.`t1`.`c1`) = `test`.`t2`.`c2`))
DROP TABLE t1, t2;
+#
+# Bug mdev-16420: materialized view that renames columns
+# in inner part of outer join
+#
+CREATE TABLE t1 (id int, PRIMARY KEY (id));
+INSERT INTO t1 VALUES (2), (3), (7), (1);
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v2 AS SELECT v1.id AS order_pk FROM v1 GROUP BY v1.id;
+CREATE VIEW v3 AS
+SELECT t.id AS order_pk FROM (SELECT * FROM t1) AS t GROUP BY t.id;
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+id order_pk
+1 1
+2 2
+3 3
+7 7
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00
+2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v2`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v2` on(`v2`.`order_pk` = `test`.`t1`.`id`) where 1
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+id order_pk
+1 1
+2 2
+3 3
+7 7
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY t1 index NULL PRIMARY 4 NULL 4 100.00 Using index
+1 PRIMARY <derived2> ref key0 key0 5 test.t1.id 2 100.00
+2 DERIVED t1 index PRIMARY PRIMARY 4 NULL 4 100.00 Using index; Using filesort
+Warnings:
+Note 1003 /* select#1 */ select `test`.`t1`.`id` AS `id`,`v3`.`order_pk` AS `order_pk` from `test`.`t1` left join `test`.`v3` on(`v3`.`order_pk` = `test`.`t1`.`id`) where 1
+DROP VIEW v1,v2,v3;
+DROP TABLE t1;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test
index 9b0cf9d..68f334e 100644
--- a/mysql-test/main/derived_view.test
+++ b/mysql-test/main/derived_view.test
@@ -1949,6 +1949,30 @@ eval EXPLAIN EXTENDED $q;
DROP TABLE t1, t2;
+--echo #
+--echo # Bug mdev-16420: materialized view that renames columns
+--echo # in inner part of outer join
+--echo #
+
+CREATE TABLE t1 (id int, PRIMARY KEY (id));
+INSERT INTO t1 VALUES (2), (3), (7), (1);
+
+CREATE VIEW v1 AS SELECT * FROM t1;
+CREATE VIEW v2 AS SELECT v1.id AS order_pk FROM v1 GROUP BY v1.id;
+CREATE VIEW v3 AS
+SELECT t.id AS order_pk FROM (SELECT * FROM t1) AS t GROUP BY t.id;
+
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v2 ON t1.id=v2.order_pk;
+
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+EXPLAIN EXTENDED
+SELECT * FROM t1 LEFT JOIN v3 ON t1.id=v3.order_pk;
+
+DROP VIEW v1,v2,v3;
+DROP TABLE t1;
+
# The following command must be the last one the file
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 52041cc..0bc19ad 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -16811,7 +16811,10 @@ Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
if (result && modify_item)
field->result_field= result;
if (orig_item)
+ {
item->maybe_null= save_maybe_null;
+ result->field_name= orig_item->name;
+ }
}
else if (table_cant_handle_bit_fields && field->field->type() ==
MYSQL_TYPE_BIT)
1
0
[Commits] 71c318372e9: MDEV-11071: Assertion `thd->transaction.stmt.is_empty()' failed in Locked_tables_list::unlock_locked_table
by Oleksandr Byelkin 14 Jun '18
by Oleksandr Byelkin 14 Jun '18
14 Jun '18
revision-id: 71c318372e919e21ccf73e54553fffecb1040f75 (mariadb-10.2.15-56-g71c318372e9)
parent(s): a79b033b359b882f2fe88051781c6e850bd71780
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-06-14 17:58:33 +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 | 60 +++++++++------
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 | 71 ++++++++++-------
sql/item_subselect.h | 22 +++---
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 | 14 +++-
26 files changed, 778 insertions(+), 518 deletions(-)
diff --git a/mysql-test/r/alter_table.result b/mysql-test/r/alter_table.result
index 89bf9ed638e..2bea055df4c 100644
--- a/mysql-test/r/alter_table.result
+++ b/mysql-test/r/alter_table.result
@@ -2369,5 +2369,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 eddc9f704da..092569dcadb 100644
--- a/mysql-test/t/alter_table.test
+++ b/mysql-test/t/alter_table.test
@@ -1931,6 +1931,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 423ee4cc089..5ed45c69e96 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -4211,7 +4211,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 f552a3eca58..b86c0079bce 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,8 @@ 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;
+ return setup_args_and_comparator(current_thd, &cmp);
}
@@ -1156,12 +1156,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;
}
@@ -1780,10 +1781,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()
@@ -1880,7 +1882,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();
@@ -1898,10 +1900,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++)
@@ -1942,6 +1947,7 @@ void Item_func_interval::fix_length_and_dec()
with_sum_func= with_sum_func || row->with_sum_func;
with_param= with_param || row->with_param;
with_field= with_field || row->with_field;
+ return FALSE;
}
@@ -2102,7 +2108,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;
@@ -2113,13 +2119,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
@@ -2144,6 +2150,7 @@ void Item_func_between::fix_length_and_dec()
m_compare_type= INT_RESULT; // Works for all types.
}
}
+ return FALSE;
}
@@ -2441,7 +2448,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.
@@ -2452,15 +2459,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);
}
@@ -2574,7 +2581,7 @@ void Item_func_nullif::update_used_tables()
-void
+bool
Item_func_nullif::fix_length_and_dec()
{
/*
@@ -2724,6 +2731,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());
@@ -2737,7 +2746,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.
@@ -2777,6 +2787,7 @@ Item_func_nullif::fix_length_and_dec()
*/
if (args[0] == m_arg0)
m_arg0= NULL;
+ return FALSE;
}
@@ -3158,7 +3169,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)
@@ -3175,7 +3186,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);
@@ -3189,7 +3200,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))
@@ -3222,7 +3233,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++)
@@ -3233,10 +3244,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;
}
@@ -4117,7 +4129,6 @@ static int srtcmp_in(CHARSET_INFO *cs, const String *x,const String *y)
(uchar *) y->ptr(),y->length());
}
-
/*
Create 'array' for this IN predicate with the respect to its result type
and put values from <in value list> in 'array'.
@@ -4178,7 +4189,7 @@ bool Item_func_in::create_array(THD *thd)
}
-void Item_func_in::fix_length_and_dec()
+bool Item_func_in::fix_length_and_dec()
{
Item **arg, **arg_end;
bool const_itm= 1;
@@ -4190,7 +4201,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++)
{
@@ -4239,7 +4250,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)
@@ -4250,12 +4261,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;
@@ -4272,6 +4285,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;
}
}
}
@@ -4306,7 +4321,7 @@ void Item_func_in::fix_length_and_dec()
}
}
if (create_array(thd))
- return;
+ return TRUE;
}
else
{
@@ -4314,7 +4329,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])
@@ -4322,11 +4337,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;
}
@@ -4617,7 +4633,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;
}
@@ -5656,16 +5673,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;
}
@@ -5689,14 +5706,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;
}
@@ -6638,7 +6656,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;
}
@@ -6724,11 +6743,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 78a9e384b55..a59432058eb 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);
- fix_char_length(2); // returns "1" or "0" or "-1"
+ if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
+ return TRUE;
+ fix_char_length(2);
+ 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"; }
@@ -1649,7 +1655,7 @@ class Item_func_in :public Item_func_opt_neg
longlong val_int();
bool fix_fields(THD *, Item **);
bool create_array(THD *thd);
- void fix_length_and_dec();
+ bool fix_length_and_dec();
void cleanup()
{
uint i;
@@ -1710,7 +1716,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]; }
};
@@ -1724,7 +1730,7 @@ class in_row :public in_vector
void set(uint pos,Item *item);
uchar *get_value(Item *item);
friend bool Item_func_in::create_array(THD *thd);
- 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; }
};
@@ -1756,7 +1762,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);
};
@@ -1980,10 +1990,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();
@@ -2104,7 +2114,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)
@@ -2142,7 +2152,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); }
@@ -2378,7 +2388,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 cd23c0b64fe..4bdb18ad95a 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -237,8 +237,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;
@@ -733,10 +732,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;
}
@@ -755,7 +756,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()));
@@ -791,7 +792,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);
}
@@ -801,7 +802,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()));
@@ -832,7 +833,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);
}
@@ -1417,12 +1418,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;
}
@@ -1720,11 +1723,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:
{
@@ -1755,7 +1759,7 @@ void Item_func_div::fix_length_and_dec()
DBUG_ASSERT(0);
}
maybe_null= 1; // devision by zero
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1831,7 +1835,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 */
@@ -1842,6 +1846,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;
}
@@ -1925,11 +1930,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;
}
@@ -1976,10 +1983,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;
@@ -2005,7 +2013,7 @@ void Item_func_neg::fix_length_and_dec()
}
}
unsigned_flag= 0;
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2045,10 +2053,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;
}
@@ -2280,7 +2290,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()));
@@ -2328,7 +2338,7 @@ void Item_func_int_val::fix_length_and_dec()
result_type() == INT_RESULT ? "INT_RESULT" :
"--ILLEGAL!!!--")));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -2426,7 +2436,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;
@@ -2444,12 +2454,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)
@@ -2462,7 +2472,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()) {
@@ -2503,6 +2513,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,
@@ -2727,7 +2738,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;
@@ -2838,6 +2849,7 @@ void Item_func_min_max::fix_length_and_dec()
set_handler_by_field_type(MYSQL_TYPE_DOUBLE);
break;
}
+ return FALSE;
}
@@ -3088,10 +3100,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);
}
@@ -3208,14 +3220,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;
}
@@ -3262,7 +3275,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
@@ -3284,7 +3297,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=',';
@@ -3490,7 +3503,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;
@@ -3828,13 +3842,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)
@@ -4721,7 +4735,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;
@@ -4735,6 +4749,7 @@ Item_func_set_user_var::fix_length_and_dec()
args[0]->collation.collation);
}
unsigned_flag= args[0]->unsigned_flag;
+ return FALSE;
}
@@ -5573,7 +5588,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;
@@ -5623,6 +5638,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;
}
@@ -5765,7 +5781,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;
@@ -5777,7 +5793,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;
@@ -5841,6 +5857,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;
}
@@ -6617,7 +6634,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");
@@ -6625,7 +6642,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);
}
@@ -6964,9 +6981,10 @@ 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 3787b4f4924..0969cf2e3f0 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -399,8 +399,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; }
};
@@ -577,7 +577,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();
};
@@ -592,7 +592,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; }
};
@@ -619,7 +619,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; }
};
@@ -630,7 +630,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)
@@ -656,7 +656,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);
@@ -667,6 +667,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(); }
@@ -713,7 +714,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; }
@@ -733,7 +734,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; }
@@ -777,7 +778,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); }
};
@@ -811,7 +812,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); }
@@ -826,7 +827,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);
@@ -850,7 +851,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)
@@ -873,7 +874,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;}
@@ -891,7 +892,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)
@@ -905,10 +906,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;
}
};
@@ -1066,7 +1068,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();
};
@@ -1111,7 +1113,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); }
};
@@ -1163,8 +1165,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); }
};
@@ -1194,7 +1196,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
@@ -1237,13 +1239,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); }
@@ -1257,7 +1260,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); }
};
@@ -1280,7 +1283,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); }
};
@@ -1291,7 +1294,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;
@@ -1313,7 +1316,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); }
@@ -1329,7 +1332,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); }
};
@@ -1342,7 +1345,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); }
};
@@ -1369,7 +1372,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); }
};
@@ -1381,7 +1384,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)
{
@@ -1418,7 +1421,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); }
};
@@ -1469,12 +1472,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)
@@ -1494,7 +1498,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)
{
@@ -1652,7 +1656,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); }
};
@@ -1671,7 +1675,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); }
};
@@ -1690,7 +1694,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); }
};
@@ -1730,7 +1734,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); }
};
@@ -1782,7 +1786,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 */
@@ -1797,7 +1801,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;
@@ -1819,7 +1823,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;
@@ -1847,7 +1851,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);
@@ -1865,7 +1869,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);
@@ -1956,7 +1960,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 ?
@@ -1997,7 +2001,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
@@ -2079,7 +2083,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; }
@@ -2218,7 +2222,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);
@@ -2234,7 +2242,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);
@@ -2286,7 +2298,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);
@@ -2414,7 +2426,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()
@@ -2450,7 +2462,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);
@@ -2469,8 +2481,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)
{
@@ -2491,7 +2503,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 a8e83d298f6..8a9dd083911 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -305,10 +305,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
-
+ res= TRUE;
+ goto end;
+ }
+ if (fix_length_and_dec())
+ {
+ res= TRUE;
goto end;
}
- fix_length_and_dec();
}
else
goto end;
@@ -905,9 +909,11 @@ 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);
+ if (engine->fix_length_and_dec(0))
+ return TRUE;
+ return FALSE;
}
@@ -1195,18 +1201,19 @@ 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)
{
- engine->fix_length_and_dec(row= &value);
+ if (engine->fix_length_and_dec(row= &value))
+ return TRUE;
}
else
{
if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) *
- max_columns)))
- return;
- engine->fix_length_and_dec(row);
+ max_columns)) ||
+ engine->fix_length_and_dec(row))
+ return TRUE;
value= *row;
}
unsigned_flag= value->unsigned_flag;
@@ -1222,6 +1229,7 @@ void Item_singlerow_subselect::fix_length_and_dec()
for (uint i= 0; i < max_columns; i++)
row[i]->maybe_null= TRUE;
}
+ return FALSE;
}
@@ -1506,7 +1514,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();
@@ -1514,14 +1522,17 @@ void Item_exists_subselect::fix_length_and_dec()
We need only 1 row to determine existence (i.e. any EXISTS that is not
an IN always requires LIMIT 1)
*/
+ Item *item= new (thd->mem_root) Item_int(thd, (int32) 1);
+ if (!item)
+ DBUG_RETURN(TRUE);
thd->change_item_tree(&unit->global_parameters()->select_limit,
- new (thd->mem_root) Item_int(thd, (int32) 1));
+ item);
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();
@@ -1529,7 +1540,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);
}
@@ -3712,11 +3723,11 @@ bool subselect_single_select_engine::no_rows()
}
-/*
- makes storage for the output values for the subquery and calcuates
+/**
+ Makes storage for the output values for the subquery and calcuates
their data and column types and their nullability.
-*/
-void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
+*/
+bool subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
{
Item *sel_item;
List_iterator_fast<Item> li(item_list);
@@ -3732,44 +3743,51 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item->unsigned_flag= sel_item->unsigned_flag;
maybe_null= sel_item->maybe_null;
if (!(row[i]= Item_cache::get_cache(thd, sel_item, sel_item->cmp_type())))
- return;
+ return TRUE;
row[i]->setup(thd, sel_item);
//psergey-backport-timours: row[i]->store(sel_item);
}
if (item_list.elements > 1)
cmp_type= res_type= ROW_RESULT;
+ return FALSE;
}
-void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
+bool subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
{
DBUG_ASSERT(row || select_lex->item_list.elements==1);
- set_row(select_lex->item_list, row);
+ if (set_row(select_lex->item_list, row))
+ return TRUE;
item->collation.set(row[0]->collation);
if (cols() != 1)
maybe_null= 0;
+ return FALSE;
}
-void subselect_union_engine::fix_length_and_dec(Item_cache **row)
+bool subselect_union_engine::fix_length_and_dec(Item_cache **row)
{
DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
if (unit->first_select()->item_list.elements == 1)
{
- set_row(unit->types, row);
+ if (set_row(unit->types, row))
+ return TRUE;
item->collation.set(row[0]->collation);
}
else
{
bool maybe_null_saved= maybe_null;
- set_row(unit->types, row);
+ if (set_row(unit->types, row))
+ return TRUE;
maybe_null= maybe_null_saved;
}
+ return FALSE;
}
-void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
+bool subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
{
//this never should be called
DBUG_ASSERT(0);
+ return FALSE;
}
int read_first_record_seq(JOIN_TAB *tab);
@@ -5602,9 +5620,10 @@ void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
));
}
-void subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
+bool subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
{
DBUG_ASSERT(FALSE);
+ return FALSE;
}
void subselect_hash_sj_engine::exclude()
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 7e99e2c3075..bd6a1bdc498 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
{
@@ -810,7 +810,7 @@ class subselect_engine: public Sql_alloc
void set_thd(THD *thd_arg);
THD * get_thd() { return thd ? thd : current_thd; }
virtual int prepare(THD *)= 0;
- virtual void fix_length_and_dec(Item_cache** row)= 0;
+ virtual bool fix_length_and_dec(Item_cache** row)= 0;
/*
Execute the engine
@@ -854,7 +854,7 @@ class subselect_engine: public Sql_alloc
virtual int get_identifier() { DBUG_ASSERT(0); return 0; }
virtual void force_reexecution() {}
protected:
- void set_row(List<Item> &item_list, Item_cache **row);
+ bool set_row(List<Item> &item_list, Item_cache **row);
};
@@ -870,7 +870,7 @@ class subselect_single_select_engine: public subselect_engine
Item_subselect *item);
void cleanup();
int prepare(THD *thd);
- void fix_length_and_dec(Item_cache** row);
+ bool fix_length_and_dec(Item_cache** row);
int exec();
uint cols();
uint8 uncacheable();
@@ -905,7 +905,7 @@ class subselect_union_engine: public subselect_engine
Item_subselect *item);
void cleanup();
int prepare(THD *);
- void fix_length_and_dec(Item_cache** row);
+ bool fix_length_and_dec(Item_cache** row);
int exec();
uint cols();
uint8 uncacheable();
@@ -963,7 +963,7 @@ class subselect_uniquesubquery_engine: public subselect_engine
~subselect_uniquesubquery_engine();
void cleanup();
int prepare(THD *);
- void fix_length_and_dec(Item_cache** row);
+ bool fix_length_and_dec(Item_cache** row);
int exec();
uint cols() { return 1; }
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; }
@@ -1112,7 +1112,7 @@ class subselect_hash_sj_engine : public subselect_engine
TODO: factor out all these methods in a base subselect_index_engine class
because all of them have dummy implementations and should never be called.
*/
- void fix_length_and_dec(Item_cache** row);//=>base class
+ bool fix_length_and_dec(Item_cache** row);//=>base class
void exclude(); //=>base class
//=>base class
bool change_result(Item_subselect *si,
@@ -1385,7 +1385,7 @@ class subselect_partial_match_engine : public subselect_engine
uint count_columns_with_nulls_arg);
int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; }
int exec();
- void fix_length_and_dec(Item_cache**) {}
+ bool fix_length_and_dec(Item_cache**) { return FALSE; }
uint cols() { /* TODO: what is the correct value? */ return 1; }
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
void exclude() {}
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index cb150db3031..9e59ec4e373 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -1132,9 +1132,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);
@@ -1189,9 +1188,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];
@@ -1329,7 +1327,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;
@@ -1364,7 +1362,7 @@ void Item_sum_sum::fix_length_and_dec()
"--ILLEGAL!!!--"),
max_length,
(int)decimals));
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
}
@@ -1664,9 +1662,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)
@@ -1686,6 +1685,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;
}
@@ -1884,7 +1884,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;
@@ -1919,7 +1919,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);
}
@@ -2989,13 +2989,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 52738bfab87..7cb07af440b 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 ee5ba4ade54..bc2b817fbca 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -13525,7 +13525,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 dd21c8fb107..9a87b0e7461 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4896,7 +4896,12 @@ 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)
+ /*
+ TODO: remove this check of thd->is_error() (now it intercept
+ errors in some val_*() methoids and bring some single place to
+ such error interception).
+ */
+ if (!file || thd->is_error())
goto err;
if (rea_create_table(thd, frm, path, db, table_name, create_info,
file, frm_only))
@@ -7398,10 +7403,15 @@ static bool mysql_inplace_alter_table(THD *thd,
/*
Replace the old .FRM with the new .FRM, but keep the old name for now.
Rename to the new name (if needed) will be handled separately below.
+
+ TODO: remove this check of thd->is_error() (now it intercept
+ errors in some val_*() methoids and bring some single place to
+ such error interception).
*/
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
revision-id: fa98ae28f5e7025e0cd1ca19c71863fd083570b7 (mariadb-10.2.14-79-gfa98ae28f5e)
parent(s): 46e0c8a921978e7b95adf3f17f3c85b18d9f9ef6
author: Oleksandr Byelkin
committer: Oleksandr Byelkin
timestamp: 2018-06-14 17:40:10 +0200
message:
Postreview fix
---
sql/item_cmpfunc.cc | 3 +--
sql/item_cmpfunc.h | 2 +-
sql/item_subselect.cc | 52 +++++++++++++++++++++++++++++++++------------------
sql/item_subselect.h | 14 +++++++-------
sql/sql_table.cc | 11 +++++++----
5 files changed, 50 insertions(+), 32 deletions(-)
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 46cf412e229..55840b40ed2 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -536,8 +536,7 @@ bool Item_bool_rowready_func2::fix_length_and_dec()
*/
if (!args[0] || !args[1])
return FALSE;
- bool res= setup_args_and_comparator(current_thd, &cmp);
- return res;
+ return setup_args_and_comparator(current_thd, &cmp);
}
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 5efb98bc81d..0d3f20f1d63 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -915,7 +915,7 @@ class Item_func_strcmp :public Item_int_func
{
if (agg_arg_charsets_for_comparison(cmp_collation, args, 2))
return TRUE;
- fix_char_length(2); // returns "1" or "0" or "-1"
+ fix_char_length(2);
return FALSE;
}
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index ca49e06a9e7..24121292869 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -304,11 +304,14 @@ bool Item_subselect::fix_fields(THD *thd_param, Item **ref)
if (engine->cols() > max_columns)
{
my_error(ER_OPERAND_COLUMNS, MYF(0), 1);
-
+ res= TRUE;
goto end;
}
if (fix_length_and_dec())
+ {
+ res= TRUE;
goto end;
+ }
}
else
goto end;
@@ -907,7 +910,8 @@ Item::Type Item_subselect::type() const
bool Item_subselect::fix_length_and_dec()
{
- engine->fix_length_and_dec(0);
+ if (engine->fix_length_and_dec(0))
+ return TRUE;
return FALSE;
}
@@ -1200,14 +1204,15 @@ bool Item_singlerow_subselect::fix_length_and_dec()
{
if ((max_columns= engine->cols()) == 1)
{
- engine->fix_length_and_dec(row= &value);
+ if (engine->fix_length_and_dec(row= &value))
+ return TRUE;
}
else
{
if (!(row= (Item_cache**) current_thd->alloc(sizeof(Item_cache*) *
- max_columns)))
+ max_columns)) ||
+ engine->fix_length_and_dec(row))
return TRUE;
- engine->fix_length_and_dec(row);
value= *row;
}
unsigned_flag= value->unsigned_flag;
@@ -1516,8 +1521,11 @@ bool Item_exists_subselect::fix_length_and_dec()
We need only 1 row to determine existence (i.e. any EXISTS that is not
an IN always requires LIMIT 1)
*/
+ Item *item= new (thd->mem_root) Item_int(thd, (int32) 1);
+ if (!item)
+ DBUG_RETURN(TRUE);
thd->change_item_tree(&unit->global_parameters()->select_limit,
- new (thd->mem_root) Item_int(thd, (int32) 1));
+ item);
DBUG_PRINT("info", ("Set limit to 1"));
DBUG_RETURN(FALSE);
}
@@ -3714,11 +3722,11 @@ bool subselect_single_select_engine::no_rows()
}
-/*
- makes storage for the output values for the subquery and calcuates
+/**
+ Makes storage for the output values for the subquery and calcuates
their data and column types and their nullability.
-*/
-void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
+*/
+bool subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
{
Item *sel_item;
List_iterator_fast<Item> li(item_list);
@@ -3734,44 +3742,51 @@ void subselect_engine::set_row(List<Item> &item_list, Item_cache **row)
item->unsigned_flag= sel_item->unsigned_flag;
maybe_null= sel_item->maybe_null;
if (!(row[i]= Item_cache::get_cache(thd, sel_item, sel_item->cmp_type())))
- return;
+ return TRUE;
row[i]->setup(thd, sel_item);
//psergey-backport-timours: row[i]->store(sel_item);
}
if (item_list.elements > 1)
cmp_type= res_type= ROW_RESULT;
+ return FALSE;
}
-void subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
+bool subselect_single_select_engine::fix_length_and_dec(Item_cache **row)
{
DBUG_ASSERT(row || select_lex->item_list.elements==1);
- set_row(select_lex->item_list, row);
+ if (set_row(select_lex->item_list, row))
+ return TRUE;
item->collation.set(row[0]->collation);
if (cols() != 1)
maybe_null= 0;
+ return FALSE;
}
-void subselect_union_engine::fix_length_and_dec(Item_cache **row)
+bool subselect_union_engine::fix_length_and_dec(Item_cache **row)
{
DBUG_ASSERT(row || unit->first_select()->item_list.elements==1);
if (unit->first_select()->item_list.elements == 1)
{
- set_row(unit->types, row);
+ if (set_row(unit->types, row))
+ return TRUE;
item->collation.set(row[0]->collation);
}
else
{
bool maybe_null_saved= maybe_null;
- set_row(unit->types, row);
+ if (set_row(unit->types, row))
+ return TRUE;
maybe_null= maybe_null_saved;
}
+ return FALSE;
}
-void subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
+bool subselect_uniquesubquery_engine::fix_length_and_dec(Item_cache **row)
{
//this never should be called
DBUG_ASSERT(0);
+ return FALSE;
}
int read_first_record_seq(JOIN_TAB *tab);
@@ -5604,9 +5619,10 @@ void subselect_hash_sj_engine::print(String *str, enum_query_type query_type)
));
}
-void subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
+bool subselect_hash_sj_engine::fix_length_and_dec(Item_cache** row)
{
DBUG_ASSERT(FALSE);
+ return FALSE;
}
void subselect_hash_sj_engine::exclude()
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index f44a5c4d0ce..bd6a1bdc498 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -810,7 +810,7 @@ class subselect_engine: public Sql_alloc
void set_thd(THD *thd_arg);
THD * get_thd() { return thd ? thd : current_thd; }
virtual int prepare(THD *)= 0;
- virtual void fix_length_and_dec(Item_cache** row)= 0;
+ virtual bool fix_length_and_dec(Item_cache** row)= 0;
/*
Execute the engine
@@ -854,7 +854,7 @@ class subselect_engine: public Sql_alloc
virtual int get_identifier() { DBUG_ASSERT(0); return 0; }
virtual void force_reexecution() {}
protected:
- void set_row(List<Item> &item_list, Item_cache **row);
+ bool set_row(List<Item> &item_list, Item_cache **row);
};
@@ -870,7 +870,7 @@ class subselect_single_select_engine: public subselect_engine
Item_subselect *item);
void cleanup();
int prepare(THD *thd);
- void fix_length_and_dec(Item_cache** row);
+ bool fix_length_and_dec(Item_cache** row);
int exec();
uint cols();
uint8 uncacheable();
@@ -905,7 +905,7 @@ class subselect_union_engine: public subselect_engine
Item_subselect *item);
void cleanup();
int prepare(THD *);
- void fix_length_and_dec(Item_cache** row);
+ bool fix_length_and_dec(Item_cache** row);
int exec();
uint cols();
uint8 uncacheable();
@@ -963,7 +963,7 @@ class subselect_uniquesubquery_engine: public subselect_engine
~subselect_uniquesubquery_engine();
void cleanup();
int prepare(THD *);
- void fix_length_and_dec(Item_cache** row);
+ bool fix_length_and_dec(Item_cache** row);
int exec();
uint cols() { return 1; }
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT_INJECTED; }
@@ -1112,7 +1112,7 @@ class subselect_hash_sj_engine : public subselect_engine
TODO: factor out all these methods in a base subselect_index_engine class
because all of them have dummy implementations and should never be called.
*/
- void fix_length_and_dec(Item_cache** row);//=>base class
+ bool fix_length_and_dec(Item_cache** row);//=>base class
void exclude(); //=>base class
//=>base class
bool change_result(Item_subselect *si,
@@ -1385,7 +1385,7 @@ class subselect_partial_match_engine : public subselect_engine
uint count_columns_with_nulls_arg);
int prepare(THD *thd_arg) { set_thd(thd_arg); return 0; }
int exec();
- void fix_length_and_dec(Item_cache**) {}
+ bool fix_length_and_dec(Item_cache**) { return FALSE; }
uint cols() { /* TODO: what is the correct value? */ return 1; }
uint8 uncacheable() { return UNCACHEABLE_DEPENDENT; }
void exclude() {}
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index f3cb85f01d3..e010a667590 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4895,10 +4895,9 @@ int create_table_impl(THD *thd,
alter_info, create_table_mode, key_info,
key_count, frm);
/*
- 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()
+ TODO: remove this check of thd->is_error() (now it intercept
+ errors in some val_*() methoids and bring some single place to
+ such error interception).
*/
if (!file || thd->is_error())
goto err;
@@ -7380,6 +7379,10 @@ static bool mysql_inplace_alter_table(THD *thd,
/*
Replace the old .FRM with the new .FRM, but keep the old name for now.
Rename to the new name (if needed) will be handled separately below.
+
+ TODO: remove this check of thd->is_error() (now it intercept
+ errors in some val_*() methoids and bring some single place to
+ such error interception).
*/
if (mysql_rename_table(db_type, alter_ctx->new_db, alter_ctx->tmp_name,
alter_ctx->db, alter_ctx->alias,
1
0
[Commits] c4411c68dd8: MDEV-15611 Due to the failure of foreign key detection, Galera slave node killed himself.
by jan 14 Jun '18
by jan 14 Jun '18
14 Jun '18
revision-id: c4411c68dd829d79d58d2b4959fb045d35456d25 (mariadb-10.1.33-44-gc4411c68dd8)
parent(s): 72005b7a1c42cb31294ead822b812909e5885f1c
author: Jan Lindström
committer: Jan Lindström
timestamp: 2018-06-14 15:47:39 +0300
message:
MDEV-15611 Due to the failure of foreign key detection, Galera slave node killed himself.
Merge following change from 10.2
revision-id: d52cff9f10aeea208a1058f7b5527e602125584c (mariadb-10.2.14-25-gd52cff9)
parent(s): bc2501453c3ab9a2cf3516bc3557de8665bc2776
author: Sachin Setiya
committer: Sachin Setiya
timestamp: 2018-04-04 12:26:06 +0530
message:
MDEV-15611 Due to the failure of foreign key detection, Galera...
slave node killed himself.
Problem:- If we try to delete table with foreign key and table whom it is
referring with wsrep_slave_threads>1 then galera tries to execute both
Delete_rows_log-event in parallel, which should not happen.
Solution:- This is happening because we do not have foreign key info in
write set. Upto version 10.2.7 it used to work fine. Actually it happening
because of issue in commit 2f342c4. wsrep_must_process_fk should be used
with negation.
---
mysql-test/suite/galera/r/galera_mdev_15611.result | 15 +++
mysql-test/suite/galera/t/galera_mdev_15611.cnf | 5 +
mysql-test/suite/galera/t/galera_mdev_15611.test | 30 +++++
storage/innobase/row/row0upd.cc | 141 +++++++++++----------
storage/xtradb/row/row0upd.cc | 141 +++++++++++----------
5 files changed, 200 insertions(+), 132 deletions(-)
diff --git a/mysql-test/suite/galera/r/galera_mdev_15611.result b/mysql-test/suite/galera/r/galera_mdev_15611.result
new file mode 100644
index 00000000000..677ed98202d
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_mdev_15611.result
@@ -0,0 +1,15 @@
+CREATE TABLE t1 (
+id int primary key
+);
+CREATE TABLE t2 (
+id int primary key ,
+f_id int DEFAULT NULL, FOREIGN KEY(f_id) REFERENCES t1 (id)
+);
+insert into t1 select 1;
+#Running 200 insert in t2 table
+select count(*) from t2;
+count(*)
+200
+delete from t2;
+delete from t1;
+drop table t2,t1;
diff --git a/mysql-test/suite/galera/t/galera_mdev_15611.cnf b/mysql-test/suite/galera/t/galera_mdev_15611.cnf
new file mode 100644
index 00000000000..b6f601c56b1
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_mdev_15611.cnf
@@ -0,0 +1,5 @@
+!include ../galera_2nodes.cnf
+[mysqld.1]
+
+[mysqld.2]
+wsrep_slave_threads=6
diff --git a/mysql-test/suite/galera/t/galera_mdev_15611.test b/mysql-test/suite/galera/t/galera_mdev_15611.test
new file mode 100644
index 00000000000..d32d7e75262
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_mdev_15611.test
@@ -0,0 +1,30 @@
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+--connection node_1
+CREATE TABLE t1 (
+ id int primary key
+);
+
+CREATE TABLE t2 (
+ id int primary key ,
+ f_id int DEFAULT NULL, FOREIGN KEY(f_id) REFERENCES t1 (id)
+);
+
+insert into t1 select 1;
+
+--disable_query_log
+--let $count=200
+--echo #Running 200 insert in t2 table
+while($count)
+{
+ #Repeatedly execute the following SQL until you generate thousands of data
+ --eval insert into t2 values ($count, 1);
+ --dec $count
+}
+--enable_query_log
+
+select count(*) from t2;
+delete from t2;
+delete from t1;
+drop table t2,t1;
diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc
index e2de47bf86a..33f46882651 100644
--- a/storage/innobase/row/row0upd.cc
+++ b/storage/innobase/row/row0upd.cc
@@ -1803,6 +1803,23 @@ row_upd_store_row(
}
}
+#ifdef WITH_WSREP
+/** Determine if a FOREIGN KEY constraint needs to be processed.
+@param[in] node query node
+@param[in] trx transaction
+@return whether the node cannot be ignored */
+
+inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
+{
+ if (!wsrep_on_trx(trx)) {
+ return false;
+ }
+ return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
+ || static_cast<upd_node_t*>(node->common.parent)->cascade_node
+ != node;
+}
+#endif /* WITH_WSREP */
+
/***********************************************************//**
Updates a secondary index entry of a row.
@return DB_SUCCESS if operation successfully completed, else error
@@ -1833,7 +1850,7 @@ row_upd_sec_index_entry(
referenced = row_upd_index_is_referenced(index, trx);
#ifdef WITH_WSREP
- ibool foreign = wsrep_row_upd_index_is_foreign(index, trx);
+ bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
#endif /* WITH_WSREP */
heap = mem_heap_create(1024);
@@ -1962,61 +1979,61 @@ row_upd_sec_index_entry(
row_ins_sec_index_entry() below */
if (!rec_get_deleted_flag(
rec, dict_table_is_comp(index->table))) {
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
err = btr_cur_del_mark_set_sec_rec(
0, btr_cur, TRUE, thr, &mtr);
- if (err == DB_SUCCESS && referenced) {
-
- ulint* offsets;
-
- offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED,
- &heap);
-
- /* NOTE that the following call loses
- the position of pcur ! */
- err = row_upd_check_references_constraints(
- node, &pcur, index->table,
- index, offsets, thr, &mtr);
+ if (err != DB_SUCCESS) {
+ break;
}
+
#ifdef WITH_WSREP
- if (err == DB_SUCCESS && !referenced &&
- wsrep_on_trx(trx) &&
- !wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- !(parent && que_node_get_type(parent) ==
- QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
- ulint* offsets =
- rec_get_offsets(
+ if (!referenced && foreign
+ && wsrep_must_process_fk(node, trx)
+ && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ ulint* offsets = rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
+
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: sec index FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
}
#endif /* WITH_WSREP */
}
- break;
+
+ if (referenced) {
+
+ ulint* offsets;
+
+ offsets = rec_get_offsets(
+ rec, index, NULL, ULINT_UNDEFINED,
+ &heap);
+
+ /* NOTE that the following call loses
+ the position of pcur ! */
+ err = row_upd_check_references_constraints(
+ node, &pcur, index->table,
+ index, offsets, thr, &mtr);
+ }
}
btr_pcur_close(&pcur);
@@ -2185,9 +2202,6 @@ row_upd_clust_rec_by_insert(
rec_t* rec;
ulint* offsets = NULL;
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
ut_ad(node);
ut_ad(dict_index_is_clust(index));
@@ -2269,35 +2283,31 @@ row_upd_clust_rec_by_insert(
if (err != DB_SUCCESS) {
goto err_exit;
}
- }
#ifdef WITH_WSREP
- if (!referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if ((foreign && wsrep_must_process_fk(node, trx))) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: insert FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- if (err != DB_SUCCESS) {
- goto err_exit;
- }
- }
#endif /* WITH_WSREP */
+ }
}
mtr_commit(mtr);
@@ -2500,7 +2510,7 @@ row_upd_del_mark_clust_rec(
dberr_t err;
#ifdef WITH_WSREP
rec_t* rec;
- que_node_t *parent = que_node_get_parent(node);
+ trx_t* trx = thr_get_trx(thr) ;
#endif /* WITH_WSREP */
ut_ad(node);
@@ -2529,38 +2539,37 @@ row_upd_del_mark_clust_rec(
btr_cur_get_block(btr_cur), btr_cur_get_rec(btr_cur),
#endif /* WITH_WSREP */
index, offsets, thr, mtr);
- if (err == DB_SUCCESS && referenced) {
+ if (err != DB_SUCCESS) {
+ } else if (referenced) {
/* NOTE that the following call loses the position of pcur ! */
err = row_upd_check_references_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
- }
#ifdef WITH_WSREP
- trx_t* trx = thr_get_trx(thr) ;
- if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if (foreign && wsrep_must_process_fk(node, trx)) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: clust rec FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: clust rec referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- }
#endif /* WITH_WSREP */
+ }
mtr_commit(mtr);
diff --git a/storage/xtradb/row/row0upd.cc b/storage/xtradb/row/row0upd.cc
index 9ac72f8d068..93ccc07c9af 100644
--- a/storage/xtradb/row/row0upd.cc
+++ b/storage/xtradb/row/row0upd.cc
@@ -1806,6 +1806,23 @@ row_upd_store_row(
}
}
+#ifdef WITH_WSREP
+/** Determine if a FOREIGN KEY constraint needs to be processed.
+@param[in] node query node
+@param[in] trx transaction
+@return whether the node cannot be ignored */
+
+inline bool wsrep_must_process_fk(const upd_node_t* node, const trx_t* trx)
+{
+ if (!wsrep_on_trx(trx)) {
+ return false;
+ }
+ return que_node_get_type(node->common.parent) != QUE_NODE_UPDATE
+ || static_cast<upd_node_t*>(node->common.parent)->cascade_node
+ != node;
+}
+#endif /* WITH_WSREP */
+
/***********************************************************//**
Updates a secondary index entry of a row.
@return DB_SUCCESS if operation successfully completed, else error
@@ -1836,7 +1853,7 @@ row_upd_sec_index_entry(
referenced = row_upd_index_is_referenced(index, trx);
#ifdef WITH_WSREP
- ibool foreign = wsrep_row_upd_index_is_foreign(index, trx);
+ bool foreign = wsrep_row_upd_index_is_foreign(index, trx);
#endif /* WITH_WSREP */
heap = mem_heap_create(1024);
@@ -1968,61 +1985,61 @@ row_upd_sec_index_entry(
row_ins_sec_index_entry() below */
if (!rec_get_deleted_flag(
rec, dict_table_is_comp(index->table))) {
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
err = btr_cur_del_mark_set_sec_rec(
0, btr_cur, TRUE, thr, &mtr);
- if (err == DB_SUCCESS && referenced) {
-
- ulint* offsets;
-
- offsets = rec_get_offsets(
- rec, index, NULL, ULINT_UNDEFINED,
- &heap);
-
- /* NOTE that the following call loses
- the position of pcur ! */
- err = row_upd_check_references_constraints(
- node, &pcur, index->table,
- index, offsets, thr, &mtr);
+ if (err != DB_SUCCESS) {
+ break;
}
+
#ifdef WITH_WSREP
- if (err == DB_SUCCESS && !referenced &&
- wsrep_on_trx(trx) &&
- !wsrep_thd_is_BF(trx->mysql_thd, FALSE) &&
- !(parent && que_node_get_type(parent) ==
- QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
- ulint* offsets =
- rec_get_offsets(
+ if (!referenced && foreign
+ && wsrep_must_process_fk(node, trx)
+ && !wsrep_thd_is_BF(trx->mysql_thd, FALSE)) {
+ ulint* offsets = rec_get_offsets(
rec, index, NULL, ULINT_UNDEFINED,
&heap);
+
err = wsrep_row_upd_check_foreign_constraints(
node, &pcur, index->table,
index, offsets, thr, &mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: sec index FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
}
#endif /* WITH_WSREP */
}
- break;
+
+ if (referenced) {
+
+ ulint* offsets;
+
+ offsets = rec_get_offsets(
+ rec, index, NULL, ULINT_UNDEFINED,
+ &heap);
+
+ /* NOTE that the following call loses
+ the position of pcur ! */
+ err = row_upd_check_references_constraints(
+ node, &pcur, index->table,
+ index, offsets, thr, &mtr);
+ }
}
btr_pcur_close(&pcur);
@@ -2191,9 +2208,6 @@ row_upd_clust_rec_by_insert(
rec_t* rec;
ulint* offsets = NULL;
-#ifdef WITH_WSREP
- que_node_t *parent = que_node_get_parent(node);
-#endif /* WITH_WSREP */
ut_ad(node);
ut_ad(dict_index_is_clust(index));
@@ -2278,35 +2292,31 @@ row_upd_clust_rec_by_insert(
if (err != DB_SUCCESS) {
goto err_exit;
}
- }
#ifdef WITH_WSREP
- if (!referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if ((foreign && wsrep_must_process_fk(node, trx))) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: insert FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- if (err != DB_SUCCESS) {
- goto err_exit;
- }
- }
#endif /* WITH_WSREP */
+ }
}
mtr_commit(mtr);
@@ -2512,7 +2522,7 @@ row_upd_del_mark_clust_rec(
dberr_t err;
#ifdef WITH_WSREP
rec_t* rec;
- que_node_t *parent = que_node_get_parent(node);
+ trx_t* trx = thr_get_trx(thr) ;
#endif /* WITH_WSREP */
ut_ad(node);
@@ -2541,38 +2551,37 @@ row_upd_del_mark_clust_rec(
btr_cur_get_block(btr_cur), btr_cur_get_rec(btr_cur),
#endif /* WITH_WSREP */
index, offsets, thr, mtr);
- if (err == DB_SUCCESS && referenced) {
+ if (err != DB_SUCCESS) {
+ } else if (referenced) {
/* NOTE that the following call loses the position of pcur ! */
err = row_upd_check_references_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
- }
#ifdef WITH_WSREP
- trx_t* trx = thr_get_trx(thr) ;
- if (err == DB_SUCCESS && !referenced && wsrep_on_trx(trx) &&
- !(parent && que_node_get_type(parent) == QUE_NODE_UPDATE &&
- ((upd_node_t*)parent)->cascade_node == node) &&
- foreign
- ) {
+ } else if (foreign && wsrep_must_process_fk(node, trx)) {
err = wsrep_row_upd_check_foreign_constraints(
node, pcur, index->table, index, offsets, thr, mtr);
+
switch (err) {
case DB_SUCCESS:
case DB_NO_REFERENCED_ROW:
err = DB_SUCCESS;
break;
case DB_DEADLOCK:
- if (wsrep_debug) fprintf (stderr,
- "WSREP: clust rec FK check fail for deadlock");
+ if (wsrep_debug) {
+ ib_logf(IB_LOG_LEVEL_WARN,
+ "WSREP: sec index FK check fail for deadlock: "
+ " index %s table %s", index->name, index->table->name);
+ }
break;
default:
- fprintf (stderr,
- "WSREP: clust rec referenced FK check fail: %d",
- (int)err);
+ ib_logf(IB_LOG_LEVEL_ERROR,
+ "WSREP: referenced FK check fail: %s index %s table %s",
+ ut_strerr(err), index->name, index->table->name);
break;
}
- }
#endif /* WITH_WSREP */
+ }
mtr_commit(mtr);
1
0
[Commits] 88f3235d7c7: MDEV-16386: Wrong result when pushdown into the HAVING clause of the
by Galina 13 Jun '18
by Galina 13 Jun '18
13 Jun '18
revision-id: 88f3235d7c7e47213a89d8096af3be536c8ba69b (mariadb-10.2.15-52-g88f3235d7c7)
parent(s): 8662015c90718501d504f4c7aeb94b8626902a9c
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-06-13 23:21:01 +0200
message:
MDEV-16386: Wrong result when pushdown into the HAVING clause of the
materialized derived table/view that uses aliases is done
The problem appears when a column alias inside the materialized derived
table/view t1 definition coincide with the column name used in the
GROUP BY clause of t1. If the condition that can be pushed into t1
uses that ambiguous column name this column is determined as a column that
is used in the GROUP BY clause instead of the alias used in the projection
list of t1. That causes wrong result.
To prevent it resolve_ref_in_select_and_group() was changed.
---
mysql-test/r/derived_cond_pushdown.result | 196 ++++++++++++++++++++++++++++++
mysql-test/t/derived_cond_pushdown.test | 56 +++++++++
sql/item.cc | 11 +-
sql/sql_lex.cc | 1 +
sql/sql_lex.h | 5 +
sql/sql_select.cc | 2 +
6 files changed, 267 insertions(+), 4 deletions(-)
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index 3fbc81019cc..83e70dd634c 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -9473,3 +9473,199 @@ WHERE (a>0 AND a<2 OR a IN (2,3)) AND
a
2
DROP TABLE t1;
+#
+# MDEV-16386: pushing condition into the HAVING clause when ambiguous
+# fields warning appears
+#
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,2),(2,3),(3,4);
+SELECT * FROM
+(
+SELECT t1.b AS a
+FROM t1
+GROUP BY t1.a
+) dt
+WHERE (dt.a=2);
+a
+2
+EXPLAIN FORMAT=JSON SELECT * FROM
+(
+SELECT t1.b AS a
+FROM t1
+GROUP BY t1.a
+) dt
+WHERE (dt.a=2);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "dt.a = 2",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "a = 2",
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM
+(
+SELECT t1.b AS a
+FROM t1
+GROUP BY t1.a
+HAVING (t1.a<3)
+) dt
+WHERE (dt.a>1);
+a
+2
+3
+EXPLAIN FORMAT=JSON SELECT * FROM
+(
+SELECT t1.b AS a
+FROM t1
+GROUP BY t1.a
+HAVING (t1.a<3)
+) dt
+WHERE (dt.a>1);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "dt.a > 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "having_condition": "t1.a < 3 and a > 1",
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM
+(
+SELECT 'ab' AS a
+FROM t1
+GROUP BY t1.a
+) dt
+WHERE (dt.a='ab');
+a
+ab
+ab
+ab
+EXPLAIN FORMAT=JSON SELECT * FROM
+(
+SELECT 'ab' AS a
+FROM t1
+GROUP BY t1.a
+) dt
+WHERE (dt.a='ab');
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "dt.a = 'ab'",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+SELECT * FROM
+(
+SELECT 1 AS a
+FROM t1
+GROUP BY t1.a
+) dt
+WHERE (dt.a=1);
+a
+1
+1
+1
+EXPLAIN FORMAT=JSON SELECT * FROM
+(
+SELECT 1 AS a
+FROM t1
+GROUP BY t1.a
+) dt
+WHERE (dt.a=1);
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "dt.a = 1",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "filesort": {
+ "sort_key": "t1.a",
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+DROP TABLE t1;
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index d3832ce1ec3..718140d3a77 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -1745,3 +1745,59 @@ WHERE (a>0 AND a<2 OR a IN (2,3)) AND
(a=2 OR 0);
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-16386: pushing condition into the HAVING clause when ambiguous
+--echo # fields warning appears
+--echo #
+
+CREATE TABLE t1 (a INT, b INT);
+
+INSERT INTO t1 VALUES (1,2),(2,3),(3,4);
+
+LET $query=
+SELECT * FROM
+(
+ SELECT t1.b AS a
+ FROM t1
+ GROUP BY t1.a
+) dt
+WHERE (dt.a=2);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM
+(
+ SELECT t1.b AS a
+ FROM t1
+ GROUP BY t1.a
+ HAVING (t1.a<3)
+) dt
+WHERE (dt.a>1);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM
+(
+ SELECT 'ab' AS a
+ FROM t1
+ GROUP BY t1.a
+) dt
+WHERE (dt.a='ab');
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+LET $query=
+SELECT * FROM
+(
+ SELECT 1 AS a
+ FROM t1
+ GROUP BY t1.a
+) dt
+WHERE (dt.a=1);
+EVAL $query;
+EVAL EXPLAIN FORMAT=JSON $query;
+
+DROP TABLE t1;
diff --git a/sql/item.cc b/sql/item.cc
index f9200ccf56d..4bc6fe7e5bc 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4984,9 +4984,11 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
in the SELECT clause of Q.
- Search for a column named col_ref_i [in table T_j]
in the GROUP BY clause of Q.
- - If found different columns with the same name in GROUP BY and SELECT
- - issue a warning and return the GROUP BY column,
- - otherwise
+ - If found different columns with the same name in GROUP BY and SELECT:
+ - if the condition that uses this column name is pushed down into
+ the HAVING clause return the SELECT column
+ - else issue a warning and return the GROUP BY column.
+ - Otherwise
- if the MODE_ONLY_FULL_GROUP_BY mode is enabled return error
- else return the found SELECT column.
@@ -5025,7 +5027,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
/* Check if the fields found in SELECT and GROUP BY are the same field. */
if (group_by_ref && (select_ref != not_found_item) &&
- !((*group_by_ref)->eq(*select_ref, 0)))
+ !((*group_by_ref)->eq(*select_ref, 0)) &&
+ (!select->having_fix_field_for_pushed_cond))
{
ambiguous_fields= TRUE;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 750fb75bfb9..d3ddd9e208c 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -2107,6 +2107,7 @@ void st_select_lex::init_query()
cond_pushed_into_where= cond_pushed_into_having= 0;
olap= UNSPECIFIED_OLAP_TYPE;
having_fix_field= 0;
+ having_fix_field_for_pushed_cond= 0;
context.select_lex= this;
context.init();
/*
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index ed5e423fd5a..a1f6b202ae6 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -887,6 +887,11 @@ class st_select_lex: public st_select_lex_node
bool braces; /* SELECT ... UNION (SELECT ... ) <- this braces */
/* TRUE when having fix field called in processing of this SELECT */
bool having_fix_field;
+ /*
+ TRUE when fix field is called for a new condition pushed into the
+ HAVING clause of this SELECT
+ */
+ bool having_fix_field_for_pushed_cond;
/* List of references to fields referenced from inner selects */
List<Item_outer_ref> inner_refs_list;
/* Number of Item_sum-derived objects in this SELECT */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ee5ba4ade54..4ebd5ef4954 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -1350,9 +1350,11 @@ JOIN::optimize_inner()
if (having)
{
select_lex->having_fix_field= 1;
+ select_lex->having_fix_field_for_pushed_cond= 1;
if (having->fix_fields(thd, &having))
DBUG_RETURN(1);
select_lex->having_fix_field= 0;
+ select_lex->having_fix_field_for_pushed_cond= 0;
}
}
1
0
[Commits] f339c6b18f3: MDEV-16386: Wrong result when pushdown into the HAVING clause of the
by Galina 13 Jun '18
by Galina 13 Jun '18
13 Jun '18
revision-id: f339c6b18f37f26a6a92a1f2a55458bc31fa604d (mariadb-10.2.15-52-gf339c6b18f3)
parent(s): 8662015c90718501d504f4c7aeb94b8626902a9c
author: Galina Shalygina
committer: Galina Shalygina
timestamp: 2018-06-13 16:32:25 +0200
message:
MDEV-16386: Wrong result when pushdown into the HAVING clause of the
materialized derived table/view that uses aliases is done
The problem appears when a column alias inside the materialized derived
table/view t1 definition coincide with the column name used in the
GROUP BY clause of t1. If the condition that can be pushed into t1
uses that ambiguous column name this column is determined as a column that
is used in the GROUP BY clause instead of the alias used in the projection
list of t1. That causes wrong result.
To prevent it resolve_ref_in_select_and_group() was changed.
---
mysql-test/r/derived_cond_pushdown.result | 36 +++++++++++++++++++++++++++++++
mysql-test/t/derived_cond_pushdown.test | 34 +++++++++++++++++++++++++++++
sql/item.cc | 11 ++++++----
3 files changed, 77 insertions(+), 4 deletions(-)
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index 3fbc81019cc..91f7546300b 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -9473,3 +9473,39 @@ WHERE (a>0 AND a<2 OR a IN (2,3)) AND
a
2
DROP TABLE t1;
+#
+# MDEV-16386: pushing condition into the HAVING clause when ambiguous
+# fields warning appears
+#
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,2),(2,3);
+SELECT * FROM
+(
+SELECT b AS a
+FROM t1
+GROUP BY t1.a
+) der_tab
+WHERE (der_tab.a=2);
+a
+2
+SELECT * FROM
+(
+SELECT 'a' AS a
+FROM t1
+GROUP BY t1.a
+) der_tab
+WHERE (der_tab.a='a');
+a
+a
+a
+SELECT * FROM
+(
+SELECT 1 AS a
+FROM t1
+GROUP BY t1.a
+) der_tab
+WHERE (der_tab.a=1);
+a
+1
+1
+DROP TABLE t1;
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index d3832ce1ec3..b4214a06435 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -1745,3 +1745,37 @@ WHERE (a>0 AND a<2 OR a IN (2,3)) AND
(a=2 OR 0);
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-16386: pushing condition into the HAVING clause when ambiguous
+--echo # fields warning appears
+--echo #
+
+CREATE TABLE t1 (a INT, b INT);
+INSERT INTO t1 VALUES (1,2),(2,3);
+
+SELECT * FROM
+(
+ SELECT b AS a
+ FROM t1
+ GROUP BY t1.a
+) der_tab
+WHERE (der_tab.a=2);
+
+SELECT * FROM
+(
+ SELECT 'a' AS a
+ FROM t1
+ GROUP BY t1.a
+) der_tab
+WHERE (der_tab.a='a');
+
+SELECT * FROM
+(
+ SELECT 1 AS a
+ FROM t1
+ GROUP BY t1.a
+) der_tab
+WHERE (der_tab.a=1);
+
+DROP TABLE t1;
diff --git a/sql/item.cc b/sql/item.cc
index f9200ccf56d..ad0d40501ae 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -4984,9 +4984,11 @@ static Item** find_field_in_group_list(Item *find_item, ORDER *group_list)
in the SELECT clause of Q.
- Search for a column named col_ref_i [in table T_j]
in the GROUP BY clause of Q.
- - If found different columns with the same name in GROUP BY and SELECT
- - issue a warning and return the GROUP BY column,
- - otherwise
+ - If found different columns with the same name in GROUP BY and SELECT:
+ - if the condition using this column name is pushed into the HAVING clause
+ of the materialized table/view return the SELECT column
+ - else issue a warning and return the GROUP BY column.
+ - Otherwise
- if the MODE_ONLY_FULL_GROUP_BY mode is enabled return error
- else return the found SELECT column.
@@ -5025,7 +5027,8 @@ resolve_ref_in_select_and_group(THD *thd, Item_ident *ref, SELECT_LEX *select)
/* Check if the fields found in SELECT and GROUP BY are the same field. */
if (group_by_ref && (select_ref != not_found_item) &&
- !((*group_by_ref)->eq(*select_ref, 0)))
+ !((*group_by_ref)->eq(*select_ref, 0)) &&
+ (!select->cond_pushed_into_having))
{
ambiguous_fields= TRUE;
push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
1
0
[Commits] 0918ae42a83: MDEV-14014 Multi-Slave Replication Fail: bogus data in log event
by andrei.elkinï¼ pp.inet.fi 13 Jun '18
by andrei.elkinï¼ pp.inet.fi 13 Jun '18
13 Jun '18
revision-id: 0918ae42a8394b6faf28f67b70550894851be3bb (mariadb-10.1.33-36-g0918ae42a83)
parent(s): 26be5072429082e634b8fc102609370975443439
author: Andrei Elkin
committer: Andrei Elkin
timestamp: 2018-06-13 16:27:00 +0300
message:
MDEV-14014 Multi-Slave Replication Fail: bogus data in log event
MDEV-7257 made a dump thread to read from binlog concurrently with
writers as long as the read bytes are below a water-mark
(MYSQL_BIN_LOG::binlog_end_pos). However it appeared to be possible a
dump thread reader reach out for bytes past the water mark through a
feature of IO_CACHE that fills in the internal buffer and while doing
so it could read what the reader is not supposed to see (the bytes
above MYSQL_BIN_LOG::binlog_end_pos).
The issue is fixed with constraining the IO_CACHE buffer fill to respect
the watermark.
An added test simulates potentially unconstrained buffer fill and an
assert guards this is not the case anymore.
---
sql/sql_repl.cc | 1 +
unittest/sql/mf_iocache-t.cc | 35 +++++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+)
diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc
index 569c3d2c4ef..db608de5147 100644
--- a/sql/sql_repl.cc
+++ b/sql/sql_repl.cc
@@ -2546,6 +2546,7 @@ static int send_events(binlog_send_info *info, IO_CACHE* log, LOG_INFO* linfo,
linfo->pos= my_b_tell(log);
info->last_pos= my_b_tell(log);
+ log->end_of_file= end_pos;
while (linfo->pos < end_pos)
{
if (should_stop(info))
diff --git a/unittest/sql/mf_iocache-t.cc b/unittest/sql/mf_iocache-t.cc
index 1b04f8eb0d3..edc4c3ce789 100644
--- a/unittest/sql/mf_iocache-t.cc
+++ b/unittest/sql/mf_iocache-t.cc
@@ -253,6 +253,39 @@ void mdev10259()
}
+void mdev14014()
+{
+ int res;
+ uchar buf_o[200];
+ uchar buf_i[200];
+ memset(buf_i, 0, sizeof( buf_i));
+ memset(buf_o, FILL, sizeof(buf_o));
+
+ diag("MDEV-14014 Dump thread reads past last 'officially' written byte");
+
+ 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_o, sizeof(buf_o));
+ ok(res == 0, "buffer is written" 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);
+
+ info.end_of_file= 100;
+ res= my_b_read(&info, buf_i, sizeof(buf_i));
+ ok(res == 1 && buf_i[100] == 0 && buf_i[200-1] == 0,
+ "short read leaves buf_i[100..200-1] == 0");
+
+ close_cached_file(&info);
+}
+
+
int main(int argc __attribute__((unused)),char *argv[])
{
MY_INIT(argv[0]);
@@ -272,6 +305,8 @@ int main(int argc __attribute__((unused)),char *argv[])
mdev10259();
encrypt_tmp_files= 0;
+ mdev14014();
+
my_end(0);
return exit_status();
}
1
0