summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.org>2017-05-17 12:59:07 +0400
committerAlexander Barkov <bar@mariadb.org>2017-05-17 12:59:07 +0400
commit896c2c73a02c7e82299b00e66ee3ff5f85aa3adc (patch)
treeb51a6b87f0d2488845144be585275c8cac19a1ed
parent6378c95ee07cccc2f2187b2caddc4496e14827d9 (diff)
parentfba7fbbc5c7bb1d05488108a29b854ee8ef0066a (diff)
downloadmariadb-git-10.3-MDEV-10953.tar.gz
Merge remote-tracking branch 'origin/bb-10.2-ext' into 10.310.3-MDEV-10953
-rw-r--r--client/mysqlcheck.c2
-rw-r--r--include/my_base.h4
-rw-r--r--include/mysql/service_my_snprintf.h2
-rw-r--r--mysql-test/extra/rpl_tests/rpl_charset.test28
-rw-r--r--mysql-test/r/cte_recursive.result2
-rw-r--r--mysql-test/r/ctype_binary.result4
-rw-r--r--mysql-test/r/ctype_cp1250_ch.result2
-rw-r--r--mysql-test/r/ctype_latin1.result8
-rw-r--r--mysql-test/r/ctype_latin2_ch.result2
-rw-r--r--mysql-test/r/ctype_tis620.result4
-rw-r--r--mysql-test/r/ctype_uca.result4
-rw-r--r--mysql-test/r/ctype_ucs.result4
-rw-r--r--mysql-test/r/ctype_utf8.result4
-rw-r--r--mysql-test/r/default.result2
-rw-r--r--mysql-test/r/func_compress.result2
-rw-r--r--mysql-test/r/func_str.result22
-rw-r--r--mysql-test/r/func_time.result18
-rw-r--r--mysql-test/r/gis.result18
-rw-r--r--mysql-test/r/metadata.result6
-rw-r--r--mysql-test/r/mysqld--help.result2
-rw-r--r--mysql-test/r/range.result18
-rw-r--r--mysql-test/r/range_mrr_icp.result18
-rw-r--r--mysql-test/r/subselect.result2
-rw-r--r--mysql-test/r/subselect_no_exists_to_in.result2
-rw-r--r--mysql-test/r/subselect_no_mat.result2
-rw-r--r--mysql-test/r/subselect_no_opts.result2
-rw-r--r--mysql-test/r/subselect_no_scache.result2
-rw-r--r--mysql-test/r/subselect_no_semijoin.result2
-rw-r--r--mysql-test/r/temp_table.result16
-rw-r--r--mysql-test/r/type_date.result18
-rw-r--r--mysql-test/r/type_datetime.result12
-rw-r--r--mysql-test/r/type_datetime_hires.result12
-rw-r--r--mysql-test/r/type_float.result14
-rw-r--r--mysql-test/r/type_newdecimal.result6
-rw-r--r--mysql-test/r/type_time.result56
-rw-r--r--mysql-test/r/type_time_hires.result12
-rw-r--r--mysql-test/r/type_timestamp.result12
-rw-r--r--mysql-test/r/type_timestamp_hires.result12
-rw-r--r--mysql-test/r/union.result215
-rw-r--r--mysql-test/r/view.result2
-rw-r--r--mysql-test/suite/funcs_1/r/innodb_func_view.result8
-rw-r--r--mysql-test/suite/funcs_1/r/memory_func_view.result8
-rw-r--r--mysql-test/suite/funcs_1/r/myisam_func_view.result8
-rw-r--r--mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result6
-rw-r--r--mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result6
-rw-r--r--mysql-test/suite/rpl/r/rpl_charset.result23
-rw-r--r--mysql-test/suite/sql_sequence/alter.result238
-rw-r--r--mysql-test/suite/sql_sequence/alter.test139
-rw-r--r--mysql-test/suite/sql_sequence/create.result2
-rw-r--r--mysql-test/suite/sql_sequence/create.test2
-rw-r--r--mysql-test/suite/sql_sequence/next.result10
-rw-r--r--mysql-test/suite/sql_sequence/next.test3
-rw-r--r--mysql-test/suite/sql_sequence/other.result42
-rw-r--r--mysql-test/suite/sql_sequence/other.test29
-rw-r--r--mysql-test/suite/sql_sequence/read_only.test1
-rw-r--r--mysql-test/suite/sql_sequence/setval.result246
-rw-r--r--mysql-test/suite/sql_sequence/setval.test126
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_embedded.result4
-rw-r--r--mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result4
-rw-r--r--mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result6
-rw-r--r--mysql-test/t/func_str.test10
-rw-r--r--mysql-test/t/gis.test13
-rw-r--r--mysql-test/t/union.test127
-rw-r--r--sql/field.cc479
-rw-r--r--sql/field.h62
-rw-r--r--sql/ha_partition.cc1
-rw-r--r--sql/ha_sequence.cc27
-rw-r--r--sql/ha_sequence.h4
-rw-r--r--sql/item.cc263
-rw-r--r--sql/item.h82
-rw-r--r--sql/item_cmpfunc.cc25
-rw-r--r--sql/item_cmpfunc.h15
-rw-r--r--sql/item_create.cc53
-rw-r--r--sql/item_func.cc81
-rw-r--r--sql/item_func.h40
-rw-r--r--sql/item_jsonfunc.cc2
-rw-r--r--sql/item_strfunc.cc69
-rw-r--r--sql/item_strfunc.h18
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/lex.h2
-rw-r--r--sql/mysqld.cc1
-rw-r--r--sql/opt_range.cc2
-rw-r--r--sql/slave.cc3
-rw-r--r--sql/sp_head.cc1
-rw-r--r--sql/sp_head.h3
-rw-r--r--sql/sql_admin.cc2
-rw-r--r--sql/sql_alter.h23
-rw-r--r--sql/sql_class.cc11
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_cmd.h1
-rw-r--r--sql/sql_lex.cc25
-rw-r--r--sql/sql_lex.h17
-rw-r--r--sql/sql_parse.cc7
-rw-r--r--sql/sql_prepare.cc1
-rw-r--r--sql/sql_sequence.cc326
-rw-r--r--sql/sql_sequence.h41
-rw-r--r--sql/sql_table.cc477
-rw-r--r--sql/sql_table.h2
-rw-r--r--sql/sql_type.cc718
-rw-r--r--sql/sql_type.h406
-rw-r--r--sql/sql_union.cc217
-rw-r--r--sql/sql_yacc.yy195
-rw-r--r--sql/sql_yacc_ora.yy222
-rw-r--r--sql/structs.h21
-rw-r--r--sql/sys_vars.ic2
-rw-r--r--sql/table.cc6
-rw-r--r--sql/wsrep_binlog.cc2
-rw-r--r--storage/connect/ha_connect.cc2
-rw-r--r--storage/connect/tabext.cpp2
-rw-r--r--storage/innobase/buf/buf0flu.cc2
-rw-r--r--storage/innobase/handler/ha_innodb.cc4
-rw-r--r--storage/innobase/include/ut0dbg.h2
-rw-r--r--storage/innobase/include/ut0stage.h2
-rw-r--r--storage/maria/ma_create.c2
-rw-r--r--storage/maria/ma_ft_update.c2
-rw-r--r--storage/mroonga/ha_mroonga.cpp3
-rw-r--r--storage/myisam/ft_update.c2
-rw-r--r--storage/myisam/mi_create.c2
-rw-r--r--storage/tokudb/mysql-test/tokudb/r/type_float.result6
-rwxr-xr-xsupport-files/build-tags2
120 files changed, 4188 insertions, 1438 deletions
diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c
index b47b9c98510..8bc6334448f 100644
--- a/client/mysqlcheck.c
+++ b/client/mysqlcheck.c
@@ -19,6 +19,8 @@
/* By Jani Tolonen, 2001-04-20, MySQL Development Team */
#define CHECK_VERSION "2.7.4-MariaDB"
+/* Avoid warnings from %'s format */
+#define USING_MARIADB_SNPRINTF_EXTENSIONS
#include "client_priv.h"
#include <m_ctype.h>
diff --git a/include/my_base.h b/include/my_base.h
index ea8fd623b28..57b16ad985b 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -202,7 +202,9 @@ enum ha_extra_function {
HA_EXTRA_DETACH_CHILDREN,
HA_EXTRA_DETACH_CHILD,
/* Inform handler we will force a close as part of flush */
- HA_EXTRA_PREPARE_FOR_FORCED_CLOSE
+ HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
+ /* Inform handler that we will do an alter table */
+ HA_EXTRA_PREPARE_FOR_ALTER_TABLE,
};
/* Compatible option, to be deleted in 6.0 */
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
index 586a539d48c..1b2ee2ca202 100644
--- a/include/mysql/service_my_snprintf.h
+++ b/include/mysql/service_my_snprintf.h
@@ -96,7 +96,7 @@ extern struct my_snprintf_service_st {
#define ATTRIBUTE_FORMAT_DEFINED
#define ATTRIBUTE_FORMAT(A,B,C)
#endif
-#ifdef MYSQL_ABI_CHECK
+#if defined(MYSQL_ABI_CHECK) || defined(USING_MARIADB_SNPRINTF_EXTENSIONS)
#undef ATTRIBUTE_FORMAT
#define ATTRIBUTE_FORMAT(A,B,C)
#endif
diff --git a/mysql-test/extra/rpl_tests/rpl_charset.test b/mysql-test/extra/rpl_tests/rpl_charset.test
index 37ca2e28eec..e67122cbb4c 100644
--- a/mysql-test/extra/rpl_tests/rpl_charset.test
+++ b/mysql-test/extra/rpl_tests/rpl_charset.test
@@ -117,4 +117,32 @@ update t1 set pk='test' where pk=@p;
drop table t1;
# End of 4.1 tests
+
+
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+
+--echo #
+--echo # MDEV-12685 Oracle-compatible function CHR()
+--echo #
+
+connection master;
+CREATE DATABASE db1 DEFAULT CHARACTER SET latin1 COLLATE latin1_bin;
+USE db1;
+CREATE TABLE t1 AS SELECT CHR(0x60);
+sync_slave_with_master;
+SHOW CREATE TABLE db1.t1;
+connection master;
+USE test;
+DROP DATABASE db1;
+sync_slave_with_master;
+
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
+
+
--source include/rpl_end.inc
diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result
index f691db27239..946ba16ac5c 100644
--- a/mysql-test/r/cte_recursive.result
+++ b/mysql-test/r/cte_recursive.result
@@ -130,7 +130,7 @@ select t2.a+1 from t1,t2 where t1.a=t2.a
select * from t1;
show columns from v1;
Field Type Null Key Default Extra
-a bigint(20) YES NULL
+a bigint(12) YES NULL
# WITH RECURSIVE : types of t1 columns are determined by anchor parts
create view v2 as
with recursive
diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result
index 6c16b10f1ee..79080bde8ed 100644
--- a/mysql-test/r/ctype_binary.result
+++ b/mysql-test/r/ctype_binary.result
@@ -3037,7 +3037,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a'
DROP TABLE t1;
#
# End of MDEV-8694
@@ -3070,7 +3070,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a), CRC32(a) FROM t1 WHERE a='a' AND CRC32(a)=
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)`,crc32(`test`.`t1`.`a`) AS `CRC32(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)`,crc32(`test`.`t1`.`a`) AS `CRC32(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a'
SELECT a, HEX(a) FROM t1 WHERE HEX(a)='61';
a HEX(a)
a 61
diff --git a/mysql-test/r/ctype_cp1250_ch.result b/mysql-test/r/ctype_cp1250_ch.result
index d4f75778ace..5799331f73e 100644
--- a/mysql-test/r/ctype_cp1250_ch.result
+++ b/mysql-test/r/ctype_cp1250_ch.result
@@ -220,7 +220,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
DROP TABLE t1;
#
# End of MDEV-8694
diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result
index 4b92c8100ce..dab6bfc61df 100644
--- a/mysql-test/r/ctype_latin1.result
+++ b/mysql-test/r/ctype_latin1.result
@@ -7817,7 +7817,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
@@ -7938,7 +7938,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
@@ -8160,7 +8160,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a), CRC32(a) FROM t1 WHERE a='a' AND CRC32(a)=
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)`,crc32(`test`.`t1`.`a`) AS `CRC32(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and crc32(`test`.`t1`.`a`) = 3904355907
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)`,crc32(`test`.`t1`.`a`) AS `CRC32(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and crc32(`test`.`t1`.`a`) = 3904355907
SELECT a, HEX(a) FROM t1 WHERE HEX(a)='61';
a HEX(a)
a 61
@@ -8188,7 +8188,7 @@ EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='a' AND LENGTH(a)=2;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and length(`test`.`t1`.`a`) = 2
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 'a' and octet_length(`test`.`t1`.`a`) = 2
DROP TABLE t1;
#
# MDEV-8712 Wrong result for SELECT..WHERE latin1_bin_column=_latin1'a' AND latin1_bin_column='A'
diff --git a/mysql-test/r/ctype_latin2_ch.result b/mysql-test/r/ctype_latin2_ch.result
index 87357a49197..a396bc77fb6 100644
--- a/mysql-test/r/ctype_latin2_ch.result
+++ b/mysql-test/r/ctype_latin2_ch.result
@@ -160,7 +160,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
diff --git a/mysql-test/r/ctype_tis620.result b/mysql-test/r/ctype_tis620.result
index d5b4c632c31..cf66c81c647 100644
--- a/mysql-test/r/ctype_tis620.result
+++ b/mysql-test/r/ctype_tis620.result
@@ -3230,7 +3230,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
@@ -3446,7 +3446,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
diff --git a/mysql-test/r/ctype_uca.result b/mysql-test/r/ctype_uca.result
index 6c6dceba9cb..725e744c44e 100644
--- a/mysql-test/r/ctype_uca.result
+++ b/mysql-test/r/ctype_uca.result
@@ -8547,7 +8547,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
DROP TABLE t1;
#
# End of MDEV-8694
@@ -8705,7 +8705,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
DROP TABLE t1;
#
# End of MDEV-8694
diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result
index 5b2fadb8168..101cfc47cf1 100644
--- a/mysql-test/r/ctype_ucs.result
+++ b/mysql-test/r/ctype_ucs.result
@@ -5465,7 +5465,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
@@ -5586,7 +5586,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index f6a88d49579..87ca13cd743 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -6918,7 +6918,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` = 'a' and `test`.`t1`.`a` not like 'a '
DROP TABLE t1;
#
# End of MDEV-8694
@@ -7039,7 +7039,7 @@ EXPLAIN EXTENDED SELECT a, LENGTH(a) FROM t1 WHERE a NOT LIKE 'a ' AND a='a';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
+Note 1003 select `test`.`t1`.`a` AS `a`,octet_length(`test`.`t1`.`a`) AS `LENGTH(a)` from `test`.`t1` where `test`.`t1`.`a` not like 'a ' and `test`.`t1`.`a` = 'a'
DROP TABLE t1;
#
# End of MDEV-8694
diff --git a/mysql-test/r/default.result b/mysql-test/r/default.result
index 253cb412146..c18db932afa 100644
--- a/mysql-test/r/default.result
+++ b/mysql-test/r/default.result
@@ -2901,7 +2901,7 @@ SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) DEFAULT length(`a`),
+ `b` int(11) DEFAULT octet_length(`a`),
`c` int(11) DEFAULT char_length(`a`),
`d` int(11) DEFAULT bit_length(`a`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1
diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result
index 6857813559f..60ddd866507 100644
--- a/mysql-test/r/func_compress.result
+++ b/mysql-test/r/func_compress.result
@@ -22,7 +22,7 @@ explain extended select uncompressed_length(compress(@test_compress_string))=len
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select uncompressed_length(compress(@`test_compress_string`)) = length(@`test_compress_string`) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
+Note 1003 select uncompressed_length(compress(@`test_compress_string`)) = octet_length(@`test_compress_string`) AS `uncompressed_length(compress(@test_compress_string))=length(@test_compress_string)`
select uncompressed_length(compress(@test_compress_string));
uncompressed_length(compress(@test_compress_string))
117
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 9d3e5587426..28ed3cef9b4 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -966,7 +966,7 @@ explain extended select length('\n\t\r\b\0\_\%\\');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select length('\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`
+Note 1003 select octet_length('\n \r\0\\_\\%\\') AS `length('\n\t\r\b\0\_\%\\')`
explain extended select bit_length('\n\t\r\b\0\_\%\\');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -986,7 +986,7 @@ explain extended select length('hello');
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
Warnings:
-Note 1003 select length('hello') AS `length('hello')`
+Note 1003 select octet_length('hello') AS `length('hello')`
explain extended select char(ascii('h'));
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
@@ -1425,7 +1425,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t2 const PRIMARY PRIMARY 12 const 1 100.00 Using index
1 SIMPLE t1 ref code code 13 const 3 100.00 Using where; Using index
Warnings:
-Note 1003 select `test`.`t1`.`code` AS `code`,'a12' AS `id` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`code` = 'a12' and length(`test`.`t1`.`code`) = 5
+Note 1003 select `test`.`t1`.`code` AS `code`,'a12' AS `id` from `test`.`t1` join `test`.`t2` where `test`.`t1`.`code` = 'a12' and octet_length(`test`.`t1`.`code`) = 5
DROP TABLE t1,t2;
select encode(NULL, NULL);
encode(NULL, NULL)
@@ -4843,6 +4843,22 @@ YQ== 61
Yq== 62
DROP TABLE t1;
#
+# MDEV-12685 Oracle-compatible function CHR()
+#
+select chr(65);
+chr(65)
+A
+create database mysqltest1 CHARACTER SET = 'utf8' COLLATE = 'utf8_bin';
+use mysqltest1;
+select charset(chr(65)), length(chr(65)),char_length(chr(65));
+charset(chr(65)) length(chr(65)) char_length(chr(65))
+utf8 1 1
+select charset(chr(14844588)), length(chr(14844588)),char_length(chr(14844588));
+charset(chr(14844588)) length(chr(14844588)) char_length(chr(14844588))
+utf8 3 1
+drop database mysqltest1;
+use test;
+#
# End of 10.1 tests
#
#
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index a05c6a78cdb..4a37c56d28f 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -950,10 +950,10 @@ sec_to_time(1) + 0, from_unixtime(1) + 0;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `now() - now()` bigint(21) NOT NULL,
- `curtime() - curtime()` bigint(12) NOT NULL,
- `sec_to_time(1) + 0` bigint(12) DEFAULT NULL,
- `from_unixtime(1) + 0` bigint(21) DEFAULT NULL
+ `now() - now()` bigint(16) NOT NULL,
+ `curtime() - curtime()` int(9) NOT NULL,
+ `sec_to_time(1) + 0` int(9) DEFAULT NULL,
+ `from_unixtime(1) + 0` bigint(16) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
SELECT SEC_TO_TIME(3300000);
@@ -2054,11 +2054,11 @@ SEC_TO_TIME(1.123456)+0.1,
SEC_TO_TIME(1.1234567)+0.1;
SHOW COLUMNS FROM t1;
Field Type Null Key Default Extra
-SEC_TO_TIME(1)+0.1 decimal(12,1) YES NULL
-SEC_TO_TIME(1.1)+0.1 decimal(13,1) YES NULL
-SEC_TO_TIME(1.12)+0.1 decimal(14,2) YES NULL
-SEC_TO_TIME(1.123456)+0.1 decimal(18,6) YES NULL
-SEC_TO_TIME(1.1234567)+0.1 decimal(18,6) YES NULL
+SEC_TO_TIME(1)+0.1 decimal(9,1) YES NULL
+SEC_TO_TIME(1.1)+0.1 decimal(9,1) YES NULL
+SEC_TO_TIME(1.12)+0.1 decimal(10,2) YES NULL
+SEC_TO_TIME(1.123456)+0.1 decimal(14,6) YES NULL
+SEC_TO_TIME(1.1234567)+0.1 decimal(14,6) YES NULL
DROP TABLE t1;
CREATE TABLE t1 (a DATE) ENGINE=MyISAM;
INSERT INTO t1 VALUES ('2005-05-04'),('2000-02-23');
diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result
index 1a4a4bb48fd..df773a15ec2 100644
--- a/mysql-test/r/gis.result
+++ b/mysql-test/r/gis.result
@@ -4300,5 +4300,23 @@ t2 CREATE TABLE `t2` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP PROCEDURE p1;
#
+# MDEV-12798 Item_param does not preserve exact field type in EXECUTE IMMEDIATE 'CREATE TABLE AS SELECT ?' USING POINT(1,1)
+#
+EXECUTE IMMEDIATE 'CREATE TABLE t1 AS SELECT ?' USING POINT(1,1);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `?` point NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 AS SELECT ?';
+EXECUTE stmt USING POINT(1,1);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `?` point NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/r/metadata.result b/mysql-test/r/metadata.result
index 3ff332e03cc..cc249a7eab7 100644
--- a/mysql-test/r/metadata.result
+++ b/mysql-test/r/metadata.result
@@ -147,7 +147,7 @@ id data data
2 female no
select t1.id from t1 union select t2.id from t2;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def id id 1 4 1 Y 32768 0 63
+def id id 246 4 1 Y 32768 0 63
id
1
2
@@ -168,12 +168,12 @@ def aaa @arg00 @arg00 8 20 1 Y 32768 0 63
1
select 1 union select 1;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def 1 1 3 11 1 N 32769 0 63
+def 1 1 3 1 1 N 32769 0 63
1
1
select * from (select 1 union select 1) aaa;
Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
-def aaa 1 1 3 11 1 N 32769 0 63
+def aaa 1 1 3 1 1 N 32769 0 63
1
1
drop table t1;
diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result
index d1bcd243ae9..564269319cb 100644
--- a/mysql-test/r/mysqld--help.result
+++ b/mysql-test/r/mysqld--help.result
@@ -1404,7 +1404,7 @@ performance-schema-max-rwlock-instances -1
performance-schema-max-socket-classes 10
performance-schema-max-socket-instances -1
performance-schema-max-stage-classes 150
-performance-schema-max-statement-classes 189
+performance-schema-max-statement-classes 190
performance-schema-max-table-handles -1
performance-schema-max-table-instances -1
performance-schema-max-thread-classes 50
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 28f5cf635d0..735a0069ba0 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -2581,7 +2581,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 12,
"filtered": 100,
- "attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
+ "attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1"
}
}
}
@@ -2666,7 +2666,7 @@ EXPLAIN
"used_key_parts": ["e"],
"rows": 6,
"filtered": 100,
- "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1 and t2.d is not null"
+ "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1 and t2.d is not null"
},
"table": {
"table_name": "t1",
@@ -2716,7 +2716,7 @@ EXPLAIN
"rows": 5,
"filtered": 100,
"index_condition": "t2.d is not null",
- "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
+ "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1"
},
"table": {
"table_name": "t1",
@@ -2776,7 +2776,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and length(t2.f) = 1"
+ "attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and octet_length(t2.f) = 1"
}
}
}
@@ -2830,7 +2830,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
+ "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1"
}
}
}
@@ -2870,7 +2870,7 @@ EXPLAIN
"rows": 13,
"filtered": 100,
"index_condition": "t1.a is not null",
- "attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1"
+ "attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1"
},
"table": {
"table_name": "t2",
@@ -2882,7 +2882,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "length(t2.f) = 1"
+ "attached_condition": "octet_length(t2.f) = 1"
}
}
}
@@ -2958,7 +2958,7 @@ EXPLAIN
"rows": 13,
"filtered": 100,
"index_condition": "t1.a is not null",
- "attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1"
+ "attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1"
},
"table": {
"table_name": "t2",
@@ -2970,7 +2970,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "length(t2.f) = 1"
+ "attached_condition": "octet_length(t2.f) = 1"
}
}
}
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
index f2860aaab76..afce3c66c21 100644
--- a/mysql-test/r/range_mrr_icp.result
+++ b/mysql-test/r/range_mrr_icp.result
@@ -2588,7 +2588,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 12,
"filtered": 100,
- "attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
+ "attached_condition": "(t1.a,t2.e) in (<cache>((3,3)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1"
}
}
}
@@ -2673,7 +2673,7 @@ EXPLAIN
"used_key_parts": ["e"],
"rows": 6,
"filtered": 100,
- "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1 and t2.d is not null",
+ "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1 and t2.d is not null",
"mrr_type": "Rowid-ordered scan"
},
"table": {
@@ -2724,7 +2724,7 @@ EXPLAIN
"rows": 5,
"filtered": 100,
"index_condition": "t2.d is not null",
- "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1",
+ "attached_condition": "(t2.d,t2.e) in (<cache>((4,4)),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1",
"mrr_type": "Rowid-ordered scan"
},
"table": {
@@ -2786,7 +2786,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and length(t2.f) = 1"
+ "attached_condition": "(t1.a,t2.e) in ((4,t1.a + 1),(7,t1.a + 1),(8,t1.a + 1)) and octet_length(t2.f) = 1"
}
}
}
@@ -2840,7 +2840,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),<cache>((7,7)),<cache>((8,8))) and length(t2.f) = 1"
+ "attached_condition": "(t1.a,t2.e) in ((t2.e,t1.a + 1),<cache>((7,7)),<cache>((8,8))) and octet_length(t2.f) = 1"
}
}
}
@@ -2880,7 +2880,7 @@ EXPLAIN
"rows": 13,
"filtered": 100,
"index_condition": "t1.a is not null",
- "attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1",
+ "attached_condition": "(t1.a,2) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1",
"mrr_type": "Rowid-ordered scan"
},
"table": {
@@ -2893,7 +2893,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "length(t2.f) = 1"
+ "attached_condition": "octet_length(t2.f) = 1"
}
}
}
@@ -2969,7 +2969,7 @@ EXPLAIN
"rows": 13,
"filtered": 100,
"index_condition": "t1.a is not null",
- "attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and length(t1.c) = 1",
+ "attached_condition": "(t1.a,1 + 1) in (<cache>((2,2)),<cache>((7,7)),<cache>((8,8))) and octet_length(t1.c) = 1",
"mrr_type": "Rowid-ordered scan"
},
"table": {
@@ -2982,7 +2982,7 @@ EXPLAIN
"ref": ["test.t1.a"],
"rows": 3,
"filtered": 100,
- "attached_condition": "length(t2.f) = 1"
+ "attached_condition": "octet_length(t2.f) = 1"
}
}
}
diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result
index b83ee20e784..95a872f1498 100644
--- a/mysql-test/r/subselect.result
+++ b/mysql-test/r/subselect.result
@@ -1260,7 +1260,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(20) NOT NULL
+ `a` int(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/subselect_no_exists_to_in.result b/mysql-test/r/subselect_no_exists_to_in.result
index 87f33d1dbf4..7f07b974bb2 100644
--- a/mysql-test/r/subselect_no_exists_to_in.result
+++ b/mysql-test/r/subselect_no_exists_to_in.result
@@ -1264,7 +1264,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(20) NOT NULL
+ `a` int(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/subselect_no_mat.result b/mysql-test/r/subselect_no_mat.result
index 626990f2c9e..57c7a979d61 100644
--- a/mysql-test/r/subselect_no_mat.result
+++ b/mysql-test/r/subselect_no_mat.result
@@ -1267,7 +1267,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(20) NOT NULL
+ `a` int(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/subselect_no_opts.result b/mysql-test/r/subselect_no_opts.result
index 3637604646f..6e8be4a02a7 100644
--- a/mysql-test/r/subselect_no_opts.result
+++ b/mysql-test/r/subselect_no_opts.result
@@ -1263,7 +1263,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(20) NOT NULL
+ `a` int(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/subselect_no_scache.result b/mysql-test/r/subselect_no_scache.result
index afebd27c192..1b437f6919d 100644
--- a/mysql-test/r/subselect_no_scache.result
+++ b/mysql-test/r/subselect_no_scache.result
@@ -1266,7 +1266,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(20) NOT NULL
+ `a` int(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/subselect_no_semijoin.result b/mysql-test/r/subselect_no_semijoin.result
index 0f0fc59341e..6094c7e029d 100644
--- a/mysql-test/r/subselect_no_semijoin.result
+++ b/mysql-test/r/subselect_no_semijoin.result
@@ -1263,7 +1263,7 @@ a
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `a` bigint(20) NOT NULL
+ `a` int(3) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 (a int);
diff --git a/mysql-test/r/temp_table.result b/mysql-test/r/temp_table.result
index b833f4f9768..d1bec4a2af5 100644
--- a/mysql-test/r/temp_table.result
+++ b/mysql-test/r/temp_table.result
@@ -181,20 +181,20 @@ CREATE TABLE t2 ( c FLOAT(30,18) );
INSERT INTO t2 VALUES( 123456 );
SELECT AVG( c ) FROM t1 UNION SELECT 1;
AVG( c )
-12139
-1
+12139.000000000000000000
+1.000000000000000000
SELECT 1 UNION SELECT AVG( c ) FROM t1;
1
-1
-12139
+1.000000000000000000
+12139.000000000000000000
SELECT 1 UNION SELECT * FROM t2 UNION SELECT 1;
1
-1
-123456
+1.000000000000000000
+123456.000000000000000000
SELECT c/1 FROM t1 UNION SELECT 1;
c/1
-12139
-1
+12139.000000000000000000
+1.000000000000000000
DROP TABLE t1, t2;
create temporary table t1 (a int);
insert into t1 values (4711);
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index 7c7494903b6..d56fac962fe 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -615,14 +615,14 @@ SELECT * FROM t1 WHERE LENGTH(a)=11+RAND() AND a=' 2001-01-01';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2001-01-01' and <cache>(length(DATE'2001-01-01')) = 11 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2001-01-01' and <cache>(octet_length(DATE'2001-01-01')) = 11 + rand()
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=11+RAND() AND a=' garbage ';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Incorrect datetime value: ' garbage '
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'0000-00-00' and <cache>(length(DATE'0000-00-00')) = 11 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'0000-00-00' and <cache>(octet_length(DATE'0000-00-00')) = 11 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATE);
INSERT INTO t1 VALUES ('2001-01-01'),('2001-01-01');
@@ -641,7 +641,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=8+RAND() AND a='20010101';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2001-01-01' and <cache>(length(DATE'2001-01-01')) = 8 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2001-01-01' and <cache>(octet_length(DATE'2001-01-01')) = 8 + rand()
DROP TABLE t1;
#
# MDEV-8706 Wrong result for SELECT..WHERE time_column=TIMESTAMP'2015-08-30 00:00:00' AND time_column='00:00:00'
@@ -670,7 +670,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2015-08-30' and <cache>(length(DATE'2015-08-30')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2015-08-30' and <cache>(octet_length(DATE'2015-08-30')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATE);
INSERT INTO t1 VALUES ('2015-08-30'),('2015-08-31');
@@ -695,7 +695,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'24:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2015-08-31' and <cache>(length(DATE'2015-08-31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2015-08-31' and <cache>(octet_length(DATE'2015-08-31')) = 30 + rand()
DROP TABLE t1;
# In this example '00:00:00' is not recognized as TIME'00:00:00'
# and is treated as DATE'0000-00-00'.
@@ -721,7 +721,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'0000-00-00' and <cache>(length(DATE'0000-00-00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'0000-00-00' and <cache>(octet_length(DATE'0000-00-00')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATE);
INSERT INTO t1 VALUES ('2015-08-30'),('2015-08-31');
@@ -746,7 +746,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2015-08-30 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2015-08-30 00:00:00' and <cache>(length(DATE'2015-08-30')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2015-08-30 00:00:00' and <cache>(octet_length(DATE'2015-08-30')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATE);
INSERT INTO t1 VALUES ('2015-08-30'),('2015-08-31');
@@ -769,7 +769,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2015-08-30 00:00:00.1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2015-08-30 00:00:00.1' and <cache>(length(DATE'2015-08-30')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2015-08-30 00:00:00.1' and <cache>(octet_length(DATE'2015-08-30')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATE);
INSERT INTO t1 VALUES ('2015-08-30'),('2015-08-31');
@@ -794,7 +794,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='2015-08-30 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2015-08-30' and <cache>(length(DATE'2015-08-30')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = DATE'2015-08-30' and <cache>(octet_length(DATE'2015-08-30')) = 30 + rand()
DROP TABLE t1;
SET timestamp=DEFAULT;
#
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index 4dd214b61b3..95e421821c1 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -984,7 +984,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) <> 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) <> 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -1006,14 +1006,14 @@ SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = 19 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) = 19 + rand()
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage ';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Incorrect datetime value: ' garbage '
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-00 00:00:00' and <cache>(length(TIMESTAMP'0000-00-00 00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-00 00:00:00' and <cache>(octet_length(TIMESTAMP'0000-00-00 00:00:00')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -1038,7 +1038,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 00:00:00.0
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a DATETIME(6));;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00.000000'),('2001-01-01 00:00:01.000000');
@@ -1063,7 +1063,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIMESTAMP'2001-01-01 00:00:00.0
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00.000000')) = 40 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00.000000')) = 40 + rand()
DROP TABLE t1;
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
CREATE TABLE t1 (a DATETIME);;
@@ -1089,7 +1089,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = 40 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) = 40 + rand()
DROP TABLE t1;
#
# MDEV-8795 Equal expression propagation does not work for temporal literals
diff --git a/mysql-test/r/type_datetime_hires.result b/mysql-test/r/type_datetime_hires.result
index e2c2f83a96c..003ecf15e69 100644
--- a/mysql-test/r/type_datetime_hires.result
+++ b/mysql-test/r/type_datetime_hires.result
@@ -131,18 +131,18 @@ show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` datetime(4) DEFAULT NULL,
- `a+0` decimal(25,4) DEFAULT NULL,
- `a-1` decimal(25,4) DEFAULT NULL,
- `a*1` decimal(25,4) DEFAULT NULL,
- `a/2` decimal(28,8) DEFAULT NULL
+ `a+0` decimal(19,4) DEFAULT NULL,
+ `a-1` decimal(19,4) DEFAULT NULL,
+ `a*1` decimal(19,4) DEFAULT NULL,
+ `a/2` decimal(22,8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`max(a)` datetime(4) DEFAULT NULL,
`min(a)` datetime(4) DEFAULT NULL,
- `sum(a)` decimal(46,4) DEFAULT NULL,
- `avg(a)` decimal(28,8) DEFAULT NULL
+ `sum(a)` decimal(40,4) DEFAULT NULL,
+ `avg(a)` decimal(22,8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
create table t1 (f0_datetime datetime(0), f1_datetime datetime(1), f2_datetime datetime(2), f3_datetime datetime(3), f4_datetime datetime(4), f5_datetime datetime(5), f6_datetime datetime(6));
diff --git a/mysql-test/r/type_float.result b/mysql-test/r/type_float.result
index 43aed60749e..9a92ff21e9f 100644
--- a/mysql-test/r/type_float.result
+++ b/mysql-test/r/type_float.result
@@ -232,12 +232,12 @@ insert into t2 values ("1.23456780");
create table t3 select * from t2 union select * from t1;
select * from t3;
d
-1.2345678
-100000000
+1.234567800
+100000000.000000000
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
- `d` double DEFAULT NULL
+ `d` double(18,9) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
create table t1 select 105213674794682365.00 + 0.0 x;
@@ -562,7 +562,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=100e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 100e0 and <cache>(length(100)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 100e0 and <cache>(octet_length(100)) <> rand()
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE(10,1));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
@@ -582,7 +582,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10e0 and <cache>(length(1.1)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10e0 and <cache>(octet_length(1.1)) <> rand()
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE(10,2));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
@@ -602,7 +602,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10e0 and <cache>(length(1.10)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10e0 and <cache>(octet_length(1.10)) <> rand()
DROP TABLE t1;
CREATE TABLE t1 (a DOUBLE(10,3));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
@@ -622,7 +622,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=RAND() AND a=1.10e0;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10e0 and <cache>(length(1.100)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10e0 and <cache>(octet_length(1.100)) <> rand()
DROP TABLE t1;
#
# MDEV-8741 Equal field propagation leaves some remainders after simplifying WHERE zerofill_column=2010 AND zerofill_column>=2010
diff --git a/mysql-test/r/type_newdecimal.result b/mysql-test/r/type_newdecimal.result
index ab0e2dbc71d..ba84ff50504 100644
--- a/mysql-test/r/type_newdecimal.result
+++ b/mysql-test/r/type_newdecimal.result
@@ -2086,7 +2086,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10 and <cache>(length(1.1)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10 and <cache>(octet_length(1.1)) <> rand()
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(10,2));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
@@ -2106,7 +2106,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10 and <cache>(length(1.10)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10 and <cache>(octet_length(1.10)) <> rand()
DROP TABLE t1;
CREATE TABLE t1 (a DECIMAL(10,3));
INSERT INTO t1 VALUES (1.1),(1.2),(1.3);
@@ -2126,7 +2126,7 @@ SELECT * FROM t1 WHERE LENGTH(a)!=rand() AND a=1.10;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10 and <cache>(length(1.100)) <> rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1.10 and <cache>(octet_length(1.100)) <> rand()
DROP TABLE t1;
#
# MDEV-8741 Equal field propagation leaves some remainders after simplifying WHERE zerofill_column=2010 AND zerofill_column>=2010
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 3f125598f9b..1600732cec3 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -221,7 +221,7 @@ MAX(t0)+1
101011
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
-MAX(t0)+1 bigint(12) YES NULL
+MAX(t0)+1 int(9) YES NULL
DROP TABLE t2,t1;
CREATE TABLE t1 (t0 TIME);
INSERT INTO t1 VALUES ('10:10:10');
@@ -234,7 +234,7 @@ MAX(t0)+1.1
101011.1
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
-MAX(t0)+1.1 decimal(12,1) YES NULL
+MAX(t0)+1.1 decimal(9,1) YES NULL
DROP TABLE t2,t1;
CREATE TABLE t1 (t0 TIME);
INSERT INTO t1 VALUES ('10:10:10');
@@ -260,7 +260,7 @@ MAX(t1)+1
101011.0
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
-MAX(t1)+1 decimal(13,1) YES NULL
+MAX(t1)+1 decimal(9,1) YES NULL
DROP TABLE t2,t1;
CREATE TABLE t1 (t0 DATETIME);
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
@@ -273,7 +273,7 @@ MAX(t0)+1
20010101101011
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
-MAX(t0)+1 bigint(21) YES NULL
+MAX(t0)+1 bigint(16) YES NULL
DROP TABLE t2,t1;
CREATE TABLE t1 (t0 DATETIME);
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
@@ -286,7 +286,7 @@ MAX(t0)+1.1
20010101101011.1
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
-MAX(t0)+1.1 decimal(21,1) YES NULL
+MAX(t0)+1.1 decimal(16,1) YES NULL
DROP TABLE t2,t1;
CREATE TABLE t1 (t0 DATETIME);
INSERT INTO t1 VALUES ('2001-01-01 10:10:10');
@@ -312,7 +312,7 @@ MAX(t1)+1
20010101101011.0
SHOW COLUMNS FROM t2;
Field Type Null Key Default Extra
-MAX(t1)+1 decimal(22,1) YES NULL
+MAX(t1)+1 decimal(16,1) YES NULL
DROP TABLE t2,t1;
#
# MDEV-4858 Wrong results for a huge unsigned value inserted into a TIME column
@@ -424,7 +424,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect time value: '00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(length(TIME'00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(octet_length(TIME'00:00:00')) = 30 + rand()
DROP TABLE t1;
# Trailing fractional digits in string literals
CREATE TABLE t1 (a TIME);
@@ -447,7 +447,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='00:00:00.000000';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(length(TIME'00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(octet_length(TIME'00:00:00')) = 30 + rand()
DROP TABLE t1;
# Trailing fractional digits in temporal literals
CREATE TABLE t1 (a TIME);
@@ -470,7 +470,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'00:00:00.000000';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00.000000' and <cache>(length(TIME'00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00.000000' and <cache>(octet_length(TIME'00:00:00')) = 30 + rand()
DROP TABLE t1;
# Trailing fractional digits in temporal literals, same precision
CREATE TABLE t1 (a TIME(6));
@@ -490,7 +490,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'00:00:00.000000';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00.000000' and <cache>(length(TIME'00:00:00.000000')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00.000000' and <cache>(octet_length(TIME'00:00:00.000000')) = 30 + rand()
DROP TABLE t1;
# Leading spaces in string literals
CREATE TABLE t1 (a TIME);
@@ -513,7 +513,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(length(TIME'00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(octet_length(TIME'00:00:00')) = 30 + rand()
DROP TABLE t1;
# Numeric format in string literals
CREATE TABLE t1 (a TIME);
@@ -536,7 +536,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='000000';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(length(TIME'00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'00:00:00' and <cache>(octet_length(TIME'00:00:00')) = 30 + rand()
DROP TABLE t1;
#
# MDEV-8766 Wrong result for SELECT..WHERE LENGTH(time_column)=8 AND time_column=TIMESTAMP'2001-01-01 10:20:31'
@@ -565,7 +565,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 10:20:31';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIMESTAMP literal with a bigger scale and fractional second truncation
# Ok to propagate with precision truncation
@@ -589,7 +589,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 10:20:31.1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIMESTAMP literal with a bigger scale and no fractional second truncation
# Ok to propagate
@@ -615,7 +615,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 10:20:31.0
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIMESTAMP literal with a smaller scale
# Ok to propagate
@@ -638,7 +638,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 10:20:31.1
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(length(TIME'10:20:31.123000')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(octet_length(TIME'10:20:31.123000')) = 30 + rand()
DROP TABLE t1;
# TIME literal with a bigger scale and fractional second truncation
# Ok to propagate with precision truncation
@@ -662,7 +662,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'10:20:31.123';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIME literal with a bigger scale and no fractional second truncation
# Ok to propagate
@@ -688,7 +688,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'10:20:31.000';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.000' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.000' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIME literal with a smaller scale
# Ok to propagate
@@ -711,7 +711,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIME'10:20:31.123';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123' and <cache>(length(TIME'10:20:31.123000')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123' and <cache>(octet_length(TIME'10:20:31.123000')) = 30 + rand()
DROP TABLE t1;
# TIME-alike string literal with a bigger scale and fractional second truncation
# Ok to propagate with precision truncation
@@ -735,7 +735,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='10:20:31.123';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIME-alike string literal with a bigger scale and no fractional second truncation
# Ok to propagate
@@ -761,7 +761,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='10:20:31.000';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31' and <cache>(length(TIME'10:20:31')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31' and <cache>(octet_length(TIME'10:20:31')) = 30 + rand()
DROP TABLE t1;
# TIME-alike string literal with a smaller scale
# Ok to propagate
@@ -784,7 +784,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a='10:20:31.123';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(length(TIME'10:20:31.123000')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:31.123000' and <cache>(octet_length(TIME'10:20:31.123000')) = 30 + rand()
DROP TABLE t1;
SET timestamp=DEFAULT;
SET @@old_mode=zero_date_time_cast;
@@ -821,7 +821,7 @@ SELECT * FROM t1 WHERE a=TIMESTAMP'0000-00-00 10:20:30' AND LENGTH(a)=30+RAND();
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:30' and <cache>(length(TIME'10:20:30')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:30' and <cache>(octet_length(TIME'10:20:30')) = 30 + rand()
# Old mode, TIMESTAMP literal, zon-zero YYYYMMDD, no propagation
SELECT * FROM t1 WHERE a=TIMESTAMP'0000-00-01 10:20:30';
a
@@ -834,13 +834,13 @@ SELECT * FROM t1 WHERE a=TIMESTAMP'0000-00-01 10:20:30' AND LENGTH(a)=8;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-01 10:20:30' and length(`test`.`t1`.`a`) = 8
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-01 10:20:30' and octet_length(`test`.`t1`.`a`) = 8
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a=TIMESTAMP'0000-00-01 10:20:30' AND LENGTH(a)=30+RAND();
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-01 10:20:30' and length(`test`.`t1`.`a`) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-01 10:20:30' and octet_length(`test`.`t1`.`a`) = 30 + rand()
# Old mode, TIMESTAMP-alike string literal, zero YYYYMMDD, Ok to propagate
SELECT * FROM t1 WHERE a='0000-00-00 10:20:30';
a
@@ -859,7 +859,7 @@ SELECT * FROM t1 WHERE a='0000-00-00 10:20:30' AND LENGTH(a)=30+RAND();
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:30' and <cache>(length(TIME'10:20:30')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIME'10:20:30' and <cache>(octet_length(TIME'10:20:30')) = 30 + rand()
# Old mode, TIMESTAMP-alike literal, zon-zero YYYYMMDD, no propagation
SELECT * FROM t1 WHERE a='0000-00-01 10:20:30';
a
@@ -872,13 +872,13 @@ SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = '0000-00-01 10:20:30' and length(`test`.`t1`.`a`) = 8
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = '0000-00-01 10:20:30' and octet_length(`test`.`t1`.`a`) = 8
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=30+RAND();
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = '0000-00-01 10:20:30' and length(`test`.`t1`.`a`) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = '0000-00-01 10:20:30' and octet_length(`test`.`t1`.`a`) = 30 + rand()
DROP TABLE t1;
SET @@old_mode=DEFAULT;
#
diff --git a/mysql-test/r/type_time_hires.result b/mysql-test/r/type_time_hires.result
index a9345a7e83f..47185116bea 100644
--- a/mysql-test/r/type_time_hires.result
+++ b/mysql-test/r/type_time_hires.result
@@ -145,18 +145,18 @@ show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` time(4) DEFAULT NULL,
- `a+0` decimal(16,4) DEFAULT NULL,
- `a-1` decimal(16,4) DEFAULT NULL,
- `a*1` decimal(16,4) DEFAULT NULL,
- `a/2` decimal(19,8) DEFAULT NULL
+ `a+0` decimal(12,4) DEFAULT NULL,
+ `a-1` decimal(12,4) DEFAULT NULL,
+ `a*1` decimal(12,4) DEFAULT NULL,
+ `a/2` decimal(15,8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`max(a)` time(4) DEFAULT NULL,
`min(a)` time(4) DEFAULT NULL,
- `sum(a)` decimal(37,4) DEFAULT NULL,
- `avg(a)` decimal(19,8) DEFAULT NULL
+ `sum(a)` decimal(33,4) DEFAULT NULL,
+ `avg(a)` decimal(15,8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
create table t1 (f0_time time(0), f1_time time(1), f2_time time(2), f3_time time(3), f4_time time(4), f5_time time(5), f6_time time(6));
diff --git a/mysql-test/r/type_timestamp.result b/mysql-test/r/type_timestamp.result
index cf4f6df4b04..b0405bc4ad7 100644
--- a/mysql-test/r/type_timestamp.result
+++ b/mysql-test/r/type_timestamp.result
@@ -840,7 +840,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Truncated incorrect datetime value: '2001-01-01 00:00:00x'
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) <> 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) <> 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -862,14 +862,14 @@ SELECT * FROM t1 WHERE LENGTH(a)=19+RAND() AND a=' 2001-01-01 00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = 19 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) = 19 + rand()
EXPLAIN EXTENDED
SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=' garbage ';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
Warning 1292 Incorrect datetime value: ' garbage '
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-00 00:00:00' and <cache>(length(TIMESTAMP'0000-00-00 00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'0000-00-00 00:00:00' and <cache>(octet_length(TIMESTAMP'0000-00-00 00:00:00')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP);;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00'),('2001-01-01 00:00:01');
@@ -894,7 +894,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=30+RAND() AND a=TIMESTAMP'2001-01-01 00:00:00.0
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = 30 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) = 30 + rand()
DROP TABLE t1;
CREATE TABLE t1 (a TIMESTAMP(6));;
INSERT INTO t1 VALUES ('2001-01-01 00:00:00.000000'),('2001-01-01 00:00:01.000000');
@@ -919,7 +919,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIMESTAMP'2001-01-01 00:00:00.0
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00.000000')) = 40 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00.000000' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00.000000')) = 40 + rand()
DROP TABLE t1;
SET timestamp=UNIX_TIMESTAMP('2001-01-01 10:20:30');
CREATE TABLE t1 (a TIMESTAMP);;
@@ -945,7 +945,7 @@ SELECT * FROM t1 WHERE LENGTH(a)=40+RAND() AND a=TIME'00:00:00';
id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(length(TIMESTAMP'2001-01-01 00:00:00')) = 40 + rand()
+Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = TIMESTAMP'2001-01-01 00:00:00' and <cache>(octet_length(TIMESTAMP'2001-01-01 00:00:00')) = 40 + rand()
DROP TABLE t1;
#
# End of 10.1 tests
diff --git a/mysql-test/r/type_timestamp_hires.result b/mysql-test/r/type_timestamp_hires.result
index 7179277aa9a..fa6adc075ed 100644
--- a/mysql-test/r/type_timestamp_hires.result
+++ b/mysql-test/r/type_timestamp_hires.result
@@ -131,18 +131,18 @@ show create table t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` timestamp(4) NOT NULL DEFAULT current_timestamp(4) ON UPDATE current_timestamp(4),
- `a+0` decimal(25,4) NOT NULL,
- `a-1` decimal(25,4) NOT NULL,
- `a*1` decimal(25,4) NOT NULL,
- `a/2` decimal(28,8) DEFAULT NULL
+ `a+0` decimal(19,4) NOT NULL,
+ `a-1` decimal(19,4) NOT NULL,
+ `a*1` decimal(19,4) NOT NULL,
+ `a/2` decimal(22,8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
`max(a)` timestamp(4) NULL DEFAULT NULL,
`min(a)` timestamp(4) NULL DEFAULT NULL,
- `sum(a)` decimal(46,4) DEFAULT NULL,
- `avg(a)` decimal(28,8) DEFAULT NULL
+ `sum(a)` decimal(40,4) DEFAULT NULL,
+ `avg(a)` decimal(22,8) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1, t2, t3;
create table t1 (f0_timestamp timestamp(0), f1_timestamp timestamp(1), f2_timestamp timestamp(2), f3_timestamp timestamp(3), f4_timestamp timestamp(4), f5_timestamp timestamp(5), f6_timestamp timestamp(6));
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result
index 9949defebf7..e0aa93d5c97 100644
--- a/mysql-test/r/union.result
+++ b/mysql-test/r/union.result
@@ -852,7 +852,7 @@ select * from t1;
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `1` int(11) NOT NULL DEFAULT 0
+ `1` int(2) NOT NULL DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARSET=latin1
drop table t1;
create table t1 select _latin1"test" union select _latin2"testt" ;
@@ -1608,7 +1608,7 @@ NULL binary(0) YES NULL
CREATE TABLE t5 SELECT NULL UNION SELECT NULL;
DESC t5;
Field Type Null Key Default Extra
-NULL binary(0) YES NULL
+NULL null YES NULL
CREATE TABLE t6
SELECT * FROM (SELECT * FROM (SELECT NULL)a) b UNION SELECT a FROM t1;
DESC t6;
@@ -2195,16 +2195,223 @@ CREATE OR REPLACE TABLE t1 AS SELECT 1 UNION SELECT 1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `1` int(11) NOT NULL DEFAULT 0
+ `1` int(1) NOT NULL DEFAULT 0
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE OR REPLACE TABLE t1 AS SELECT * FROM (SELECT 1 UNION SELECT 1) AS t0;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
- `1` int(11) NOT NULL DEFAULT 0
+ `1` int(1) NOT NULL DEFAULT 0
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
+#
+CREATE TABLE t1 (a INT, b INT UNSIGNED);
+INSERT INTO t1 VALUES (0x7FFFFFFF,0xFFFFFFFF);
+CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` decimal(10,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2 ORDER BY a;
+a
+2147483647
+4294967295
+DROP TABLE t2;
+CREATE TABLE t2 AS SELECT COALESCE(a,b), COALESCE(b,a) FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `COALESCE(a,b)` decimal(10,0) DEFAULT NULL,
+ `COALESCE(b,a)` decimal(10,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+SELECT * FROM t2;
+COALESCE(a,b) COALESCE(b,a)
+2147483647 4294967295
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
+#
+CREATE TABLE t1 AS SELECT COALESCE(10.1,CAST(10 AS UNSIGNED)) AS a;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` decimal(3,1) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 10.1 AS a UNION SELECT CAST(10 AS UNSIGNED);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `a` decimal(3,1) NOT NULL DEFAULT 0.0
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
#
+# MDEV-12594 UNION between fixed length double columns does not always preserve scale
+#
+CREATE TABLE t1 (a FLOAT(20,4), b FLOAT(20,3), c FLOAT(20,4));
+INSERT INTO t1 VALUES (1111,2222,3333);
+CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` float(20,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 SELECT a FROM t1 UNION SELECT c FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` float(20,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 SELECT b FROM t1 UNION SELECT b FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `b` float(20,3) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 SELECT c FROM t1 UNION SELECT c FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` float(20,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 SELECT c FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` float(20,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` float(21,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+CREATE OR REPLACE TABLE t2 AS SELECT b FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `b` float(21,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1;
+# Corner case
+CREATE TABLE t1 (a FLOAT(255,4), b FLOAT(255,3));
+INSERT INTO t1 VALUES (1111,2222);
+CREATE OR REPLACE TABLE t2 AS SELECT b FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `b` float(255,4) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1;
+#
+# MDEV-12595 UNION converts INT to BIGINT
+#
+CREATE TABLE t1 AS SELECT
+1,
+-1,
+COALESCE(1,1),
+COALESCE(-1,-1),
+COALESCE(1,-1),
+COALESCE(-1,1);
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `1` int(1) NOT NULL,
+ `-1` int(2) NOT NULL,
+ `COALESCE(1,1)` int(1) NOT NULL,
+ `COALESCE(-1,-1)` int(2) NOT NULL,
+ `COALESCE(1,-1)` int(2) NOT NULL,
+ `COALESCE(-1,1)` int(2) NOT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT 1 AS c1,1 AS c2,-1 AS c3,-1 AS c4 UNION SELECT 1,-1,1,-1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` int(1) NOT NULL DEFAULT 0,
+ `c2` int(2) NOT NULL DEFAULT 0,
+ `c3` int(2) NOT NULL DEFAULT 0,
+ `c4` int(2) NOT NULL DEFAULT 0
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+#
+# MDEV-12599 UNION is not symmetric when mixing INT and CHAR
+#
+CREATE OR REPLACE TABLE t1 AS SELECT 1 AS c1, 'a' AS c2 UNION SELECT 'a', 1;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` varchar(1) NOT NULL DEFAULT '',
+ `c2` varchar(1) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 11112222 AS c1, 'a' AS c2 UNION SELECT 'a', 11112222;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` varchar(8) NOT NULL DEFAULT '',
+ `c2` varchar(8) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 111122223333 AS c1, 'a' AS c2 UNION SELECT 'a', 111122223333;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` varchar(12) NOT NULL DEFAULT '',
+ `c2` varchar(12) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 1111222233334444 AS c1, 'a' AS c2 UNION SELECT 'a', 1111222233334444;
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `c1` varchar(16) NOT NULL DEFAULT '',
+ `c2` varchar(16) NOT NULL DEFAULT ''
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+CREATE TABLE t1 (a INT(3), b VARCHAR(1));
+CREATE TABLE t2 AS SELECT a,b FROM t1 UNION SELECT b,a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` varchar(11) DEFAULT NULL,
+ `b` varchar(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1;
+CREATE TABLE t1 (a BIGINT(3), b VARCHAR(1));
+CREATE TABLE t2 AS SELECT a,b FROM t1 UNION SELECT b,a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` varchar(20) DEFAULT NULL,
+ `b` varchar(20) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1;
+CREATE TABLE t1 (a BIGINT(12), b VARCHAR(1));
+CREATE TABLE t2 AS SELECT a,b FROM t1 UNION SELECT b,a FROM t1;
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `a` varchar(20) DEFAULT NULL,
+ `b` varchar(20) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+DROP TABLE t1;
+#
# End of 10.3 tests
#
diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result
index 14b92e93133..2bb12c3d380 100644
--- a/mysql-test/r/view.result
+++ b/mysql-test/r/view.result
@@ -4582,7 +4582,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where
1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where
Warnings:
-Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`a` = `test`.`t1`.`a`) where `test`.`t1`.`b` = 1 or `test`.`t1`.`a` = 'a' and length(`test`.`t1`.`a`) >= `test`.`t1`.`b`
+Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`a` = `test`.`t1`.`a`) where `test`.`t1`.`b` = 1 or `test`.`t1`.`a` = 'a' and octet_length(`test`.`t1`.`a`) >= `test`.`t1`.`b`
DROP VIEW v1;
DROP TABLE t1,t2;
# Bug#798625: duplicate of the previous one, but without crash
diff --git a/mysql-test/suite/funcs_1/r/innodb_func_view.result b/mysql-test/suite/funcs_1/r/innodb_func_view.result
index 04e689cc651..481787e4eaa 100644
--- a/mysql-test/suite/funcs_1/r/innodb_func_view.result
+++ b/mysql-test/suite/funcs_1/r/innodb_func_view.result
@@ -857,7 +857,7 @@ my_varbinary_1000, id FROM t1_values
WHERE select_id = 155 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_varbinary_1000`) AS `LENGTH(my_varbinary_1000)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_varbinary_1000`) AS `LENGTH(my_varbinary_1000)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 155 OR select_id IS NULL) order by id;
@@ -871,7 +871,7 @@ my_binary_30, id FROM t1_values
WHERE select_id = 154 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_binary_30`) AS `LENGTH(my_binary_30)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_binary_30`) AS `LENGTH(my_binary_30)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 154 OR select_id IS NULL) order by id;
@@ -885,7 +885,7 @@ my_varchar_1000, id FROM t1_values
WHERE select_id = 153 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_varchar_1000`) AS `LENGTH(my_varchar_1000)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_varchar_1000`) AS `LENGTH(my_varchar_1000)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 153 OR select_id IS NULL) order by id;
@@ -899,7 +899,7 @@ my_char_30, id FROM t1_values
WHERE select_id = 152 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_char_30`) AS `LENGTH(my_char_30)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_char_30`) AS `LENGTH(my_char_30)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 152 OR select_id IS NULL) order by id;
diff --git a/mysql-test/suite/funcs_1/r/memory_func_view.result b/mysql-test/suite/funcs_1/r/memory_func_view.result
index 765869a312d..3a75e4abac5 100644
--- a/mysql-test/suite/funcs_1/r/memory_func_view.result
+++ b/mysql-test/suite/funcs_1/r/memory_func_view.result
@@ -858,7 +858,7 @@ my_varbinary_1000, id FROM t1_values
WHERE select_id = 155 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_varbinary_1000`) AS `LENGTH(my_varbinary_1000)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_varbinary_1000`) AS `LENGTH(my_varbinary_1000)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 155 OR select_id IS NULL) order by id;
@@ -872,7 +872,7 @@ my_binary_30, id FROM t1_values
WHERE select_id = 154 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_binary_30`) AS `LENGTH(my_binary_30)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_binary_30`) AS `LENGTH(my_binary_30)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 154 OR select_id IS NULL) order by id;
@@ -886,7 +886,7 @@ my_varchar_1000, id FROM t1_values
WHERE select_id = 153 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_varchar_1000`) AS `LENGTH(my_varchar_1000)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_varchar_1000`) AS `LENGTH(my_varchar_1000)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 153 OR select_id IS NULL) order by id;
@@ -900,7 +900,7 @@ my_char_30, id FROM t1_values
WHERE select_id = 152 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_char_30`) AS `LENGTH(my_char_30)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_char_30`) AS `LENGTH(my_char_30)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 152 OR select_id IS NULL) order by id;
diff --git a/mysql-test/suite/funcs_1/r/myisam_func_view.result b/mysql-test/suite/funcs_1/r/myisam_func_view.result
index 765869a312d..3a75e4abac5 100644
--- a/mysql-test/suite/funcs_1/r/myisam_func_view.result
+++ b/mysql-test/suite/funcs_1/r/myisam_func_view.result
@@ -858,7 +858,7 @@ my_varbinary_1000, id FROM t1_values
WHERE select_id = 155 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_varbinary_1000`) AS `LENGTH(my_varbinary_1000)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_varbinary_1000`) AS `LENGTH(my_varbinary_1000)`,`t1_values`.`my_varbinary_1000` AS `my_varbinary_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 155 OR select_id IS NULL) order by id;
@@ -872,7 +872,7 @@ my_binary_30, id FROM t1_values
WHERE select_id = 154 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_binary_30`) AS `LENGTH(my_binary_30)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_binary_30`) AS `LENGTH(my_binary_30)`,`t1_values`.`my_binary_30` AS `my_binary_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 154 OR select_id IS NULL) order by id;
@@ -886,7 +886,7 @@ my_varchar_1000, id FROM t1_values
WHERE select_id = 153 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_varchar_1000`) AS `LENGTH(my_varchar_1000)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_varchar_1000`) AS `LENGTH(my_varchar_1000)`,`t1_values`.`my_varchar_1000` AS `my_varchar_1000`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 153 OR select_id IS NULL) order by id;
@@ -900,7 +900,7 @@ my_char_30, id FROM t1_values
WHERE select_id = 152 OR select_id IS NULL order by id;
SHOW CREATE VIEW v1;
View Create View character_set_client collation_connection
-v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select length(`t1_values`.`my_char_30`) AS `LENGTH(my_char_30)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select octet_length(`t1_values`.`my_char_30`) AS `LENGTH(my_char_30)`,`t1_values`.`my_char_30` AS `my_char_30`,`t1_values`.`id` AS `id` from `t1_values` latin1 latin1_swedish_ci
SELECT v1.* FROM v1
WHERE v1.id IN (SELECT id FROM t1_values
WHERE select_id = 152 OR select_id IS NULL) order by id;
diff --git a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result
index f8f447d493d..5e165b42be7 100644
--- a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result
+++ b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_innodb.result
@@ -915,7 +915,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
`b` varchar(10) DEFAULT NULL,
- `c` varchar(20) GENERATED ALWAYS AS (insert(`a`,length(`a`),length(`b`),`b`)) VIRTUAL
+ `c` varchar(20) GENERATED ALWAYS AS (insert(`a`,octet_length(`a`),octet_length(`b`),`b`)) VIRTUAL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
insert into t1 values ('start,','end',default);
select * from t1;
@@ -978,7 +978,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) GENERATED ALWAYS AS (length(`a`)) VIRTUAL
+ `b` int(11) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
insert into t1 values ('text',default);
select * from t1;
@@ -1142,7 +1142,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) GENERATED ALWAYS AS (length(`a`)) VIRTUAL
+ `b` int(11) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
insert into t1 values ('text',default);
select * from t1;
diff --git a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result
index 9db5f0c7c38..7a18bf2d8fb 100644
--- a/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result
+++ b/mysql-test/suite/gcol/r/gcol_supported_sql_funcs_myisam.result
@@ -915,7 +915,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
`b` varchar(10) DEFAULT NULL,
- `c` varchar(20) GENERATED ALWAYS AS (insert(`a`,length(`a`),length(`b`),`b`)) VIRTUAL
+ `c` varchar(20) GENERATED ALWAYS AS (insert(`a`,octet_length(`a`),octet_length(`b`),`b`)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('start,','end',default);
select * from t1;
@@ -978,7 +978,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) GENERATED ALWAYS AS (length(`a`)) VIRTUAL
+ `b` int(11) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('text',default);
select * from t1;
@@ -1142,7 +1142,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) GENERATED ALWAYS AS (length(`a`)) VIRTUAL
+ `b` int(11) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('text',default);
select * from t1;
diff --git a/mysql-test/suite/rpl/r/rpl_charset.result b/mysql-test/suite/rpl/r/rpl_charset.result
index a96cb26dd9d..5bda623172b 100644
--- a/mysql-test/suite/rpl/r/rpl_charset.result
+++ b/mysql-test/suite/rpl/r/rpl_charset.result
@@ -121,4 +121,27 @@ primary key (`pk`)
set @p=_latin1 'test';
update t1 set pk='test' where pk=@p;
drop table t1;
+#
+# Start of 10.3 tests
+#
+#
+# MDEV-12685 Oracle-compatible function CHR()
+#
+connection master;
+CREATE DATABASE db1 DEFAULT CHARACTER SET latin1 COLLATE latin1_bin;
+USE db1;
+CREATE TABLE t1 AS SELECT CHR(0x60);
+connection slave;
+SHOW CREATE TABLE db1.t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `CHR(0x60)` varchar(4) COLLATE latin1_bin DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_bin
+connection master;
+USE test;
+DROP DATABASE db1;
+connection slave;
+#
+# End of 10.3 tests
+#
include/rpl_end.inc
diff --git a/mysql-test/suite/sql_sequence/alter.result b/mysql-test/suite/sql_sequence/alter.result
new file mode 100644
index 00000000000..43afe2377c3
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/alter.result
@@ -0,0 +1,238 @@
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 'test.t1'
+#
+# Test alter sequence
+#
+CREATE SEQUENCE t1 nocache engine=myisam;
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+1 1 9223372036854775806 1 1 0 0 0
+select next value for t1;
+next value for t1
+1
+alter sequence t1 start=50;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 50 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+2 1 9223372036854775806 50 1 0 0 0
+select next value for t1;
+next value for t1
+2
+alter sequence t1 minvalue=-100;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 50 minvalue -100 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+3 -100 9223372036854775806 50 1 0 0 0
+alter sequence t1 minvalue=100 start=100;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 100 minvalue 100 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+3 100 9223372036854775806 100 1 0 0 0
+alter sequence t1 maxvalue=500;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 100 minvalue 100 maxvalue 500 increment by 1 nocache nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+3 100 500 100 1 0 0 0
+drop sequence t1;
+CREATE SEQUENCE t1 engine=myisam;
+alter sequence t1 nocache;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=MyISAM
+alter sequence t1 cache=100;
+flush tables;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 100 nocycle ENGINE=MyISAM
+alter sequence t1 nocache;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=MyISAM
+flush tables;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 nocache nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+1 1 9223372036854775806 1 1 0 0 0
+select next value for t1;
+next value for t1
+1
+select next value for t1;
+next value for t1
+2
+select next value for t1;
+next value for t1
+3
+select next_value, round from t1;
+next_value round
+4 0
+drop sequence t1;
+CREATE SEQUENCE t1 maxvalue=100 engine=myisam;
+alter sequence t1 no maxvalue;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+1 1 9223372036854775806 1 1 1000 0 0
+alter sequence t1 cycle;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 cycle ENGINE=MyISAM
+alter sequence t1 nocycle;
+alter sequence t1 start=15 restart minvalue=10 maxvalue=20 cycle;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 15 minvalue 10 maxvalue 20 increment by 1 cache 1000 cycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+15 10 20 15 1 1000 1 0
+select NEXT VALUE for t1 from seq_1_to_10;
+NEXT VALUE for t1
+15
+16
+17
+18
+19
+20
+10
+11
+12
+13
+alter sequence t1 restart with 17 minvalue=10 maxvalue=20 cycle;
+select NEXT VALUE for t1 from seq_1_to_10;
+NEXT VALUE for t1
+17
+18
+19
+20
+10
+11
+12
+13
+14
+15
+drop sequence t1;
+CREATE SEQUENCE t1 maxvalue=100;
+alter sequence t1 increment=-2 start with 50 minvalue=-100;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 50 minvalue -100 maxvalue 100 increment by -2 cache 1000 nocycle ENGINE=MyISAM
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+1 -100 100 50 -2 1000 0 0
+select NEXT VALUE for t1 from seq_1_to_10;
+NEXT VALUE for t1
+1
+-1
+-3
+-5
+-7
+-9
+-11
+-13
+-15
+-17
+drop sequence t1;
+#
+# InnoDB (some things work different with InnoDB)
+
+CREATE SEQUENCE t1 cache 10 engine=innodb;
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+1 1 9223372036854775806 1 1 10 0 0
+select next value for t1;
+next value for t1
+1
+alter sequence t1 start=100;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 100 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 10 nocycle ENGINE=InnoDB
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+11 1 9223372036854775806 100 1 10 0 0
+select next value for t1;
+next value for t1
+11
+drop sequence t1;
+#
+# ALTER TABLE
+#
+CREATE SEQUENCE t1 engine=innodb;
+select next value for t1;
+next value for t1
+1
+alter table t1 rename t2;
+select next value for t2;
+next value for t2
+1001
+rename table t2 to t1;
+select next value for t1;
+next value for t1
+2001
+alter table t1 comment="foo";
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB COMMENT='foo'
+alter table t1 engine=myisam;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=MyISAM COMMENT='foo'
+alter table t1 engine=innodb;
+show create sequence t1;
+Table Create Table
+t1 CREATE SEQUENCE `t1` start with 1 minvalue 1 maxvalue 9223372036854775806 increment by 1 cache 1000 nocycle ENGINE=InnoDB COMMENT='foo'
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+3001 1 9223372036854775806 1 1 1000 0 0
+drop sequence t1;
+CREATE SEQUENCE t1 engine=myisam;
+alter sequence t1 minvalue=100;
+ERROR HY000: Sequence 'test.t1' values are conflicting
+drop sequence t1;
+CREATE SEQUENCE t1 engine=myisam;
+alter sequence t1 minvalue=25 maxvalue=20;
+ERROR HY000: Sequence 'test.t1' values are conflicting
+drop sequence t1;
+create table t1 (a int);
+alter sequence t1 minvalue=100;
+ERROR 42S02: 'test.t1' is not a SEQUENCE
+drop table t1;
+alter sequence if exists t1 minvalue=100;
+Warnings:
+Note 4067 Unknown SEQUENCE: 'test.t1'
+alter sequence t1 minvalue=100;
+ERROR 42S02: Table 'test.t1' doesn't exist
+create sequence t1;
+alter sequence t1;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1
+drop sequence t1;
+CREATE SEQUENCE t1 maxvalue=100;
+alter sequence t1 increment=-2 start with 50;
+select next value for t1;
+next value for t1
+1
+select next value for t1;
+ERROR HY000: Sequence 'test.t1' has run out
+select * from t1;
+next_value min_value max_value start increment cache cycle round
+0 1 100 50 -2 1000 0 0
+alter sequence t1 restart;
+select next value for t1;
+next value for t1
+50
+alter sequence t1 restart with 90;
+select next value for t1;
+next value for t1
+90
+drop sequence t1;
diff --git a/mysql-test/suite/sql_sequence/alter.test b/mysql-test/suite/sql_sequence/alter.test
new file mode 100644
index 00000000000..7454f5900f7
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/alter.test
@@ -0,0 +1,139 @@
+--source include/have_sequence.inc
+--source include/have_innodb.inc
+
+drop table if exists t1;
+
+--echo #
+--echo # Test alter sequence
+--echo #
+
+CREATE SEQUENCE t1 nocache engine=myisam;
+select * from t1;
+select next value for t1;
+alter sequence t1 start=50;
+show create sequence t1;
+select * from t1;
+select next value for t1;
+
+alter sequence t1 minvalue=-100;
+show create sequence t1;
+select * from t1;
+alter sequence t1 minvalue=100 start=100;
+show create sequence t1;
+select * from t1;
+
+alter sequence t1 maxvalue=500;
+show create sequence t1;
+select * from t1;
+drop sequence t1;
+
+CREATE SEQUENCE t1 engine=myisam;
+alter sequence t1 nocache;
+show create sequence t1;
+alter sequence t1 cache=100;
+flush tables;
+show create sequence t1;
+alter sequence t1 nocache;
+show create sequence t1;
+flush tables;
+show create sequence t1;
+select * from t1;
+select next value for t1;
+select next value for t1;
+select next value for t1;
+select next_value, round from t1;
+drop sequence t1;
+
+CREATE SEQUENCE t1 maxvalue=100 engine=myisam;
+alter sequence t1 no maxvalue;
+show create sequence t1;
+select * from t1;
+alter sequence t1 cycle;
+show create sequence t1;
+alter sequence t1 nocycle;
+alter sequence t1 start=15 restart minvalue=10 maxvalue=20 cycle;
+show create sequence t1;
+select * from t1;
+select NEXT VALUE for t1 from seq_1_to_10;
+alter sequence t1 restart with 17 minvalue=10 maxvalue=20 cycle;
+select NEXT VALUE for t1 from seq_1_to_10;
+drop sequence t1;
+
+CREATE SEQUENCE t1 maxvalue=100;
+alter sequence t1 increment=-2 start with 50 minvalue=-100;
+show create sequence t1;
+select * from t1;
+select NEXT VALUE for t1 from seq_1_to_10;
+drop sequence t1;
+
+--echo #
+--echo # InnoDB (some things work different with InnoDB)
+--echo
+
+CREATE SEQUENCE t1 cache 10 engine=innodb;
+select * from t1;
+select next value for t1;
+alter sequence t1 start=100;
+show create sequence t1;
+select * from t1;
+select next value for t1;
+drop sequence t1;
+
+--echo #
+--echo # ALTER TABLE
+--echo #
+
+CREATE SEQUENCE t1 engine=innodb;
+select next value for t1;
+alter table t1 rename t2;
+select next value for t2;
+rename table t2 to t1;
+select next value for t1;
+alter table t1 comment="foo";
+show create sequence t1;
+alter table t1 engine=myisam;
+show create sequence t1;
+alter table t1 engine=innodb;
+show create sequence t1;
+select * from t1;
+drop sequence t1;
+
+#
+# Some error testing
+#
+
+CREATE SEQUENCE t1 engine=myisam;
+--error ER_SEQUENCE_INVALID_DATA
+alter sequence t1 minvalue=100;
+drop sequence t1;
+
+CREATE SEQUENCE t1 engine=myisam;
+--error ER_SEQUENCE_INVALID_DATA
+alter sequence t1 minvalue=25 maxvalue=20;
+drop sequence t1;
+
+create table t1 (a int);
+--error ER_NOT_SEQUENCE
+alter sequence t1 minvalue=100;
+drop table t1;
+
+alter sequence if exists t1 minvalue=100;
+--error ER_NO_SUCH_TABLE
+alter sequence t1 minvalue=100;
+
+create sequence t1;
+--error ER_PARSE_ERROR
+alter sequence t1;
+drop sequence t1;
+
+CREATE SEQUENCE t1 maxvalue=100;
+alter sequence t1 increment=-2 start with 50;
+select next value for t1;
+--error ER_SEQUENCE_RUN_OUT
+select next value for t1;
+select * from t1;
+alter sequence t1 restart;
+select next value for t1;
+alter sequence t1 restart with 90;
+select next value for t1;
+drop sequence t1;
diff --git a/mysql-test/suite/sql_sequence/create.result b/mysql-test/suite/sql_sequence/create.result
index 59dfe62acee..4962752c7d9 100644
--- a/mysql-test/suite/sql_sequence/create.result
+++ b/mysql-test/suite/sql_sequence/create.result
@@ -186,6 +186,8 @@ create sequence t1 start with 10 maxvalue=9223372036854775807;
ERROR HY000: Sequence 'test.t1' values are conflicting
create sequence t1 start with 10 minvalue=-9223372036854775808;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '9223372036854775808' at line 1
+create sequence t1 RESTART WITH 10;
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'RESTART' at line 1
create or replace sequence t1 start with 10 NO MINVALUE minvalue=1;
drop sequence t1;
create sequence t1;
diff --git a/mysql-test/suite/sql_sequence/create.test b/mysql-test/suite/sql_sequence/create.test
index 6cb6dedd91b..cf094c2cedd 100644
--- a/mysql-test/suite/sql_sequence/create.test
+++ b/mysql-test/suite/sql_sequence/create.test
@@ -118,6 +118,8 @@ create or replace sequence t1 start with 10 min_value=1 NO MINVALUE;
create sequence t1 start with 10 maxvalue=9223372036854775807;
--error ER_PARSE_ERROR
create sequence t1 start with 10 minvalue=-9223372036854775808;
+--error ER_PARSE_ERROR
+create sequence t1 RESTART WITH 10;
# This should probably give an error
create or replace sequence t1 start with 10 NO MINVALUE minvalue=1;
diff --git a/mysql-test/suite/sql_sequence/next.result b/mysql-test/suite/sql_sequence/next.result
index fc28152a2b7..84f91bc0bdd 100644
--- a/mysql-test/suite/sql_sequence/next.result
+++ b/mysql-test/suite/sql_sequence/next.result
@@ -390,6 +390,16 @@ next_value min_value max_value start increment cache cycle round
select next value for s1;
next value for s1
3984356
+explain extended select next value for s1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select nextval(`test`.`s1`) AS `next value for s1`
+explain extended select previous value for s1;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select lastval(`test`.`s1`) AS `previous value for s1`
drop sequence s1;
create table t1 (a int);
select next value for t1;
diff --git a/mysql-test/suite/sql_sequence/next.test b/mysql-test/suite/sql_sequence/next.test
index 426ee5709a1..472feafb2c6 100644
--- a/mysql-test/suite/sql_sequence/next.test
+++ b/mysql-test/suite/sql_sequence/next.test
@@ -182,9 +182,10 @@ drop table t1,s1;
CREATE OR REPLACE SEQUENCE s1 MINVALUE 1 MAXVALUE 9999999999 INCREMENT BY 1 START WITH 3984356 nocache CYCLE engine='innodb';
select * from s1;
select next value for s1;
+explain extended select next value for s1;
+explain extended select previous value for s1;
drop sequence s1;
-
#
# Some error testing
#
diff --git a/mysql-test/suite/sql_sequence/other.result b/mysql-test/suite/sql_sequence/other.result
new file mode 100644
index 00000000000..b9510d46de7
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/other.result
@@ -0,0 +1,42 @@
+#
+# Create and check
+#
+create sequence s1 engine=innodb;
+check table s1;
+Table Op Msg_type Msg_text
+test.s1 check note The storage engine for the table doesn't support check
+select next value for s1;
+next value for s1
+1
+flush tables;
+check table s1;
+Table Op Msg_type Msg_text
+test.s1 check note The storage engine for the table doesn't support check
+select next value for s1;
+next value for s1
+1001
+flush tables;
+repair table s1;
+Table Op Msg_type Msg_text
+test.s1 repair note The storage engine for the table doesn't support repair
+select next value for s1;
+next value for s1
+2001
+drop sequence s1;
+create or replace sequence s1 engine=innodb;
+select next value for s1;
+next value for s1
+1
+repair table s1;
+Table Op Msg_type Msg_text
+test.s1 repair note The storage engine for the table doesn't support repair
+check table s1;
+Table Op Msg_type Msg_text
+test.s1 check note The storage engine for the table doesn't support check
+select next value for s1;
+next value for s1
+1001
+select * from s1;
+next_value min_value max_value start increment cache cycle round
+2001 1 9223372036854775806 1 1 1000 0 0
+drop sequence s1;
diff --git a/mysql-test/suite/sql_sequence/other.test b/mysql-test/suite/sql_sequence/other.test
new file mode 100644
index 00000000000..c9ed326004a
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/other.test
@@ -0,0 +1,29 @@
+--source include/have_sequence.inc
+--source include/have_innodb.inc
+
+#
+# Test various combinations of operations on sequence
+#
+
+--echo #
+--echo # Create and check
+--echo #
+
+create sequence s1 engine=innodb;
+check table s1;
+select next value for s1;
+flush tables;
+check table s1;
+select next value for s1;
+flush tables;
+repair table s1;
+select next value for s1;
+drop sequence s1;
+
+create or replace sequence s1 engine=innodb;
+select next value for s1;
+repair table s1;
+check table s1;
+select next value for s1;
+select * from s1;
+drop sequence s1;
diff --git a/mysql-test/suite/sql_sequence/read_only.test b/mysql-test/suite/sql_sequence/read_only.test
index d8743617ad2..04dab2bb525 100644
--- a/mysql-test/suite/sql_sequence/read_only.test
+++ b/mysql-test/suite/sql_sequence/read_only.test
@@ -1,4 +1,5 @@
--source include/have_innodb.inc
+--source include/not_embedded.inc
#
# Test innodb read only
diff --git a/mysql-test/suite/sql_sequence/setval.result b/mysql-test/suite/sql_sequence/setval.result
new file mode 100644
index 00000000000..2fe46ff90c2
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/setval.result
@@ -0,0 +1,246 @@
+drop table if exists t1;
+Warnings:
+Note 1051 Unknown table 'test.t1'
+#
+# Test setval function
+#
+CREATE SEQUENCE t1 cache 10 engine=myisam;
+select next_value,round from t1;
+next_value round
+1 0
+do setval(t1,10);
+select next_value,round from t1;
+next_value round
+11 0
+select next value for t1;
+next value for t1
+11
+do setval(t1,12,1);
+select next_value,round from t1;
+next_value round
+21 0
+select next value for t1;
+next value for t1
+13
+do setval(t1,15,0);
+select next_value,round from t1;
+next_value round
+21 0
+select next value for t1;
+next value for t1
+15
+select setval(t1,16,0);
+setval(t1,16,0)
+16
+select next value for t1;
+next value for t1
+16
+do setval(t1,1000,0);
+select next value for t1;
+next value for t1
+1000
+select next_value,round from t1;
+next_value round
+1010 0
+do setval(t1,2000,0);
+select next value for t1;
+next value for t1
+2000
+select next_value,round from t1;
+next_value round
+2010 0
+select setval(t1,1000,0);
+setval(t1,1000,0)
+NULL
+select next value for t1;
+next value for t1
+2001
+select setval(t1,1000,TRUE);
+setval(t1,1000,TRUE)
+NULL
+select next value for t1;
+next value for t1
+2002
+select next_value,round from t1;
+next_value round
+2010 0
+select setval(t1,2002,0);
+setval(t1,2002,0)
+NULL
+select next value for t1;
+next value for t1
+2003
+select setval(t1,2010,0);
+setval(t1,2010,0)
+2010
+select next value for t1;
+next value for t1
+2010
+select next_value,round from t1;
+next_value round
+2020 0
+drop sequence t1;
+#
+# Testing with cycle
+#
+CREATE SEQUENCE t1 cache=10 maxvalue=100 cycle engine=innodb;
+select next_value,round from t1;
+next_value round
+1 0
+select setval(t1,100,0);
+setval(t1,100,0)
+100
+select next_value,round from t1;
+next_value round
+100 0
+select next value for t1;
+next value for t1
+100
+select next_value,round from t1;
+next_value round
+101 0
+select setval(t1,100,0);
+setval(t1,100,0)
+NULL
+select next_value,round from t1;
+next_value round
+101 0
+select next value for t1;
+next value for t1
+1
+select next_value,round from t1;
+next_value round
+11 1
+select next value for t1;
+next value for t1
+2
+select setval(t1,100,0,1);
+setval(t1,100,0,1)
+100
+select next_value,round from t1;
+next_value round
+100 1
+select next value for t1;
+next value for t1
+100
+select setval(t1,100,1,2);
+setval(t1,100,1,2)
+100
+select next_value,round from t1;
+next_value round
+101 2
+select next value for t1;
+next value for t1
+1
+select setval(t1,100,0,3);
+setval(t1,100,0,3)
+100
+select next_value,round from t1;
+next_value round
+100 3
+select next value for t1;
+next value for t1
+100
+drop sequence t1;
+#
+# Testing extreme values
+#
+CREATE SEQUENCE t1 cache=10 maxvalue=100 engine=innodb;
+select next_value,round from t1;
+next_value round
+1 0
+select setval(t1,200);
+setval(t1,200)
+200
+select next_value,round from t1;
+next_value round
+101 0
+select next value for t1;
+ERROR HY000: Sequence 'test.t1' has run out
+drop sequence t1;
+CREATE SEQUENCE t1 cache=10 maxvalue=100 cycle engine=innodb;
+select next_value,round from t1;
+next_value round
+1 0
+select setval(t1,200);
+setval(t1,200)
+200
+select next_value,round from t1;
+next_value round
+101 0
+select next value for t1;
+next value for t1
+1
+drop sequence t1;
+CREATE SEQUENCE t1 cache=10 maxvalue=0 increment=-10;
+select setval(t1,-10);
+setval(t1,-10)
+-10
+select next_value,round from t1;
+next_value round
+-20 0
+select next value for t1;
+next value for t1
+-20
+select setval(t1,-15);
+setval(t1,-15)
+NULL
+select next_value,round from t1;
+next_value round
+-120 0
+select next value for t1;
+next value for t1
+-30
+select setval(t1,-500,FALSE);
+setval(t1,-500,FALSE)
+-500
+select next value for t1;
+next value for t1
+-500
+select next value for t1;
+next value for t1
+-510
+select setval(t1,-525,0);
+setval(t1,-525,0)
+-525
+select next value for t1;
+next value for t1
+-525
+select next value for t1;
+next value for t1
+-535
+drop sequence t1;
+CREATE SEQUENCE t1 cache=10 maxvalue=0 increment=-10;
+select setval(t1,-10,0);
+setval(t1,-10,0)
+-10
+select next_value,round from t1;
+next_value round
+-10 0
+select next value for t1;
+next value for t1
+-10
+drop sequence t1;
+#
+# Other testing
+#
+CREATE SEQUENCE t1;
+select setval(t1,10,0),setval(t1,15,1),setval(t1,5,1);
+setval(t1,10,0) setval(t1,15,1) setval(t1,5,1)
+10 15 NULL
+select next value for t1;
+next value for t1
+16
+select next_value,round from t1;
+next_value round
+1016 0
+explain extended select setval(t1,100),setval(t1,100,TRUE),setval(t1,100,FALSE,50);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select setval(`test`.`t1`,100,1,0) AS `setval(t1,100)`,setval(`test`.`t1`,100,1,0) AS `setval(t1,100,TRUE)`,setval(`test`.`t1`,100,0,50) AS `setval(t1,100,FALSE,50)`
+drop sequence t1;
+create table t1 (a int);
+select setval(t1,10);
+ERROR 42S02: 'test.t1' is not a SEQUENCE
+drop table t1;
diff --git a/mysql-test/suite/sql_sequence/setval.test b/mysql-test/suite/sql_sequence/setval.test
new file mode 100644
index 00000000000..fe0c0669494
--- /dev/null
+++ b/mysql-test/suite/sql_sequence/setval.test
@@ -0,0 +1,126 @@
+--source include/have_sequence.inc
+--source include/have_innodb.inc
+
+drop table if exists t1;
+
+--echo #
+--echo # Test setval function
+--echo #
+
+CREATE SEQUENCE t1 cache 10 engine=myisam;
+select next_value,round from t1;
+do setval(t1,10);
+select next_value,round from t1;
+select next value for t1;
+do setval(t1,12,1);
+select next_value,round from t1;
+select next value for t1;
+do setval(t1,15,0);
+select next_value,round from t1;
+select next value for t1;
+select setval(t1,16,0);
+select next value for t1;
+do setval(t1,1000,0);
+select next value for t1;
+select next_value,round from t1;
+do setval(t1,2000,0);
+select next value for t1;
+select next_value,round from t1;
+# Set smaller value
+select setval(t1,1000,0);
+select next value for t1;
+select setval(t1,1000,TRUE);
+select next value for t1;
+select next_value,round from t1;
+select setval(t1,2002,0);
+select next value for t1;
+select setval(t1,2010,0);
+select next value for t1;
+select next_value,round from t1;
+drop sequence t1;
+
+--echo #
+--echo # Testing with cycle
+--echo #
+
+CREATE SEQUENCE t1 cache=10 maxvalue=100 cycle engine=innodb;
+select next_value,round from t1;
+select setval(t1,100,0);
+select next_value,round from t1;
+select next value for t1;
+select next_value,round from t1;
+select setval(t1,100,0);
+select next_value,round from t1;
+select next value for t1;
+select next_value,round from t1;
+select next value for t1;
+select setval(t1,100,0,1);
+select next_value,round from t1;
+select next value for t1;
+select setval(t1,100,1,2);
+select next_value,round from t1;
+select next value for t1;
+select setval(t1,100,0,3);
+select next_value,round from t1;
+select next value for t1;
+drop sequence t1;
+
+--echo #
+--echo # Testing extreme values
+--echo #
+
+CREATE SEQUENCE t1 cache=10 maxvalue=100 engine=innodb;
+select next_value,round from t1;
+select setval(t1,200);
+select next_value,round from t1;
+--error ER_SEQUENCE_RUN_OUT
+select next value for t1;
+drop sequence t1;
+
+CREATE SEQUENCE t1 cache=10 maxvalue=100 cycle engine=innodb;
+select next_value,round from t1;
+select setval(t1,200);
+select next_value,round from t1;
+select next value for t1;
+drop sequence t1;
+
+CREATE SEQUENCE t1 cache=10 maxvalue=0 increment=-10;
+select setval(t1,-10);
+select next_value,round from t1;
+select next value for t1;
+select setval(t1,-15);
+select next_value,round from t1;
+select next value for t1;
+select setval(t1,-500,FALSE);
+select next value for t1;
+select next value for t1;
+select setval(t1,-525,0);
+select next value for t1;
+select next value for t1;
+drop sequence t1;
+
+CREATE SEQUENCE t1 cache=10 maxvalue=0 increment=-10;
+select setval(t1,-10,0);
+select next_value,round from t1;
+select next value for t1;
+drop sequence t1;
+
+--echo #
+--echo # Other testing
+--echo #
+
+CREATE SEQUENCE t1;
+select setval(t1,10,0),setval(t1,15,1),setval(t1,5,1);
+select next value for t1;
+select next_value,round from t1;
+explain extended select setval(t1,100),setval(t1,100,TRUE),setval(t1,100,FALSE,50);
+drop sequence t1;
+
+#
+# Some error testing
+#
+
+create table t1 (a int);
+--error ER_NOT_SEQUENCE
+select setval(t1,10);
+drop table t1;
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
index 459e0126fea..7ceea1a295c 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result
@@ -2909,9 +2909,9 @@ READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES
SESSION_VALUE NULL
-GLOBAL_VALUE 189
+GLOBAL_VALUE 190
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE 189
+DEFAULT_VALUE 190
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Maximum number of statement instruments.
diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
index 48514eea424..957485b4e4b 100644
--- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
+++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result
@@ -3105,9 +3105,9 @@ READ_ONLY YES
COMMAND_LINE_ARGUMENT REQUIRED
VARIABLE_NAME PERFORMANCE_SCHEMA_MAX_STATEMENT_CLASSES
SESSION_VALUE NULL
-GLOBAL_VALUE 189
+GLOBAL_VALUE 190
GLOBAL_VALUE_ORIGIN COMPILE-TIME
-DEFAULT_VALUE 189
+DEFAULT_VALUE 190
VARIABLE_SCOPE GLOBAL
VARIABLE_TYPE BIGINT UNSIGNED
VARIABLE_COMMENT Maximum number of statement instruments.
diff --git a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result
index 9413dbdace7..dd767071dc9 100644
--- a/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result
+++ b/mysql-test/suite/vcol/r/vcol_supported_sql_funcs.result
@@ -915,7 +915,7 @@ Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
`b` varchar(10) DEFAULT NULL,
- `c` varchar(20) GENERATED ALWAYS AS (insert(`a`,length(`a`),length(`b`),`b`)) VIRTUAL
+ `c` varchar(20) GENERATED ALWAYS AS (insert(`a`,octet_length(`a`),octet_length(`b`),`b`)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('start,','end',default);
select * from t1;
@@ -978,7 +978,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) GENERATED ALWAYS AS (length(`a`)) VIRTUAL
+ `b` int(11) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('text',default);
select * from t1;
@@ -1142,7 +1142,7 @@ show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` varchar(10) DEFAULT NULL,
- `b` int(11) GENERATED ALWAYS AS (length(`a`)) VIRTUAL
+ `b` int(11) GENERATED ALWAYS AS (octet_length(`a`)) VIRTUAL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
insert into t1 values ('text',default);
select * from t1;
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index bb3251b3e31..29a9510db00 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1853,6 +1853,16 @@ SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64(
SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64("Yq==") OR f2= from_base64("YQ=="));
DROP TABLE t1;
+--echo #
+--echo # MDEV-12685 Oracle-compatible function CHR()
+--echo #
+select chr(65);
+create database mysqltest1 CHARACTER SET = 'utf8' COLLATE = 'utf8_bin';
+use mysqltest1;
+select charset(chr(65)), length(chr(65)),char_length(chr(65));
+select charset(chr(14844588)), length(chr(14844588)),char_length(chr(14844588));
+drop database mysqltest1;
+use test;
--echo #
--echo # End of 10.1 tests
diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test
index 34797337b1d..ab9c792d523 100644
--- a/mysql-test/t/gis.test
+++ b/mysql-test/t/gis.test
@@ -2294,5 +2294,18 @@ CALL p1('geometrycollection');
DROP PROCEDURE p1;
--echo #
+--echo # MDEV-12798 Item_param does not preserve exact field type in EXECUTE IMMEDIATE 'CREATE TABLE AS SELECT ?' USING POINT(1,1)
+--echo #
+EXECUTE IMMEDIATE 'CREATE TABLE t1 AS SELECT ?' USING POINT(1,1);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+PREPARE stmt FROM 'CREATE OR REPLACE TABLE t1 AS SELECT ?';
+EXECUTE stmt USING POINT(1,1);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test
index 04ab71588be..ce8b2bc9c2a 100644
--- a/mysql-test/t/union.test
+++ b/mysql-test/t/union.test
@@ -1545,5 +1545,132 @@ SHOW CREATE TABLE t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-9495 Wrong field type for a UNION of a signed and an unsigned INT expression
+--echo #
+CREATE TABLE t1 (a INT, b INT UNSIGNED);
+INSERT INTO t1 VALUES (0x7FFFFFFF,0xFFFFFFFF);
+CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;
+SHOW CREATE TABLE t2;
+SELECT * FROM t2 ORDER BY a;
+DROP TABLE t2;
+CREATE TABLE t2 AS SELECT COALESCE(a,b), COALESCE(b,a) FROM t1;
+SHOW CREATE TABLE t2;
+SELECT * FROM t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-9497 UNION and COALESCE produce different field types for DECIMAL+INT
+--echo #
+CREATE TABLE t1 AS SELECT COALESCE(10.1,CAST(10 AS UNSIGNED)) AS a;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+CREATE OR REPLACE TABLE t1 AS SELECT 10.1 AS a UNION SELECT CAST(10 AS UNSIGNED);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo #
+--echo # MDEV-12594 UNION between fixed length double columns does not always preserve scale
+--echo #
+CREATE TABLE t1 (a FLOAT(20,4), b FLOAT(20,3), c FLOAT(20,4));
+INSERT INTO t1 VALUES (1111,2222,3333);
+
+CREATE TABLE t2 AS SELECT a FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+CREATE OR REPLACE TABLE t2 SELECT a FROM t1 UNION SELECT c FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+CREATE OR REPLACE TABLE t2 SELECT b FROM t1 UNION SELECT b FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+CREATE OR REPLACE TABLE t2 SELECT c FROM t1 UNION SELECT c FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+CREATE OR REPLACE TABLE t2 SELECT c FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+CREATE OR REPLACE TABLE t2 AS SELECT a FROM t1 UNION SELECT b FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+CREATE OR REPLACE TABLE t2 AS SELECT b FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+
+DROP TABLE t1;
+
+--echo # Corner case
+CREATE TABLE t1 (a FLOAT(255,4), b FLOAT(255,3));
+INSERT INTO t1 VALUES (1111,2222);
+CREATE OR REPLACE TABLE t2 AS SELECT b FROM t1 UNION SELECT a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-12595 UNION converts INT to BIGINT
+--echo #
+CREATE TABLE t1 AS SELECT
+ 1,
+ -1,
+ COALESCE(1,1),
+ COALESCE(-1,-1),
+ COALESCE(1,-1),
+ COALESCE(-1,1);
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+CREATE TABLE t1 AS SELECT 1 AS c1,1 AS c2,-1 AS c3,-1 AS c4 UNION SELECT 1,-1,1,-1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+--echo #
+--echo # MDEV-12599 UNION is not symmetric when mixing INT and CHAR
+--echo #
+
+CREATE OR REPLACE TABLE t1 AS SELECT 1 AS c1, 'a' AS c2 UNION SELECT 'a', 1;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE OR REPLACE TABLE t1 AS SELECT 11112222 AS c1, 'a' AS c2 UNION SELECT 'a', 11112222;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+
+CREATE OR REPLACE TABLE t1 AS SELECT 111122223333 AS c1, 'a' AS c2 UNION SELECT 'a', 111122223333;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE OR REPLACE TABLE t1 AS SELECT 1111222233334444 AS c1, 'a' AS c2 UNION SELECT 'a', 1111222233334444;
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a INT(3), b VARCHAR(1));
+CREATE TABLE t2 AS SELECT a,b FROM t1 UNION SELECT b,a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a BIGINT(3), b VARCHAR(1));
+CREATE TABLE t2 AS SELECT a,b FROM t1 UNION SELECT b,a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+CREATE TABLE t1 (a BIGINT(12), b VARCHAR(1));
+CREATE TABLE t2 AS SELECT a,b FROM t1 UNION SELECT b,a FROM t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+DROP TABLE t1;
+
+
+--echo #
--echo # End of 10.3 tests
--echo #
diff --git a/sql/field.cc b/sql/field.cc
index b0345788bf3..577b09e948d 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -53,15 +53,6 @@
static const char *zero_timestamp="0000-00-00 00:00:00.000000";
LEX_CSTRING temp_lex_str= {"temp", 4};
-/* number of bytes to store second_part part of the TIMESTAMP(N) */
-static uint sec_part_bytes[MAX_DATETIME_PRECISION+1]= { 0, 1, 1, 2, 2, 3, 3 };
-
-/* number of bytes to store DATETIME(N) */
-static uint datetime_hires_bytes[MAX_DATETIME_PRECISION+1]= { 5, 6, 6, 7, 7, 7, 8 };
-
-/* number of bytes to store TIME(N) */
-static uint time_hires_bytes[MAX_DATETIME_PRECISION+1]= { 3, 4, 4, 5, 5, 5, 6 };
-
uchar Field_null::null[1]={1};
const char field_separator=',';
@@ -5226,14 +5217,14 @@ static longlong read_bigendian(const uchar *from, uint bytes)
void Field_timestamp_hires::store_TIME(my_time_t timestamp, ulong sec_part)
{
mi_int4store(ptr, timestamp);
- store_bigendian(sec_part_shift(sec_part, dec), ptr+4, sec_part_bytes[dec]);
+ store_bigendian(sec_part_shift(sec_part, dec), ptr+4, sec_part_bytes(dec));
}
my_time_t Field_timestamp_hires::get_timestamp(const uchar *pos,
ulong *sec_part) const
{
ASSERT_COLUMN_MARKED_FOR_READ;
- *sec_part= (long)sec_part_unshift(read_bigendian(pos+4, sec_part_bytes[dec]), dec);
+ *sec_part= (long)sec_part_unshift(read_bigendian(pos+4, sec_part_bytes(dec)), dec);
return mi_uint4korr(pos);
}
@@ -5300,19 +5291,14 @@ int Field_timestamp_hires::cmp(const uchar *a_ptr, const uchar *b_ptr)
int32 a,b;
ulong a_sec_part, b_sec_part;
a= mi_uint4korr(a_ptr);
- a_sec_part= (ulong)read_bigendian(a_ptr+4, sec_part_bytes[dec]);
+ a_sec_part= (ulong)read_bigendian(a_ptr+4, sec_part_bytes(dec));
b= mi_uint4korr(b_ptr);
- b_sec_part= (ulong)read_bigendian(b_ptr+4, sec_part_bytes[dec]);
+ b_sec_part= (ulong)read_bigendian(b_ptr+4, sec_part_bytes(dec));
return ((uint32) a < (uint32) b) ? -1 : ((uint32) a > (uint32) b) ? 1 :
a_sec_part < b_sec_part ? -1 : a_sec_part > b_sec_part ? 1 : 0;
}
-uint32 Field_timestamp_hires::pack_length() const
-{
- return 4 + sec_part_bytes[dec];
-}
-
void Field_timestamp_with_dec::make_field(Send_field *field)
{
Field::make_field(field);
@@ -5951,11 +5937,6 @@ Item *Field_time::get_equal_const_item(THD *thd, const Context &ctx,
}
-uint32 Field_time_hires::pack_length() const
-{
- return time_hires_bytes[dec];
-}
-
longlong Field_time_with_dec::val_int(void)
{
ASSERT_COLUMN_MARKED_FOR_READ;
@@ -6658,11 +6639,6 @@ bool Field_datetime_hires::get_TIME(MYSQL_TIME *ltime, const uchar *pos,
}
-uint32 Field_datetime_hires::pack_length() const
-{
- return datetime_hires_bytes[dec];
-}
-
int Field_datetime_hires::cmp(const uchar *a_ptr, const uchar *b_ptr)
{
ulonglong a=read_bigendian(a_ptr, Field_datetime_hires::pack_length());
@@ -9787,7 +9763,7 @@ void Column_definition::set_attributes(const Lex_field_type_st &type,
DBUG_ASSERT(length == 0);
DBUG_ASSERT(decimals == 0);
- set_handler_by_real_type(type.field_type());
+ set_handler(type.type_handler());
charset= cs;
if (type.length())
@@ -9803,6 +9779,32 @@ void Column_definition::set_attributes(const Lex_field_type_st &type,
}
+void Column_definition::create_length_to_internal_length_bit()
+{
+ if (f_bit_as_char(pack_flag))
+ {
+ key_length= pack_length= ((length + 7) & ~7) / 8;
+ }
+ else
+ {
+ pack_length= length / 8;
+ /* We need one extra byte to store the bits we save among the null bits */
+ key_length= pack_length + MY_TEST(length & 7);
+ }
+}
+
+
+void Column_definition::create_length_to_internal_length_newdecimal()
+{
+ key_length= pack_length=
+ my_decimal_get_binary_size(my_decimal_length_to_precision(length,
+ decimals,
+ flags &
+ UNSIGNED_FLAG),
+ decimals);
+}
+
+
/**
Convert create_field::length from number of characters to number of bytes.
*/
@@ -9818,38 +9820,41 @@ void Column_definition::create_length_to_internal_length(void)
case MYSQL_TYPE_VAR_STRING:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VARCHAR:
- length*= charset->mbmaxlen;
- key_length= length;
- pack_length= calc_pack_length(real_field_type(), length);
+ create_length_to_internal_length_string();
break;
case MYSQL_TYPE_ENUM:
case MYSQL_TYPE_SET:
- /* Pack_length already calculated in sql_parse.cc */
- length*= charset->mbmaxlen;
- key_length= pack_length;
+ create_length_to_internal_length_typelib();
break;
case MYSQL_TYPE_BIT:
- if (f_bit_as_char(pack_flag))
- {
- key_length= pack_length= ((length + 7) & ~7) / 8;
- }
- else
- {
- pack_length= length / 8;
- /* We need one extra byte to store the bits we save among the null bits */
- key_length= pack_length + MY_TEST(length & 7);
- }
+ create_length_to_internal_length_bit();
break;
case MYSQL_TYPE_NEWDECIMAL:
- key_length= pack_length=
- my_decimal_get_binary_size(my_decimal_length_to_precision(length,
- decimals,
- flags &
- UNSIGNED_FLAG),
- decimals);
+ create_length_to_internal_length_newdecimal();
break;
- default:
- key_length= pack_length= calc_pack_length(real_field_type(), length);
+
+ case MYSQL_TYPE_NULL:
+ create_length_to_internal_length_null();
+ break;
+
+ case MYSQL_TYPE_DECIMAL:
+ case MYSQL_TYPE_TINY:
+ case MYSQL_TYPE_SHORT:
+ case MYSQL_TYPE_INT24:
+ case MYSQL_TYPE_LONG:
+ case MYSQL_TYPE_LONGLONG:
+ case MYSQL_TYPE_YEAR:
+ case MYSQL_TYPE_FLOAT:
+ case MYSQL_TYPE_DOUBLE:
+ case MYSQL_TYPE_TIME:
+ case MYSQL_TYPE_TIME2:
+ case MYSQL_TYPE_DATE:
+ case MYSQL_TYPE_NEWDATE:
+ case MYSQL_TYPE_DATETIME:
+ case MYSQL_TYPE_DATETIME2:
+ case MYSQL_TYPE_TIMESTAMP:
+ case MYSQL_TYPE_TIMESTAMP2:
+ create_length_to_internal_length_simple();
break;
}
}
@@ -9893,11 +9898,98 @@ bool check_expression(Virtual_column_info *vcol, LEX_CSTRING *name,
}
+bool Column_definition::check_length(uint mysql_errno, uint limit) const
+{
+ if (length <= limit)
+ return false;
+ my_error(mysql_errno, MYF(0), field_name.str, static_cast<ulong>(limit));
+ return true;
+}
+
+
+bool Column_definition::fix_attributes_int(uint default_length)
+{
+ if (length)
+ return check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_FIELD_CHARLENGTH);
+ length= default_length;
+ return false;
+}
+
+
+bool Column_definition::fix_attributes_real(uint default_length)
+{
+ /* change FLOAT(precision) to FLOAT or DOUBLE */
+ if (!length && !decimals)
+ {
+ length= default_length;
+ decimals= NOT_FIXED_DEC;
+ }
+ if (length < decimals && decimals != NOT_FIXED_DEC)
+ {
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str);
+ return true;
+ }
+ if (decimals != NOT_FIXED_DEC && decimals >= FLOATING_POINT_DECIMALS)
+ {
+ my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
+ field_name.str, static_cast<uint>(FLOATING_POINT_DECIMALS-1));
+ return true;
+ }
+ return check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_FIELD_CHARLENGTH);
+}
+
+
+bool Column_definition::fix_attributes_decimal()
+{
+ if (decimals >= NOT_FIXED_DEC)
+ {
+ my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
+ field_name.str, static_cast<uint>(NOT_FIXED_DEC - 1));
+ return true;
+ }
+ my_decimal_trim(&length, &decimals);
+ if (length > DECIMAL_MAX_PRECISION)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str,
+ DECIMAL_MAX_PRECISION);
+ return true;
+ }
+ if (length < decimals)
+ {
+ my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str);
+ return true;
+ }
+ length= my_decimal_precision_to_length(length, decimals,
+ flags & UNSIGNED_FLAG);
+ pack_length= my_decimal_get_binary_size(length, decimals);
+ return false;
+}
+
+
+bool Column_definition::fix_attributes_bit()
+{
+ if (!length)
+ length= 1;
+ pack_length= (length + 7) / 8;
+ return check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_BIT_FIELD_LENGTH);
+}
+
+
+bool Column_definition::fix_attributes_temporal_with_time(uint int_part_length)
+{
+ if (length > MAX_DATETIME_PRECISION)
+ {
+ my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str,
+ MAX_DATETIME_PRECISION);
+ return true;
+ }
+ length+= int_part_length + (length ? 1 : 0);
+ return false;
+}
+
+
bool Column_definition::check(THD *thd)
{
- const uint conditional_type_modifiers= AUTO_INCREMENT_FLAG;
- uint sign_len, allowed_type_modifier= 0;
- ulong max_field_charlength= MAX_FIELD_CHARLENGTH;
DBUG_ENTER("Column_definition::check");
/* Initialize data for a computed field */
@@ -9972,186 +10064,9 @@ bool Column_definition::check(THD *thd)
else if (flags & AUTO_INCREMENT_FLAG)
unireg_check= Field::NEXT_NUMBER;
- sign_len= flags & UNSIGNED_FLAG ? 0 : 1;
+ if (type_handler()->Column_definition_fix_attributes(this))
+ DBUG_RETURN(true);
- switch (real_field_type()) {
- case MYSQL_TYPE_TINY:
- if (!length)
- length= MAX_TINYINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case MYSQL_TYPE_SHORT:
- if (!length)
- length= MAX_SMALLINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case MYSQL_TYPE_INT24:
- if (!length)
- length= MAX_MEDIUMINT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case MYSQL_TYPE_LONG:
- if (!length)
- length= MAX_INT_WIDTH+sign_len;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case MYSQL_TYPE_LONGLONG:
- if (!length)
- length= MAX_BIGINT_WIDTH;
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- break;
- case MYSQL_TYPE_NULL:
- break;
- case MYSQL_TYPE_NEWDECIMAL:
- if (decimals >= NOT_FIXED_DEC)
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
- field_name.str, static_cast<uint>(NOT_FIXED_DEC - 1));
- DBUG_RETURN(TRUE);
- }
- my_decimal_trim(&length, &decimals);
- if (length > DECIMAL_MAX_PRECISION)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str,
- DECIMAL_MAX_PRECISION);
- DBUG_RETURN(TRUE);
- }
- if (length < decimals)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str);
- DBUG_RETURN(TRUE);
- }
- length=
- my_decimal_precision_to_length(length, decimals, flags & UNSIGNED_FLAG);
- pack_length=
- my_decimal_get_binary_size(length, decimals);
- break;
- case MYSQL_TYPE_VARCHAR:
- /*
- Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
- if they don't have a default value
- */
- max_field_charlength= MAX_FIELD_VARCHARLENGTH;
- break;
- case MYSQL_TYPE_STRING:
- break;
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_GEOMETRY:
- flags|= BLOB_FLAG;
- break;
- case MYSQL_TYPE_YEAR:
- if (!length || length != 2)
- length= 4; /* Default length */
- flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
- break;
- case MYSQL_TYPE_FLOAT:
- /* change FLOAT(precision) to FLOAT or DOUBLE */
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (!length && !decimals)
- {
- length= MAX_FLOAT_STR_LENGTH;
- decimals= NOT_FIXED_DEC;
- }
- if (length < decimals &&
- decimals != NOT_FIXED_DEC)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str);
- DBUG_RETURN(TRUE);
- }
- if (decimals != NOT_FIXED_DEC && decimals >= FLOATING_POINT_DECIMALS)
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
- field_name.str, static_cast<uint>(FLOATING_POINT_DECIMALS-1));
- DBUG_RETURN(TRUE);
- }
- break;
- case MYSQL_TYPE_DOUBLE:
- allowed_type_modifier= AUTO_INCREMENT_FLAG;
- if (!length && !decimals)
- {
- length= DBL_DIG+7;
- decimals= NOT_FIXED_DEC;
- }
- if (length < decimals &&
- decimals != NOT_FIXED_DEC)
- {
- my_error(ER_M_BIGGER_THAN_D, MYF(0), field_name.str);
- DBUG_RETURN(TRUE);
- }
- if (decimals != NOT_FIXED_DEC && decimals >= FLOATING_POINT_DECIMALS)
- {
- my_error(ER_TOO_BIG_SCALE, MYF(0), static_cast<ulonglong>(decimals),
- field_name.str, static_cast<uint>(FLOATING_POINT_DECIMALS-1));
- DBUG_RETURN(TRUE);
- }
- break;
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_TIMESTAMP2:
- if (length > MAX_DATETIME_PRECISION)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str,
- MAX_DATETIME_PRECISION);
- DBUG_RETURN(TRUE);
- }
- length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
- flags|= UNSIGNED_FLAG;
- break;
- case MYSQL_TYPE_DATE:
- /* We don't support creation of MYSQL_TYPE_DATE anymore */
- set_handler(&type_handler_newdate);
- /* fall trough */
- case MYSQL_TYPE_NEWDATE:
- length= MAX_DATE_WIDTH;
- break;
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_TIME2:
- if (length > MAX_DATETIME_PRECISION)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str,
- MAX_DATETIME_PRECISION);
- DBUG_RETURN(TRUE);
- }
- length+= MIN_TIME_WIDTH + (length ? 1 : 0);
- break;
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_DATETIME2:
- if (length > MAX_DATETIME_PRECISION)
- {
- my_error(ER_TOO_BIG_PRECISION, MYF(0), length, field_name.str,
- MAX_DATETIME_PRECISION);
- DBUG_RETURN(TRUE);
- }
- length+= MAX_DATETIME_WIDTH + (length ? 1 : 0);
- break;
- case MYSQL_TYPE_SET:
- pack_length= get_set_pack_length(interval_list.elements);
- break;
- case MYSQL_TYPE_ENUM:
- /* Should be safe. */
- pack_length= get_enum_pack_length(interval_list.elements);
- break;
- case MYSQL_TYPE_VAR_STRING:
- DBUG_ASSERT(0); /* Impossible. */
- break;
- case MYSQL_TYPE_BIT:
- {
- if (!length)
- length= 1;
- if (length > MAX_BIT_FIELD_LENGTH)
- {
- my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name.str,
- static_cast<ulong>(MAX_BIT_FIELD_LENGTH));
- DBUG_RETURN(TRUE);
- }
- pack_length= (length + 7) / 8;
- break;
- }
- case MYSQL_TYPE_DECIMAL:
- DBUG_ASSERT(0); /* Was obsolete */
- }
/* Remember the value of length */
char_length= length;
@@ -10174,32 +10089,9 @@ bool Column_definition::check(THD *thd)
}
}
- enum_field_types sql_type= real_field_type();
- if (!(flags & BLOB_FLAG) &&
- ((length > max_field_charlength &&
- sql_type != MYSQL_TYPE_VARCHAR) ||
- (length == 0 &&
- sql_type != MYSQL_TYPE_NULL /* e.g. a ROW variable */ &&
- sql_type != MYSQL_TYPE_ENUM && sql_type != MYSQL_TYPE_SET &&
- sql_type != MYSQL_TYPE_STRING && sql_type != MYSQL_TYPE_VARCHAR &&
- sql_type != MYSQL_TYPE_GEOMETRY)))
- {
- my_error((sql_type == MYSQL_TYPE_VAR_STRING ||
- sql_type == MYSQL_TYPE_VARCHAR ||
- sql_type == MYSQL_TYPE_STRING) ? ER_TOO_BIG_FIELDLENGTH :
- ER_TOO_BIG_DISPLAYWIDTH,
- MYF(0),
- field_name.str, max_field_charlength); /* purecov: inspected */
- DBUG_RETURN(TRUE);
- }
- else if (length > MAX_FIELD_BLOBLENGTH)
- {
- my_error(ER_TOO_BIG_DISPLAYWIDTH, MYF(0), field_name.str,
- MAX_FIELD_BLOBLENGTH);
- DBUG_RETURN(1);
- }
- if ((~allowed_type_modifier) & flags & conditional_type_modifiers)
+ if ((flags & AUTO_INCREMENT_FLAG) &&
+ !type_handler()->type_can_have_auto_increment_attribute())
{
my_error(ER_WRONG_FIELD_SPEC, MYF(0), field_name.str);
DBUG_RETURN(TRUE);
@@ -10223,64 +10115,6 @@ enum_field_types get_blob_type_from_length(ulong length)
}
-/*
- Make a field from the .frm file info
-*/
-
-uint32 calc_pack_length(enum_field_types type,uint32 length)
-{
- switch (type) {
- case MYSQL_TYPE_VAR_STRING:
- case MYSQL_TYPE_STRING:
- case MYSQL_TYPE_DECIMAL: return (length);
- case MYSQL_TYPE_VARCHAR: return (length + (length < 256 ? 1: 2));
- case MYSQL_TYPE_YEAR:
- case MYSQL_TYPE_TINY : return 1;
- case MYSQL_TYPE_SHORT : return 2;
- case MYSQL_TYPE_INT24:
- case MYSQL_TYPE_NEWDATE: return 3;
- case MYSQL_TYPE_TIME: return length > MIN_TIME_WIDTH
- ? time_hires_bytes[length - 1 - MIN_TIME_WIDTH]
- : 3;
- case MYSQL_TYPE_TIME2:
- return length > MIN_TIME_WIDTH ?
- my_time_binary_length(length - MIN_TIME_WIDTH - 1) : 3;
- case MYSQL_TYPE_TIMESTAMP:
- return length > MAX_DATETIME_WIDTH
- ? 4 + sec_part_bytes[length - 1 - MAX_DATETIME_WIDTH]
- : 4;
- case MYSQL_TYPE_TIMESTAMP2:
- return length > MAX_DATETIME_WIDTH ?
- my_timestamp_binary_length(length - MAX_DATETIME_WIDTH - 1) : 4;
- case MYSQL_TYPE_DATE:
- case MYSQL_TYPE_LONG : return 4;
- case MYSQL_TYPE_FLOAT : return sizeof(float);
- case MYSQL_TYPE_DOUBLE: return sizeof(double);
- case MYSQL_TYPE_DATETIME:
- return length > MAX_DATETIME_WIDTH
- ? datetime_hires_bytes[length - 1 - MAX_DATETIME_WIDTH]
- : 8;
- case MYSQL_TYPE_DATETIME2:
- return length > MAX_DATETIME_WIDTH ?
- my_datetime_binary_length(length - MAX_DATETIME_WIDTH - 1) : 5;
- case MYSQL_TYPE_LONGLONG: return 8; /* Don't crash if no longlong */
- case MYSQL_TYPE_NULL : return 0;
- case MYSQL_TYPE_TINY_BLOB: return 1+portable_sizeof_char_ptr;
- case MYSQL_TYPE_BLOB: return 2+portable_sizeof_char_ptr;
- case MYSQL_TYPE_MEDIUM_BLOB: return 3+portable_sizeof_char_ptr;
- case MYSQL_TYPE_LONG_BLOB: return 4+portable_sizeof_char_ptr;
- case MYSQL_TYPE_GEOMETRY: return 4+portable_sizeof_char_ptr;
- case MYSQL_TYPE_SET:
- case MYSQL_TYPE_ENUM:
- case MYSQL_TYPE_NEWDECIMAL:
- abort(); return 0; // This shouldn't happen
- case MYSQL_TYPE_BIT: return length / 8;
- default:
- return 0;
- }
-}
-
-
uint pack_length_to_packflag(uint type)
{
switch (type) {
@@ -10361,9 +10195,12 @@ Field *make_field(TABLE_SHARE *share,
return 0; // Error
}
- uint pack_length=calc_pack_length((enum_field_types)
- f_packtype(pack_flag),
- field_length);
+ // MYSQL_TYPE_VAR_STRING is handled above
+ DBUG_ASSERT(f_packtype(pack_flag) != MYSQL_TYPE_VAR_STRING);
+ const Type_handler *tmp;
+ tmp= Type_handler::get_handler_by_real_type((enum_field_types)
+ f_packtype(pack_flag));
+ uint pack_length= tmp->calc_pack_length(field_length);
#ifdef HAVE_SPATIAL
if (f_is_geom(pack_flag))
diff --git a/sql/field.h b/sql/field.h
index cdb80a5973a..10363fd855b 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1289,6 +1289,7 @@ public:
uint fill_cache_field(struct st_cache_field *copy);
virtual bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
bool get_time(MYSQL_TIME *ltime) { return get_date(ltime, TIME_TIME_ONLY); }
+ virtual TYPELIB *get_typelib() const { return NULL; }
virtual CHARSET_INFO *charset(void) const { return &my_charset_bin; }
virtual CHARSET_INFO *charset_for_protocol(void) const
{ return binary() ? &my_charset_bin : charset(); }
@@ -2453,6 +2454,10 @@ public:
class Field_timestamp_hires :public Field_timestamp_with_dec {
+ uint sec_part_bytes(uint dec) const
+ {
+ return Type_handler_timestamp::sec_part_bytes(dec);
+ }
public:
Field_timestamp_hires(uchar *ptr_arg,
uchar *null_ptr_arg, uchar null_bit_arg,
@@ -2467,7 +2472,7 @@ public:
my_time_t get_timestamp(const uchar *pos, ulong *sec_part) const;
void store_TIME(my_time_t timestamp, ulong sec_part);
int cmp(const uchar *,const uchar *);
- uint32 pack_length() const;
+ uint32 pack_length() const { return 4 + sec_part_bytes(dec); }
uint size_of() const { return sizeof(*this); }
};
@@ -2734,7 +2739,7 @@ public:
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
int cmp(const uchar *,const uchar *);
void sort_string(uchar *buff,uint length);
- uint32 pack_length() const;
+ uint32 pack_length() const { return Type_handler_time::hires_bytes(dec); }
uint size_of() const { return sizeof(*this); }
};
@@ -2893,7 +2898,7 @@ public:
DBUG_ASSERT(dec);
}
int cmp(const uchar *,const uchar *);
- uint32 pack_length() const;
+ uint32 pack_length() const { return Type_handler_datetime::hires_bytes(dec); }
bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
{ return Field_datetime_hires::get_TIME(ltime, ptr, fuzzydate); }
uint size_of() const { return sizeof(*this); }
@@ -3547,6 +3552,7 @@ public:
/* enum and set are sorted as integers */
CHARSET_INFO *sort_charset(void) const { return &my_charset_bin; }
uint decimals() const { return 0; }
+ TYPELIB *get_typelib() const { return typelib; }
virtual uchar *pack(uchar *to, const uchar *from, uint max_length);
virtual const uchar *unpack(uchar *to, const uchar *from,
@@ -3829,6 +3835,8 @@ class Column_definition: public Sql_alloc,
set_if_bigger(*max_length, (uint32)length);
}
}
+ bool prepare_stage1_check_typelib_default();
+ bool prepare_stage1_convert_default(THD *, MEM_ROOT *, CHARSET_INFO *to);
const Type_handler *field_type() const; // Prevent using this
public:
LEX_CSTRING field_name;
@@ -3880,6 +3888,29 @@ public:
Column_definition(THD *thd, Field *field, Field *orig_field);
void set_attributes(const Lex_field_type_st &type, CHARSET_INFO *cs);
void create_length_to_internal_length(void);
+ void create_length_to_internal_length_null()
+ {
+ DBUG_ASSERT(length == 0);
+ key_length= pack_length= 0;
+ }
+ void create_length_to_internal_length_simple()
+ {
+ key_length= pack_length= type_handler()->calc_pack_length(length);
+ }
+ void create_length_to_internal_length_string()
+ {
+ length*= charset->mbmaxlen;
+ key_length= length;
+ pack_length= type_handler()->calc_pack_length(length);
+ }
+ void create_length_to_internal_length_typelib()
+ {
+ /* Pack_length already calculated in sql_parse.cc */
+ length*= charset->mbmaxlen;
+ key_length= pack_length;
+ }
+ void create_length_to_internal_length_bit();
+ void create_length_to_internal_length_newdecimal();
/**
Prepare a SET/ENUM field.
@@ -3915,7 +3946,29 @@ public:
bool sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root);
- bool prepare_create_field(uint *blob_columns, ulonglong table_flags);
+ bool prepare_stage1(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+ bool prepare_stage1_typelib(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+ bool prepare_stage1_string(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+ bool prepare_stage1_bit(THD *thd, MEM_ROOT *mem_root,
+ handler *file, ulonglong table_flags);
+
+ bool prepare_stage2(handler *handler, ulonglong table_flags);
+ bool prepare_stage2_blob(handler *handler,
+ ulonglong table_flags, uint field_flags);
+ bool prepare_stage2_varchar(ulonglong table_flags);
+ bool prepare_stage2_typelib(const char *type_name, uint field_flags,
+ uint *dup_val_count);
+ uint pack_flag_numeric(uint dec) const;
+ uint sign_length() const { return flags & UNSIGNED_FLAG ? 0 : 1; }
+ bool check_length(uint mysql_errno, uint max_allowed_length) const;
+ bool fix_attributes_real(uint default_length);
+ bool fix_attributes_int(uint default_length);
+ bool fix_attributes_decimal();
+ bool fix_attributes_temporal_with_time(uint int_part_length);
+ bool fix_attributes_bit();
bool check(THD *thd);
@@ -4202,7 +4255,6 @@ public:
uint pack_length_to_packflag(uint type);
enum_field_types get_blob_type_from_length(ulong length);
-uint32 calc_pack_length(enum_field_types type,uint32 length);
int set_field_to_null(Field *field);
int set_field_to_null_with_conversions(Field *field, bool no_conversions);
int convert_null_to_field_value_or_error(Field *field);
diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc
index 6ce17090efd..f293c40ccdd 100644
--- a/sql/ha_partition.cc
+++ b/sql/ha_partition.cc
@@ -7149,6 +7149,7 @@ int ha_partition::extra(enum ha_extra_function operation)
case HA_EXTRA_QUICK:
case HA_EXTRA_PREPARE_FOR_DROP:
case HA_EXTRA_FLUSH_CACHE:
+ case HA_EXTRA_PREPARE_FOR_ALTER_TABLE:
{
DBUG_RETURN(loop_extra(operation));
}
diff --git a/sql/ha_sequence.cc b/sql/ha_sequence.cc
index 25a1a6e71c4..a918da92be2 100644
--- a/sql/ha_sequence.cc
+++ b/sql/ha_sequence.cc
@@ -110,6 +110,8 @@ int ha_sequence::open(const char *name, int mode, uint flags)
if ((error= table->s->sequence->read_initial_values(table)))
file->ha_close();
}
+ else
+ table->m_needs_reopen= true;
}
DBUG_RETURN(error);
}
@@ -189,15 +191,17 @@ int ha_sequence::write_row(uchar *buf)
DBUG_ASSERT(table->record[0] == buf);
row_already_logged= 0;
- if (!sequence->initialized)
+ if (unlikely(sequence->initialized == SEQUENCE::SEQ_IN_PREPARE))
{
/* This calls is from ha_open() as part of create table */
DBUG_RETURN(file->write_row(buf));
}
+ if (unlikely(sequence->initialized != SEQUENCE::SEQ_READY_TO_USE))
+ DBUG_RETURN(HA_ERR_WRONG_COMMAND);
/*
User tries to write a row
- - Check that row is an accurate object
+ - Check that the new row is an accurate object
- Update the first row in the table
*/
@@ -286,6 +290,25 @@ int ha_sequence::info(uint flag)
DBUG_RETURN(false);
}
+
+int ha_sequence::extra(enum ha_extra_function operation)
+{
+ if (operation == HA_EXTRA_PREPARE_FOR_ALTER_TABLE)
+ {
+ /* In case of ALTER TABLE allow ::write_row() to copy rows */
+ sequence->initialized= SEQUENCE::SEQ_IN_PREPARE;
+ }
+ return file->extra(operation);
+}
+
+bool ha_sequence::check_if_incompatible_data(HA_CREATE_INFO *create_info,
+ uint table_changes)
+{
+ /* Table definition is locked for SEQUENCE tables */
+ return(COMPATIBLE_DATA_YES);
+}
+
+
int ha_sequence::external_lock(THD *thd, int lock_type)
{
int error= file->external_lock(thd, lock_type);
diff --git a/sql/ha_sequence.h b/sql/ha_sequence.h
index 3aacd62c5cb..f753d038114 100644
--- a/sql/ha_sequence.h
+++ b/sql/ha_sequence.h
@@ -84,6 +84,10 @@ public:
int info(uint);
LEX_CSTRING *engine_name() { return hton_name(file->ht); }
int external_lock(THD *thd, int lock_type);
+ int extra(enum ha_extra_function operation);
+ /* For ALTER ONLINE TABLE */
+ bool check_if_incompatible_data(HA_CREATE_INFO *create_info,
+ uint table_changes);
/* Functions that are directly mapped to the underlying handler */
int rnd_init(bool scan)
diff --git a/sql/item.cc b/sql/item.cc
index e775862ca3a..a9c7604d154 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -541,28 +541,6 @@ Item::Item(THD *thd, Item *item):
}
-uint Item::decimal_precision() const
-{
- Item_result restype= result_type();
-
- if ((restype == DECIMAL_RESULT) || (restype == INT_RESULT))
- {
- uint prec=
- my_decimal_length_to_precision(max_char_length(), decimals,
- unsigned_flag);
- return MY_MIN(prec, DECIMAL_MAX_PRECISION);
- }
- uint res= max_char_length();
- /*
- Return at least one decimal digit, even if Item::max_char_length()
- returned 0. This is important to avoid attempts to create fields of types
- INT(0) or DECIMAL(0,0) when converting NULL or empty strings to INT/DECIMAL:
- CREATE TABLE t1 AS SELECT CONVERT(NULL,SIGNED) AS a;
- */
- return res ? MY_MIN(res, DECIMAL_MAX_PRECISION) : 1;
-}
-
-
void Item::print_parenthesised(String *str, enum_query_type query_type,
enum precedence parent_prec)
{
@@ -3789,45 +3767,8 @@ bool Item_param::set_from_item(THD *thd, Item *item)
struct st_value tmp;
if (!item->save_in_value(&tmp))
{
- unsigned_flag= item->unsigned_flag;
- switch (item->cmp_type()) {
- case REAL_RESULT:
- set_double(tmp.value.m_double);
- set_handler(&type_handler_double);
- break;
- case INT_RESULT:
- set_int(tmp.value.m_longlong, MY_INT64_NUM_DECIMAL_DIGITS);
- set_handler(&type_handler_longlong);
- break;
- case STRING_RESULT:
- {
- value.cs_info.set(thd, item->collation.collation);
- /*
- Exact value of max_length is not known unless data is converted to
- charset of connection, so we have to set it later.
- */
- set_handler(&type_handler_varchar);
-
- if (set_str(tmp.m_string.ptr(), tmp.m_string.length()))
- DBUG_RETURN(1);
- break;
- }
- case DECIMAL_RESULT:
- {
- set_decimal(&tmp.m_decimal, unsigned_flag);
- set_handler(&type_handler_newdecimal);
- break;
- }
- case TIME_RESULT:
- {
- set_time(&tmp.value.m_time, item->max_length, item->decimals);
- set_handler(item->type_handler());
- break;
- }
- case ROW_RESULT:
- DBUG_ASSERT(0);
- set_null();
- }
+ if (item->type_handler()->Item_param_set_from_value(thd, this, item, &tmp))
+ DBUG_RETURN(true);
}
else
set_null();
@@ -9831,206 +9772,6 @@ void Item_cache_row::set_null()
};
-Item_type_holder::Item_type_holder(THD *thd, Item *item)
- :Item(thd, item),
- Type_handler_hybrid_field_type(item->real_type_handler()),
- Type_geometry_attributes(item),
- enum_set_typelib(0)
-{
- DBUG_ASSERT(item->fixed);
- maybe_null= item->maybe_null;
- get_full_info(item);
- DBUG_ASSERT(!decimals || result_type() != INT_RESULT);
- prev_decimal_int_part= item->decimal_int_part();
-}
-
-
-/**
- Find field type which can carry current Item_type_holder type and
- type of given Item.
-
- @param thd thread handler
- @param item given item to join its parameters with this item ones
-
- @retval
- TRUE error - types are incompatible
- @retval
- FALSE OK
-*/
-
-bool Item_type_holder::join_types(THD *thd, Item *item)
-{
- uint max_length_orig= max_length;
- uint decimals_orig= decimals;
- DBUG_ENTER("Item_type_holder::join_types");
- DBUG_PRINT("info:", ("was type %s len %d, dec %d name %s",
- real_type_handler()->name().ptr(), max_length, decimals,
- (name.str ? name.str : "<NULL>")));
- DBUG_PRINT("info:", ("in type %s len %d, dec %d",
- item->real_type_handler()->name().ptr(),
- item->max_length, item->decimals));
- const Type_handler *item_type_handler= item->real_type_handler();
- if (aggregate_for_result(item_type_handler))
- {
- my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
- Item_type_holder::real_type_handler()->name().ptr(),
- item_type_handler->name().ptr(),
- "UNION");
- DBUG_RETURN(true);
- }
-
- /*
- At this point non-zero decimals in combination with integer data types
- is possible in some cases:
- SELECT * FROM (SELECT NULL) a UNION SELECT 1;
- In the constructor Item_type_holder::Item_type_holder() the data type
- handler was set to type_handler_null with decimals==NOT_FIXED_DEC.
- After the above call for aggregate_for_result() for the literal 1
- which is on the right side of the UNION, the data type handler
- changes to type_handler_longlong, while decimals is still NOT_FIXED_DEC.
- */
- if (result_type() == INT_RESULT)
- decimals= 0;
- else
- decimals= MY_MAX(decimals, item->decimals);
-
- Type_geometry_attributes::join(item);
-
- if (result_type() == DECIMAL_RESULT)
- {
- decimals= MY_MIN(MY_MAX(decimals, item->decimals), DECIMAL_MAX_SCALE);
- int item_int_part= item->decimal_int_part();
- int item_prec = MY_MAX(prev_decimal_int_part, item_int_part) + decimals;
- int precision= MY_MIN(item_prec, DECIMAL_MAX_PRECISION);
- unsigned_flag&= item->unsigned_flag;
- max_length= my_decimal_precision_to_length_no_truncation(precision,
- decimals,
- unsigned_flag);
- }
-
- switch (result_type())
- {
- case STRING_RESULT:
- {
- const char *old_cs, *old_derivation;
- uint32 old_max_chars= max_length / collation.collation->mbmaxlen;
- old_cs= collation.collation->name;
- old_derivation= collation.derivation_name();
- if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV))
- {
- my_error(ER_CANT_AGGREGATE_2COLLATIONS, MYF(0),
- old_cs, old_derivation,
- item->collation.collation->name,
- item->collation.derivation_name(),
- "UNION");
- DBUG_RETURN(TRUE);
- }
- /*
- To figure out max_length, we have to take into account possible
- expansion of the size of the values because of character set
- conversions.
- */
- if (collation.collation != &my_charset_bin)
- {
- max_length= MY_MAX(old_max_chars * collation.collation->mbmaxlen,
- item->max_display_length() /
- item->collation.collation->mbmaxlen *
- collation.collation->mbmaxlen);
- }
- else
- set_if_bigger(max_length, item->max_display_length());
- break;
- }
- case REAL_RESULT:
- {
- if (decimals != NOT_FIXED_DEC)
- {
- /*
- For FLOAT(M,D)/DOUBLE(M,D) do not change precision
- if both fields have the same M and D
- */
- if (item->max_length != max_length_orig ||
- item->decimals != decimals_orig)
- {
- int delta1= max_length_orig - decimals_orig;
- int delta2= item->max_length - item->decimals;
- max_length= MY_MAX(delta1, delta2) + decimals;
- if (Item_type_holder::real_type_handler() == &type_handler_float &&
- max_length > FLT_DIG + 2)
- {
- max_length= MAX_FLOAT_STR_LENGTH;
- decimals= NOT_FIXED_DEC;
- }
- else if (Item_type_holder::real_type_handler() == &type_handler_double &&
- max_length > DBL_DIG + 2)
- {
- max_length= MAX_DOUBLE_STR_LENGTH;
- decimals= NOT_FIXED_DEC;
- }
- }
- }
- else
- max_length= (Item_type_holder::field_type() == MYSQL_TYPE_FLOAT) ?
- FLT_DIG+6 : DBL_DIG+7;
- break;
- }
- default:
- max_length= MY_MAX(max_length, item->max_display_length());
- };
- maybe_null|= item->maybe_null;
- get_full_info(item);
- /*
- Adjust data type for union, e.g.:
- - convert type_handler_null to type_handler_string
- - convert type_handler_olddecimal to type_handler_newdecimal
- - adjust varchar/blob according to max_length
- */
- set_handler(Item_type_holder::
- real_type_handler()->type_handler_for_union(this));
-
- /* Remember decimal integer part to be used in DECIMAL_RESULT handleng */
- prev_decimal_int_part= decimal_int_part();
- DBUG_PRINT("info", ("become type: %s len: %u dec: %u",
- real_type_handler()->name().ptr(),
- max_length, (uint) decimals));
- DBUG_RETURN(FALSE);
-}
-
-
-/**
- Get full information from Item about enum/set fields to be able to create
- them later.
-
- @param item Item for information collection
-*/
-void Item_type_holder::get_full_info(Item *item)
-{
- if (Item_type_holder::real_type_handler() == &type_handler_enum ||
- Item_type_holder::real_type_handler() == &type_handler_set)
- {
- if (item->type() == Item::SUM_FUNC_ITEM &&
- (((Item_sum*)item)->sum_func() == Item_sum::MAX_FUNC ||
- ((Item_sum*)item)->sum_func() == Item_sum::MIN_FUNC))
- item = ((Item_sum*)item)->get_arg(0);
- /*
- We can have enum/set type after merging only if we have one enum|set
- field (or MIN|MAX(enum|set field)) and number of NULL fields
- */
- DBUG_ASSERT((enum_set_typelib &&
- item->real_type_handler() == &type_handler_null) ||
- (!enum_set_typelib &&
- item->real_item()->type() == Item::FIELD_ITEM &&
- (item->real_type_handler() == &type_handler_enum ||
- item->real_type_handler() == &type_handler_set) &&
- ((Field_enum*)((Item_field *) item->real_item())->field)->typelib));
- if (!enum_set_typelib)
- {
- enum_set_typelib= ((Field_enum*)((Item_field *) item->real_item())->field)->typelib;
- }
- }
-}
-
-
double Item_type_holder::val_real()
{
DBUG_ASSERT(0); // should never be called
diff --git a/sql/item.h b/sql/item.h
index ad34320c560..2de5214c99e 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -787,6 +787,13 @@ public:
{
return type_handler()->max_display_length(this);
}
+ TYPELIB *get_typelib() const { return NULL; }
+ void set_maybe_null(bool maybe_null_arg) { maybe_null= maybe_null_arg; }
+ void set_typelib(TYPELIB *typelib)
+ {
+ // Non-field Items (e.g. hybrid functions) never have ENUM/SET types yet.
+ DBUG_ASSERT(0);
+ }
Item_cache* get_cache(THD *thd) const
{
return type_handler()->Item_get_cache(thd, this);
@@ -1143,7 +1150,10 @@ public:
inline uint float_length(uint decimals_par) const
{ return decimals < FLOATING_POINT_DECIMALS ? (DBL_DIG+2+decimals_par) : DBL_DIG+8;}
/* Returns total number of decimal digits */
- virtual uint decimal_precision() const;
+ virtual uint decimal_precision() const
+ {
+ return type_handler()->Item_decimal_precision(this);
+ }
/* Returns the number of integer part digits only */
inline int decimal_int_part() const
{ return my_decimal_int_part(decimal_precision(), decimals); }
@@ -1736,6 +1746,10 @@ public:
{ return Field::GEOM_GEOMETRY; };
uint uint_geometry_type() const
{ return get_geometry_type(); }
+ void set_geometry_type(uint type)
+ {
+ DBUG_ASSERT(0);
+ }
String *check_well_formed_result(String *str, bool send_error= 0);
bool eq_by_collation(Item *item, bool binary_cmp, CHARSET_INFO *cs);
bool too_big_for_varchar() const
@@ -1838,27 +1852,28 @@ class Type_geometry_attributes
{
uint m_geometry_type;
static const uint m_geometry_type_unknown= Field::GEOM_GEOMETRYCOLLECTION + 1;
- void copy(const Item *item)
+ void copy(const Type_handler *handler, const Type_all_attributes *gattr)
{
// Ignore implicit NULLs
- m_geometry_type= item->type_handler() == &type_handler_geometry ?
- item->uint_geometry_type() :
+ m_geometry_type= handler == &type_handler_geometry ?
+ gattr->uint_geometry_type() :
m_geometry_type_unknown;
}
public:
Type_geometry_attributes()
:m_geometry_type(m_geometry_type_unknown)
{ }
- Type_geometry_attributes(const Item *item)
+ Type_geometry_attributes(const Type_handler *handler,
+ const Type_all_attributes *gattr)
:m_geometry_type(m_geometry_type_unknown)
{
- copy(item);
+ copy(handler, gattr);
}
void join(const Item *item)
{
// Ignore implicit NULLs
if (m_geometry_type == m_geometry_type_unknown)
- copy(item);
+ copy(item->type_handler(), item);
else if (item->type_handler() == &type_handler_geometry)
{
m_geometry_type=
@@ -1898,7 +1913,6 @@ class Item_args
protected:
Item **args, *tmp_arg[2];
uint arg_count;
- bool alloc_arguments(THD *thd, uint count);
void set_arguments(THD *thd, List<Item> &list);
bool walk_args(Item_processor processor, bool walk_subquery, void *arg)
{
@@ -1957,6 +1971,11 @@ public:
set_arguments(thd, list);
}
Item_args(THD *thd, const Item_args *other);
+ bool alloc_arguments(THD *thd, uint count);
+ void add_argument(Item *item)
+ {
+ args[arg_count++]= item;
+ }
inline Item **arguments() const { return args; }
inline uint argument_count() const { return arg_count; }
inline void remove_arguments() { arg_count=0; }
@@ -2679,6 +2698,7 @@ public:
return &type_handler_null;
return field->type_handler();
}
+ TYPELIB *get_typelib() const { return field->get_typelib(); }
enum_monotonicity_info get_monotonicity_info() const
{
return MONOTONIC_STRICT_INCREASING;
@@ -2938,7 +2958,8 @@ public:
class Item_param :public Item_basic_value,
private Settable_routine_parameter,
public Rewritable_query_parameter,
- public Type_handler_hybrid_field_type
+ public Type_handler_hybrid_field_type,
+ public Type_geometry_attributes
{
/*
NO_VALUE is a special value meaning that the parameter has not been
@@ -3070,6 +3091,12 @@ public:
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
+ Field::geometry_type get_geometry_type() const
+ { return Type_geometry_attributes::get_geometry_type(); };
+
+ void set_geometry_type(uint type)
+ { Type_geometry_attributes::set_geometry_type(type); }
+
Item_param(THD *thd, const LEX_CSTRING *name_arg,
uint pos_in_query_arg, uint len_in_query_arg);
@@ -4318,6 +4345,11 @@ public:
{
return ref ? (*ref)->real_item() : this;
}
+ TYPELIB *get_typelib() const
+ {
+ return ref ? (*ref)->get_typelib() : NULL;
+ }
+
bool walk(Item_processor processor, bool walk_subquery, void *arg)
{
if (ref && *ref)
@@ -5827,12 +5859,29 @@ class Item_type_holder: public Item,
{
protected:
TYPELIB *enum_set_typelib;
- void get_full_info(Item *item);
-
- /* It is used to count decimal precision in join_types */
- int prev_decimal_int_part;
public:
- Item_type_holder(THD*, Item*);
+ Item_type_holder(THD *thd, Item *item)
+ :Item(thd, item),
+ Type_handler_hybrid_field_type(item->real_type_handler()),
+ enum_set_typelib(0)
+ {
+ DBUG_ASSERT(item->fixed);
+ maybe_null= item->maybe_null;
+ }
+ Item_type_holder(THD *thd,
+ const LEX_CSTRING *name_arg,
+ const Type_handler *handler,
+ const Type_all_attributes *attr,
+ bool maybe_null_arg)
+ :Item(thd),
+ Type_handler_hybrid_field_type(handler),
+ Type_geometry_attributes(handler, attr),
+ enum_set_typelib(attr->get_typelib())
+ {
+ name= *name_arg;
+ Type_std_attributes::set(*attr);
+ maybe_null= maybe_null_arg;
+ }
const Type_handler *type_handler() const
{
@@ -5850,7 +5899,6 @@ public:
longlong val_int();
my_decimal *val_decimal(my_decimal *);
String *val_str(String*);
- bool join_types(THD *thd, Item *);
Field *create_tmp_field(bool group, TABLE *table)
{
return Item_type_holder::real_type_handler()->
@@ -5861,6 +5909,10 @@ public:
{
return Type_geometry_attributes::get_geometry_type();
}
+ void set_geometry_type(uint type)
+ {
+ Type_geometry_attributes::set_geometry_type(type);
+ }
Item* get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 891a0c0f594..717a65489f6 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -479,7 +479,6 @@ void Item_bool_rowready_func2::fix_length_and_dec()
int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
Item **a1, Item **a2)
{
- THD *thd= current_thd;
owner= owner_arg;
set_null= set_null && owner_arg;
a= a1;
@@ -488,7 +487,7 @@ int Arg_comparator::set_cmp_func(Item_func_or_sum *owner_arg,
Type_handler_hybrid_field_type tmp;
if (tmp.aggregate_for_comparison(owner_arg->func_name(), tmp_args, 2, false))
{
- DBUG_ASSERT(thd->is_error());
+ DBUG_ASSERT(current_thd->is_error());
return 1;
}
m_compare_handler= tmp.type_handler();
@@ -2219,16 +2218,6 @@ void Item_func_between::print(String *str, enum_query_type query_type)
}
-uint Item_func_case_abbreviation2::decimal_precision2(Item **args) const
-{
- int arg0_int_part= args[0]->decimal_int_part();
- int arg1_int_part= args[1]->decimal_int_part();
- int max_int_part= MY_MAX(arg0_int_part, arg1_int_part);
- int precision= max_int_part + decimals;
- return MY_MIN(precision, DECIMAL_MAX_PRECISION);
-}
-
-
double
Item_func_ifnull::real_op()
{
@@ -3202,18 +3191,6 @@ Item* Item_func_case::propagate_equal_fields(THD *thd, const Context &ctx, COND_
}
-uint Item_func_case::decimal_precision() const
-{
- int max_int_part=0;
- for (uint i=0 ; i < ncases ; i+=2)
- set_if_bigger(max_int_part, args[i+1]->decimal_int_part());
-
- if (else_expr_num != -1)
- set_if_bigger(max_int_part, args[else_expr_num]->decimal_int_part());
- return MY_MIN(max_int_part + decimals, DECIMAL_MAX_PRECISION);
-}
-
-
/**
@todo
Fix this so that it prints the whole CASE expression
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index affba859725..6d604b3a2fc 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -1009,7 +1009,6 @@ protected:
if (!aggregate_for_result(func_name(), items, 2, true))
fix_attributes(items, 2);
}
- uint decimal_precision2(Item **args) const;
void cache_type_info(const Item *source, bool maybe_null_arg)
{
@@ -1064,10 +1063,6 @@ public:
const char *func_name() const { return "ifnull"; }
table_map not_null_tables() const { return 0; }
- uint decimal_precision() const
- {
- return Item_func_case_abbreviation2::decimal_precision2(args);
- }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_ifnull>(thd, mem_root, this); }
};
@@ -1128,10 +1123,6 @@ public:
{
fix_length_and_dec2_eliminate_null(args + 1);
}
- uint decimal_precision() const
- {
- return Item_func_case_abbreviation2::decimal_precision2(args + 1);
- }
const char *func_name() const { return "if"; }
bool eval_not_null_tables(void *opt_arg);
void fix_after_pullout(st_select_lex *new_parent, Item **ref);
@@ -1156,10 +1147,6 @@ public:
{
fix_length_and_dec2_eliminate_null(args + 1);
}
- uint decimal_precision() const
- {
- return Item_func_case_abbreviation2::decimal_precision2(args + 1);
- }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_nvl2>(thd, mem_root, this); }
};
@@ -1219,7 +1206,6 @@ public:
my_decimal *decimal_op(my_decimal *);
void 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"; }
void print(String *str, enum_query_type query_type);
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
@@ -2056,7 +2042,6 @@ public:
bool date_op(MYSQL_TIME *ltime, uint fuzzydate);
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
- uint decimal_precision() const;
table_map not_null_tables() const { return 0; }
const char *func_name() const { return "case"; }
enum precedence precedence() const { return BETWEEN_PRECEDENCE; }
diff --git a/sql/item_create.cc b/sql/item_create.cc
index f678bb44f21..60b39035d1b 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -517,6 +517,19 @@ protected:
};
+class Create_func_chr : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_chr s_singleton;
+
+protected:
+ Create_func_chr() {}
+ virtual ~Create_func_chr() {}
+};
+
+
class Create_func_convexhull : public Create_func_arg1
{
public:
@@ -2153,6 +2166,18 @@ protected:
virtual ~Create_func_length() {}
};
+class Create_func_octet_length : public Create_func_arg1
+{
+public:
+ virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+ static Create_func_octet_length s_singleton;
+
+protected:
+ Create_func_octet_length() {}
+ virtual ~Create_func_octet_length() {}
+};
+
#ifndef DBUG_OFF
class Create_func_like_range_min : public Create_func_arg2
@@ -3788,6 +3813,16 @@ Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
}
+Create_func_chr Create_func_chr::s_singleton;
+
+Item*
+Create_func_chr::create_1_arg(THD *thd, Item *arg1)
+{
+ CHARSET_INFO *cs_db= thd->variables.collation_database;
+ return new (thd->mem_root) Item_func_chr(thd, arg1, cs_db);
+}
+
+
Create_func_convexhull Create_func_convexhull::s_singleton;
Item*
@@ -5649,7 +5684,20 @@ Create_func_length Create_func_length::s_singleton;
Item*
Create_func_length::create_1_arg(THD *thd, Item *arg1)
{
- return new (thd->mem_root) Item_func_length(thd, arg1);
+#if 0 // Not yet
+ if (thd->variables.sql_mode & MODE_ORACLE)
+ return new (thd->mem_root) Item_func_char_length(thd, arg1);
+ else
+#endif
+ return new (thd->mem_root) Item_func_octet_length(thd, arg1);
+}
+
+Create_func_octet_length Create_func_octet_length::s_singleton;
+
+Item*
+Create_func_octet_length::create_1_arg(THD *thd, Item *arg1)
+{
+ return new (thd->mem_root) Item_func_octet_length(thd, arg1);
}
@@ -6831,6 +6879,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)},
{ { C_STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)},
{ { C_STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
+ { { C_STRING_WITH_LEN("CHR") }, BUILDER(Create_func_chr)},
{ { C_STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)},
{ { C_STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)},
{ { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)},
@@ -6981,7 +7030,7 @@ static Native_func_registry func_array[] =
{ { C_STRING_WITH_LEN("NUMINTERIORRINGS") }, GEOM_BUILDER(Create_func_numinteriorring)},
{ { C_STRING_WITH_LEN("NUMPOINTS") }, GEOM_BUILDER(Create_func_numpoints)},
{ { C_STRING_WITH_LEN("OCT") }, BUILDER(Create_func_oct)},
- { { C_STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_length)},
+ { { C_STRING_WITH_LEN("OCTET_LENGTH") }, BUILDER(Create_func_octet_length)},
{ { C_STRING_WITH_LEN("ORD") }, BUILDER(Create_func_ord)},
{ { C_STRING_WITH_LEN("OVERLAPS") }, GEOM_BUILDER(Create_func_mbr_overlaps)},
{ { C_STRING_WITH_LEN("PERIOD_ADD") }, BUILDER(Create_func_period_add)},
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0fddc65a66b..1f1523e738a 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -546,7 +546,9 @@ my_decimal *Item_func::val_decimal(my_decimal *decimal_value)
bool Item_hybrid_func::fix_attributes(Item **items, uint nitems)
{
bool rc= Item_hybrid_func::type_handler()->
- Item_hybrid_func_fix_attributes(current_thd, this, items, nitems);
+ Item_hybrid_func_fix_attributes(current_thd,
+ func_name(), this, this,
+ items, nitems);
DBUG_ASSERT(!rc || current_thd->is_error());
return rc;
}
@@ -2771,7 +2773,7 @@ my_decimal *Item_func_min_max::val_decimal_native(my_decimal *dec)
}
-longlong Item_func_length::val_int()
+longlong Item_func_octet_length::val_int()
{
DBUG_ASSERT(fixed == 1);
String *res=args[0]->val_str(&value);
@@ -6787,7 +6789,7 @@ longlong Item_func_nextval::val_int()
}
}
entry->null_value= null_value= 0;
- value= table->s->sequence->next_value(table,0, &error);
+ value= table->s->sequence->next_value(table, 0, &error);
entry->value= value;
entry->set_version(table);
@@ -6879,3 +6881,76 @@ longlong Item_func_lastval::val_int()
null_value= entry->null_value;
DBUG_RETURN(entry->value);
}
+
+
+/*
+ Sets next value to be returned from sequences
+
+ SELECT setval('foo', 42, 0); Next nextval will return 43
+ SELECT setval('foo', 42, 0, true); Same as above
+ SELECT setval('foo', 42, 0, false); Next nextval will return 42
+*/
+
+longlong Item_func_setval::val_int()
+{
+ longlong value;
+ int error;
+ TABLE *table= table_list->table;
+ DBUG_ASSERT(table && table->s->sequence);
+ DBUG_ENTER("Item_func_setval::val_int");
+
+ value= nextval;
+ error= table->s->sequence->set_value(table, nextval, round, is_used);
+ if (error)
+ {
+ null_value= 1;
+ value= 0;
+ }
+ DBUG_RETURN(value);
+}
+
+
+/* Print for setval */
+
+void Item_func_setval::print(String *str, enum_query_type query_type)
+{
+ char d_name_buff[MAX_ALIAS_NAME], t_name_buff[MAX_ALIAS_NAME];
+ const char *d_name= table_list->db, *t_name= table_list->table_name;
+ bool use_db_name= d_name && d_name[0];
+ THD *thd= table_list->table->in_use;
+
+ str->append(func_name());
+ str->append('(');
+
+ /*
+ for next_val we assume that table_list has been updated to contain
+ the current db.
+ */
+
+ if (lower_case_table_names > 0)
+ {
+ strmake(t_name_buff, t_name, MAX_ALIAS_NAME-1);
+ my_casedn_str(files_charset_info, t_name_buff);
+ t_name= t_name_buff;
+ if (use_db_name)
+ {
+ strmake(d_name_buff, d_name, MAX_ALIAS_NAME-1);
+ my_casedn_str(files_charset_info, d_name_buff);
+ d_name= d_name_buff;
+ }
+ }
+
+ if (use_db_name)
+ {
+ append_identifier(thd, str, d_name, (uint)strlen(d_name));
+ str->append('.');
+ }
+ append_identifier(thd, str, t_name, (uint) strlen(t_name));
+ str->append(',');
+ str->append_longlong(nextval);
+ str->append(',');
+ str->append_longlong(is_used);
+ str->append(',');
+ str->append_ulonglong(round);
+ str->append(')');
+}
diff --git a/sql/item_func.h b/sql/item_func.h
index 74c986545cd..860a4fdcc7d 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -398,6 +398,10 @@ public:
{ return Type_handler_hybrid_field_type::type_handler(); }
Field::geometry_type get_geometry_type() const
{ return Type_geometry_attributes::get_geometry_type(); };
+ void set_geometry_type(uint type)
+ {
+ Type_geometry_attributes::set_geometry_type(type);
+ }
};
@@ -1548,24 +1552,24 @@ public:
};
-class Item_func_length :public Item_int_func
+class Item_func_octet_length :public Item_int_func
{
String value;
public:
- Item_func_length(THD *thd, Item *a): Item_int_func(thd, a) {}
+ Item_func_octet_length(THD *thd, Item *a): Item_int_func(thd, a) {}
longlong val_int();
- const char *func_name() const { return "length"; }
+ const char *func_name() const { return "octet_length"; }
void fix_length_and_dec() { max_length=10; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_length>(thd, mem_root, this); }
+ { return get_item_copy<Item_func_octet_length>(thd, mem_root, this); }
};
-class Item_func_bit_length :public Item_func_length
+class Item_func_bit_length :public Item_func_octet_length
{
public:
- Item_func_bit_length(THD *thd, Item *a): Item_func_length(thd, a) {}
+ Item_func_bit_length(THD *thd, Item *a): Item_func_octet_length(thd, a) {}
longlong val_int()
- { DBUG_ASSERT(fixed == 1); return Item_func_length::val_int()*8; }
+ { DBUG_ASSERT(fixed == 1); return Item_func_octet_length::val_int()*8; }
const char *func_name() const { return "bit_length"; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_bit_length>(thd, mem_root, this); }
@@ -2863,6 +2867,7 @@ public:
}
};
+
/* Implementation for sequences: LASTVAL(sequence), PostgreSQL style */
class Item_func_lastval :public Item_func_nextval
@@ -2877,6 +2882,27 @@ public:
};
+/* Implementation for sequences: SETVAL(sequence), PostgreSQL style */
+
+class Item_func_setval :public Item_func_nextval
+{
+ longlong nextval;
+ ulonglong round;
+ bool is_used;
+public:
+ Item_func_setval(THD *thd, TABLE_LIST *table, longlong nextval_arg,
+ ulonglong round_arg, bool is_used_arg)
+ : Item_func_nextval(thd, table),
+ nextval(nextval_arg), round(round_arg), is_used(is_used_arg)
+ {}
+ longlong val_int();
+ const char *func_name() const { return "setval"; }
+ void print(String *str, enum_query_type query_type);
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_setval>(thd, mem_root, this); }
+};
+
+
Item *get_system_var(THD *thd, enum_var_type var_type, LEX_CSTRING name,
LEX_CSTRING component);
extern bool check_reserved_words(const LEX_CSTRING *name);
diff --git a/sql/item_jsonfunc.cc b/sql/item_jsonfunc.cc
index c7639bc2513..fd5b4a98e0e 100644
--- a/sql/item_jsonfunc.cc
+++ b/sql/item_jsonfunc.cc
@@ -1258,6 +1258,7 @@ longlong Item_func_json_contains_path::val_int()
longlong result;
json_path_t p;
int n_found;
+ LINT_INIT(n_found);
if ((null_value= args[0]->null_value))
return 0;
@@ -1985,6 +1986,7 @@ String *Item_func_json_merge::val_str(String *str)
json_engine_t je1, je2;
String *js1= args[0]->val_json(&tmp_js1), *js2;
uint n_arg;
+ LINT_INIT(js2);
if (args[0]->null_value)
goto null_return;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 4cf3a54af90..ee5646bdfc5 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2905,29 +2905,51 @@ String *Item_func_char::val_str(String *str)
{
int32 num=(int32) args[i]->val_int();
if (!args[i]->null_value)
- {
- char tmp[4];
- if (num & 0xFF000000L)
- {
- mi_int4store(tmp, num);
- str->append(tmp, 4, &my_charset_bin);
- }
- else if (num & 0xFF0000L)
- {
- mi_int3store(tmp, num);
- str->append(tmp, 3, &my_charset_bin);
- }
- else if (num & 0xFF00L)
- {
- mi_int2store(tmp, num);
- str->append(tmp, 2, &my_charset_bin);
- }
- else
- {
- tmp[0]= (char) num;
- str->append(tmp, 1, &my_charset_bin);
- }
- }
+ append_char(str, num);
+ }
+ str->realloc(str->length()); // Add end 0 (for Purify)
+ return check_well_formed_result(str);
+}
+
+
+void Item_func_char::append_char(String *str, int32 num)
+{
+ char tmp[4];
+ if (num & 0xFF000000L)
+ {
+ mi_int4store(tmp, num);
+ str->append(tmp, 4, &my_charset_bin);
+ }
+ else if (num & 0xFF0000L)
+ {
+ mi_int3store(tmp, num);
+ str->append(tmp, 3, &my_charset_bin);
+ }
+ else if (num & 0xFF00L)
+ {
+ mi_int2store(tmp, num);
+ str->append(tmp, 2, &my_charset_bin);
+ }
+ else
+ {
+ tmp[0]= (char) num;
+ str->append(tmp, 1, &my_charset_bin);
+ }
+}
+
+
+String *Item_func_chr::val_str(String *str)
+{
+ DBUG_ASSERT(fixed == 1);
+ str->length(0);
+ str->set_charset(collation.collation);
+ int32 num=(int32) args[0]->val_int();
+ if (!args[0]->null_value)
+ append_char(str, num);
+ else
+ {
+ null_value= 1;
+ return 0;
}
str->realloc(str->length()); // Add end 0 (for Purify)
return check_well_formed_result(str);
@@ -3165,6 +3187,7 @@ void Item_func_pad::fix_length_and_dec()
if (agg_arg_charsets_for_string_result(collation, &args[0], 1, 1))
return;
pad_str.set_charset(collation.collation);
+ pad_str.length(0);
pad_str.append(" ", 1);
}
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 267408187f3..6e31d489574 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -946,7 +946,11 @@ public:
Item_func_char(THD *thd, List<Item> &list, CHARSET_INFO *cs):
Item_str_func(thd, list)
{ collation.set(cs); }
+ Item_func_char(THD *thd, Item *arg1, CHARSET_INFO *cs):
+ Item_str_func(thd, arg1)
+ { collation.set(cs); }
String *val_str(String *);
+ void append_char(String * str, int32 num);
void fix_length_and_dec()
{
max_length= arg_count * 4;
@@ -956,6 +960,20 @@ public:
{ return get_item_copy<Item_func_char>(thd, mem_root, this); }
};
+class Item_func_chr :public Item_func_char
+{
+public:
+ Item_func_chr(THD *thd, Item *arg1, CHARSET_INFO *cs):
+ Item_func_char(thd, arg1, cs) {}
+ String *val_str(String *);
+ void fix_length_and_dec()
+ {
+ max_length= 4;
+ }
+ const char *func_name() const { return "chr"; }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+ { return get_item_copy<Item_func_chr>(thd, mem_root, this); }
+};
class Item_func_repeat :public Item_str_func
{
diff --git a/sql/item_sum.h b/sql/item_sum.h
index dee480ccf0a..c1485738b11 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1044,6 +1044,7 @@ protected:
}
const Type_handler *type_handler() const
{ return Type_handler_hybrid_field_type::type_handler(); }
+ TYPELIB *get_typelib() const { return args[0]->get_typelib(); }
void update_field();
void min_max_update_str_field();
void min_max_update_real_field();
diff --git a/sql/lex.h b/sql/lex.h
index bb6ab1ca34d..17dd45f9c0b 100644
--- a/sql/lex.h
+++ b/sql/lex.h
@@ -523,6 +523,7 @@ static SYMBOL symbols[] = {
{ "REQUIRE", SYM(REQUIRE_SYM)},
{ "RESET", SYM(RESET_SYM)},
{ "RESIGNAL", SYM(RESIGNAL_SYM)},
+ { "RESTART", SYM(RESTART_SYM)},
{ "RESTORE", SYM(RESTORE_SYM)},
{ "RESTRICT", SYM(RESTRICT)},
{ "RESUME", SYM(RESUME_SYM)},
@@ -563,6 +564,7 @@ static SYMBOL symbols[] = {
{ "SESSION", SYM(SESSION_SYM)},
{ "SERVER", SYM(SERVER_SYM)},
{ "SET", SYM(SET)},
+ { "SETVAL", SYM(SETVAL_SYM)},
{ "SHARE", SYM(SHARE_SYM)},
{ "SHOW", SYM(SHOW)},
{ "SHUTDOWN", SYM(SHUTDOWN)},
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 065f4d83367..eb39e542c41 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -3767,6 +3767,7 @@ SHOW_VAR com_status_vars[]= {
{"alter_function", STMT_STATUS(SQLCOM_ALTER_FUNCTION)},
{"alter_procedure", STMT_STATUS(SQLCOM_ALTER_PROCEDURE)},
{"alter_server", STMT_STATUS(SQLCOM_ALTER_SERVER)},
+ {"alter_sequence", STMT_STATUS(SQLCOM_ALTER_SEQUENCE)},
{"alter_table", STMT_STATUS(SQLCOM_ALTER_TABLE)},
{"alter_tablespace", STMT_STATUS(SQLCOM_ALTER_TABLESPACE)},
{"alter_user", STMT_STATUS(SQLCOM_ALTER_USER)},
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 87cb16c96fe..284f4348080 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -7501,6 +7501,8 @@ SEL_TREE *Item_bool_func::get_full_func_mm_tree(RANGE_OPT_PARAM *param,
param->current_table);
#ifdef HAVE_SPATIAL
Field::geometry_type sav_geom_type;
+ LINT_INIT(sav_geom_type);
+
if (field_item->field->type() == MYSQL_TYPE_GEOMETRY)
{
sav_geom_type= ((Field_geom*) field_item->field)->geom_type;
diff --git a/sql/slave.cc b/sql/slave.cc
index b28bc1d8dc5..b2cbac44c1b 100644
--- a/sql/slave.cc
+++ b/sql/slave.cc
@@ -3728,8 +3728,7 @@ int
apply_event_and_update_pos_for_parallel(Log_event* ev, THD* thd,
rpl_group_info *rgi)
{
- Relay_log_info* rli= rgi->rli;
- mysql_mutex_assert_not_owner(&rli->data_lock);
+ mysql_mutex_assert_not_owner(&rgi->rli->data_lock);
int reason= apply_event_and_update_pos_setup(ev, thd, rgi);
/*
In parallel replication, sql_slave_skip_counter is handled in the SQL
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 12b956623f8..80730a9b060 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -260,6 +260,7 @@ sp_get_flags_for_command(LEX *lex)
case SQLCOM_CREATE_USER:
case SQLCOM_CREATE_ROLE:
case SQLCOM_ALTER_TABLE:
+ case SQLCOM_ALTER_SEQUENCE:
case SQLCOM_ALTER_USER:
case SQLCOM_GRANT:
case SQLCOM_GRANT_ROLE:
diff --git a/sql/sp_head.h b/sql/sp_head.h
index e3c9022609b..cfc2e6861d7 100644
--- a/sql/sp_head.h
+++ b/sql/sp_head.h
@@ -626,7 +626,8 @@ public:
*/
bool fill_field_definition(THD *thd, Column_definition *field_def)
{
- return field_def->check(thd) ||
+ const Type_handler *h= field_def->type_handler();
+ return h->Column_definition_fix_attributes(field_def) ||
field_def->sp_prepare_create_field(thd, mem_root);
}
bool row_fill_field_definitions(THD *thd, Row_definition_list *row)
diff --git a/sql/sql_admin.cc b/sql/sql_admin.cc
index f3ecee89a79..31933e63b4e 100644
--- a/sql/sql_admin.cc
+++ b/sql/sql_admin.cc
@@ -394,7 +394,9 @@ static bool open_only_one_table(THD* thd, TABLE_LIST* table,
open_and_lock_tables(thd, table, TRUE, 0));
}
+#ifndef DBUG_OFF
dbug_err:
+#endif
thd->prepare_derived_at_open= FALSE;
diff --git a/sql/sql_alter.h b/sql/sql_alter.h
index beec5090343..c0232dd7358 100644
--- a/sql/sql_alter.h
+++ b/sql/sql_alter.h
@@ -385,6 +385,29 @@ public:
/**
+ Sql_cmd_alter_sequence represents the ALTER SEQUENCE statement.
+*/
+class Sql_cmd_alter_sequence : public Sql_cmd
+{
+public:
+ /**
+ Constructor, used to represent a ALTER TABLE statement.
+ */
+ Sql_cmd_alter_sequence()
+ {}
+
+ ~Sql_cmd_alter_sequence()
+ {}
+
+ enum_sql_command sql_command_code() const
+ {
+ return SQLCOM_ALTER_SEQUENCE;
+ }
+ bool execute(THD *thd);
+};
+
+
+/**
Sql_cmd_alter_table_tablespace represents ALTER TABLE
IMPORT/DISCARD TABLESPACE statements.
*/
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index b586cd138de..5b8aa9ce2aa 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1246,6 +1246,17 @@ extern "C" my_thread_id next_thread_id_noinline()
}
#endif
+
+const Type_handler *THD::type_handler_for_date() const
+{
+ if (!(variables.sql_mode & MODE_ORACLE))
+ return &type_handler_newdate;
+ if (opt_mysql56_temporal_format)
+ return &type_handler_datetime2;
+ return &type_handler_datetime;
+}
+
+
/*
Init common variables that has to be reset on start and on change_user
*/
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 6d84905515b..817be9d939c 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -3196,6 +3196,7 @@ public:
{
return !MY_TEST(variables.sql_mode & MODE_NO_BACKSLASH_ESCAPES);
}
+ const Type_handler *type_handler_for_date() const;
inline my_time_t query_start() { query_start_used=1; return start_time; }
inline ulong query_start_sec_part()
{ query_start_sec_part_used=1; return start_time_sec_part; }
diff --git a/sql/sql_cmd.h b/sql/sql_cmd.h
index 875dcf0e575..4ae9353d6ff 100644
--- a/sql/sql_cmd.h
+++ b/sql/sql_cmd.h
@@ -98,6 +98,7 @@ enum enum_sql_command {
SQLCOM_EXECUTE_IMMEDIATE,
SQLCOM_CREATE_SEQUENCE,
SQLCOM_DROP_SEQUENCE,
+ SQLCOM_ALTER_SEQUENCE,
/*
When a command is added here, be sure it's also added in mysqld.cc
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 44a82838d8e..4c763f50eaf 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -5407,13 +5407,8 @@ sp_variable *LEX::sp_add_for_loop_variable(THD *thd, const LEX_CSTRING *name,
spcont->declare_var_boundary(1);
spvar->field_def.field_name= spvar->name;
spvar->field_def.set_handler(&type_handler_longlong);
- /*
- The below is a simplified version of what
- Column_definition::prepare_create_field() does for a LONGLONG field.
- */
- spvar->field_def.pack_flag= (FIELDFLAG_NUMBER |
- f_settype((uint) MYSQL_TYPE_LONGLONG));
-
+ type_handler_longlong.Column_definition_prepare_stage2(&spvar->field_def,
+ NULL, HA_CAN_GEOMETRY);
if (!value && !(value= new (thd->mem_root) Item_null(thd)))
return NULL;
@@ -6404,7 +6399,6 @@ Item *LEX::create_item_func_nextval(THD *thd, Table_ident *table_ident)
MDL_SHARED_WRITE)))
return NULL;
return new (thd->mem_root) Item_func_nextval(thd, table);
-
}
@@ -6442,6 +6436,21 @@ Item *LEX::create_item_func_lastval(THD *thd,
}
+Item *LEX::create_item_func_setval(THD *thd, Table_ident *table_ident,
+ longlong nextval, ulonglong round,
+ bool is_used)
+{
+ TABLE_LIST *table;
+ if (!(table= current_select->add_table_to_list(thd, table_ident, 0,
+ TL_OPTION_SEQUENCE,
+ TL_WRITE_ALLOW_WRITE,
+ MDL_SHARED_WRITE)))
+ return NULL;
+ return new (thd->mem_root) Item_func_setval(thd, table, nextval, round,
+ is_used);
+}
+
+
Item *LEX::create_item_ident(THD *thd,
const LEX_CSTRING *a,
const LEX_CSTRING *b,
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index e763f8938ee..61c13814eeb 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -640,6 +640,14 @@ protected:
ulonglong found_rows_for_union;
bool saved_error;
+ bool prepare_join(THD *thd, SELECT_LEX *sl, select_result *result,
+ ulong additional_options,
+ bool is_union_select);
+ bool join_union_item_types(THD *thd, List<Item> &types, uint count);
+ bool join_union_type_handlers(THD *thd,
+ class Type_holder *holders, uint count);
+ bool join_union_type_attributes(THD *thd,
+ class Type_holder *holders, uint count);
public:
// Ensures that at least all members used during cleanup() are initialized.
st_select_lex_unit()
@@ -749,9 +757,6 @@ public:
/* UNION methods */
bool prepare(THD *thd, select_result *result, ulong additional_options);
- bool prepare_join(THD *thd, SELECT_LEX *sl, select_result *result,
- ulong additional_options,
- bool is_union_select);
bool optimize();
bool exec();
bool exec_recursive();
@@ -3276,6 +3281,12 @@ public:
const LEX_CSTRING *name);
/*
+ Create an item for "SETVAL(sequence_name, value [, is_used [, round]])
+ */
+ Item *create_item_func_setval(THD *thd, Table_ident *ident, longlong value,
+ ulonglong round, bool is_used);
+
+ /*
Create an item for a name in LIMIT clause: LIMIT var
@param THD - THD, for mem_root
@param var_name - the variable name
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2ecefc271d1..4ff988659c7 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -454,6 +454,7 @@ static bool stmt_causes_implicit_commit(THD *thd, uint mask)
(thd->variables.option_bits & OPTION_GTID_BEGIN));
break;
case SQLCOM_ALTER_TABLE:
+ case SQLCOM_ALTER_SEQUENCE:
/* If ALTER TABLE of non-temporary table, do implicit commit */
skip= (lex->tmp_table());
break;
@@ -555,6 +556,8 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_ALTER_TABLE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS |
CF_INSERTS_DATA;
+ sql_command_flags[SQLCOM_ALTER_SEQUENCE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
+ CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_TRUNCATE]= CF_CHANGES_DATA | CF_WRITE_LOGS_COMMAND |
CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_SCHEMA_CHANGE;
@@ -6213,9 +6216,11 @@ end_with_restore_list:
case SQLCOM_REPAIR:
case SQLCOM_TRUNCATE:
case SQLCOM_ALTER_TABLE:
- thd->query_plan_flags|= QPLAN_ADMIN;
DBUG_ASSERT(first_table == all_tables && first_table != 0);
/* fall through */
+ case SQLCOM_ALTER_SEQUENCE:
+ thd->query_plan_flags|= QPLAN_ADMIN;
+ /* fall through */
case SQLCOM_SIGNAL:
case SQLCOM_RESIGNAL:
case SQLCOM_GET_DIAGNOSTICS:
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 3d3b702cdac..a1c352e8b19 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -2480,6 +2480,7 @@ static bool check_prepared_statement(Prepared_statement *stmt)
case SQLCOM_DROP_SEQUENCE:
case SQLCOM_RENAME_TABLE:
case SQLCOM_ALTER_TABLE:
+ case SQLCOM_ALTER_SEQUENCE:
case SQLCOM_COMMIT:
case SQLCOM_CREATE_INDEX:
case SQLCOM_DROP_INDEX:
diff --git a/sql/sql_sequence.cc b/sql/sql_sequence.cc
index 98912691904..a6e7b073251 100644
--- a/sql/sql_sequence.cc
+++ b/sql/sql_sequence.cc
@@ -22,6 +22,7 @@
#include "sql_base.h"
#include "transaction.h"
#include "lock.h"
+#include "sql_acl.h"
struct Field_definition
{
@@ -162,7 +163,7 @@ void sequence_definition::store_fields(TABLE *table)
/*
- Check the sequence fields through seq_fields when create sequence.qq
+ Check the sequence fields through seq_fields when createing a sequence.
RETURN VALUES
false Success
@@ -269,7 +270,6 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list)
Reprepare_observer *save_reprepare_observer;
sequence_definition *seq= lex->create_info.seq_create_info;
bool temporary_table= table_list->table != 0;
- MY_BITMAP *save_write_set;
DBUG_ENTER("sequence_insert");
/* If not temporary table */
@@ -316,31 +316,7 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list)
}
seq->reserved_until= seq->start;
- seq->store_fields(table);
- /* Store the sequence values in table share */
- table->s->sequence->copy(seq);
-
- /*
- Sequence values will be replicated as a statement
- like 'create sequence'. So disable binary log temporarily
- */
- tmp_disable_binlog(thd);
- save_write_set= table->write_set;
- table->write_set= &table->s->all_set;
- error= table->file->ha_write_row(table->record[0]);
- reenable_binlog(thd);
- table->write_set= save_write_set;
-
- if (error)
- table->file->print_error(error, MYF(0));
- else
- {
- /*
- Sequence structure is up to date and table has one row,
- sequence is now usable
- */
- table->s->sequence->initialized= 1;
- }
+ error= seq->write_initial_sequence(table);
trans_commit_stmt(thd);
trans_commit_implicit(thd);
@@ -353,7 +329,7 @@ bool sequence_insert(THD *thd, LEX *lex, TABLE_LIST *table_list)
/* Create a SQUENCE object */
-SEQUENCE::SEQUENCE() :initialized(0), all_values_used(0), table(0)
+SEQUENCE::SEQUENCE() :all_values_used(0), initialized(SEQ_UNINTIALIZED), table(0)
{
mysql_mutex_init(key_LOCK_SEQUENCE, &mutex, MY_MUTEX_INIT_SLOW);
}
@@ -376,11 +352,11 @@ int SEQUENCE::read_initial_values(TABLE *table_arg)
MDL_request mdl_request; // Empty constructor!
DBUG_ENTER("SEQUENCE::read_initial_values");
- if (likely(initialized))
+ if (likely(initialized != SEQ_UNINTIALIZED))
DBUG_RETURN(0);
table= table_arg;
mysql_mutex_lock(&mutex);
- if (unlikely(!initialized))
+ if (likely(initialized == SEQ_UNINTIALIZED))
{
MYSQL_LOCK *lock;
bool mdl_lock_used= 0;
@@ -419,7 +395,7 @@ int SEQUENCE::read_initial_values(TABLE *table_arg)
DBUG_RETURN(HA_ERR_LOCK_WAIT_TIMEOUT);
}
if (!(error= read_stored_values()))
- initialized= 1;
+ initialized= SEQ_READY_TO_USE;
mysql_unlock_tables(thd, lock, 0);
if (mdl_lock_used)
thd->mdl_context.release_lock(mdl_request.ticket);
@@ -461,7 +437,7 @@ int SEQUENCE::read_stored_values()
DBUG_RETURN(error);
}
read_fields(table);
- adjust_values();
+ adjust_values(reserved_until);
all_values_used= 0;
DBUG_RETURN(0);
@@ -472,12 +448,12 @@ int SEQUENCE::read_stored_values()
Adjust values after reading a the stored state
*/
-void SEQUENCE::adjust_values()
+void SEQUENCE::adjust_values(longlong next_value)
{
- offset= 0;
- next_free_value= reserved_until;
+ next_free_value= next_value;
if (!(real_increment= increment))
{
+ longlong offset= 0;
longlong off, to_add;
/* Use auto_increment_increment and auto_increment_offset */
@@ -513,6 +489,72 @@ void SEQUENCE::adjust_values()
/**
+ Write initial sequence information for CREATE and ALTER to sequence table
+*/
+
+int sequence_definition::write_initial_sequence(TABLE *table)
+{
+ int error;
+ THD *thd= table->in_use;
+ MY_BITMAP *save_write_set;
+
+ store_fields(table);
+ /* Store the sequence values in table share */
+ table->s->sequence->copy(this);
+ /*
+ Sequence values will be replicated as a statement
+ like 'create sequence'. So disable binary log temporarily
+ */
+ tmp_disable_binlog(thd);
+ save_write_set= table->write_set;
+ table->write_set= &table->s->all_set;
+ table->s->sequence->initialized= SEQUENCE::SEQ_IN_PREPARE;
+ error= table->file->ha_write_row(table->record[0]);
+ table->s->sequence->initialized= SEQUENCE::SEQ_UNINTIALIZED;
+ reenable_binlog(thd);
+ table->write_set= save_write_set;
+ if (error)
+ table->file->print_error(error, MYF(0));
+ else
+ {
+ /*
+ Sequence structure is up to date and table has one row,
+ sequence is now usable
+ */
+ table->s->sequence->initialized= SEQUENCE::SEQ_READY_TO_USE;
+ }
+ return error;
+}
+
+
+/**
+ Store current sequence values into the sequence table
+*/
+
+int sequence_definition::write(TABLE *table)
+{
+ int error;
+ MY_BITMAP *save_rpl_write_set, *save_write_set;
+
+ /* Log a full insert (ok as table is small) */
+ save_rpl_write_set= table->rpl_write_set;
+
+ /* Update table */
+ save_write_set= table->write_set;
+ table->rpl_write_set= table->write_set= &table->s->all_set;
+ store_fields(table);
+ /* Tell ha_sequence::write_row that we already hold the mutex */
+ ((ha_sequence*) table->file)->sequence_locked= 1;
+ if ((error= table->file->ha_write_row(table->record[0])))
+ table->file->print_error(error, MYF(0));
+ ((ha_sequence*) table->file)->sequence_locked= 0;
+ table->rpl_write_set= save_rpl_write_set;
+ table->write_set= save_write_set;
+ return error;
+}
+
+
+/**
Get next value for sequence
@param in table Sequence table
@@ -544,7 +586,6 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
{
longlong res_value, org_reserved_until, add_to;
bool out_of_values;
- MY_BITMAP *save_rpl_write_set, *save_write_set;
DBUG_ENTER("SEQUENCE::next_value");
*error= 0;
@@ -552,24 +593,7 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
lock();
res_value= next_free_value;
-
- /* Increment next_free_value */
- if (real_increment > 0)
- {
- if (next_free_value + real_increment > max_value ||
- next_free_value > max_value - real_increment)
- next_free_value= max_value + 1;
- else
- next_free_value+= real_increment;
- }
- else
- {
- if (next_free_value + real_increment < min_value ||
- next_free_value < min_value - real_increment)
- next_free_value= min_value - 1;
- else
- next_free_value+= real_increment;
- }
+ next_free_value= increment_value(next_free_value);
if ((real_increment > 0 && res_value < reserved_until) ||
(real_increment < 0 && res_value > reserved_until))
@@ -619,7 +643,7 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
goto err;
round++;
reserved_until= real_increment >0 ? min_value : max_value;
- adjust_values(); // Fix next_free_value
+ adjust_values(reserved_until); // Fix next_free_value
/*
We have to do everything again to ensure that the given range was
not empty, which could happen if increment == 0
@@ -627,25 +651,11 @@ longlong SEQUENCE::next_value(TABLE *table, bool second_round, int *error)
DBUG_RETURN(next_value(table, 1, error));
}
- /* Log a full insert (ok as table is small) */
- save_rpl_write_set= table->rpl_write_set;
-
- /* Update table */
- save_write_set= table->write_set;
- table->rpl_write_set= table->write_set= &table->s->all_set;
- store_fields(table);
- /* Tell ha_sequence::write_row that we already hold the mutex */
- ((ha_sequence*) table->file)->sequence_locked= 1;
- if ((*error= table->file->ha_write_row(table->record[0])))
+ if ((*error= write(table)))
{
- table->file->print_error(*error, MYF(0));
- /* Restore original range */
reserved_until= org_reserved_until;
next_free_value= res_value;
}
- ((ha_sequence*) table->file)->sequence_locked= 0;
- table->rpl_write_set= save_rpl_write_set;
- table->write_set= save_write_set;
unlock();
DBUG_RETURN(res_value);
@@ -679,3 +689,179 @@ void SEQUENCE_LAST_VALUE::set_version(TABLE *table)
{
memcpy(table_version, table->s->tabledef_version.str, MY_UUID_SIZE);
}
+
+/**
+ Set the next value for sequence
+
+ @param in table Sequence table
+ @param in next_val Next free value
+ @param in next_round Round for 'next_value' (in cace of cycles)
+ @param in is_used 1 if next_val is already used
+
+  @retval 0 ok, value adjusted
+ 1 value was less than current value or
+ error when storing value
+
+ @comment
+ A new value is set only if "nextval,next_round" is less than
+ "next_free_value,round". This is needed as in replication
+ setvalue() calls may come out to the slave out-of-order.
+ Storing only the highest value ensures that sequence object will always
+ contain the highest used value when the slave is promoted to a master.
+*/
+
+bool SEQUENCE::set_value(TABLE *table, longlong next_val, ulonglong next_round,
+ bool is_used)
+{
+ bool error= 1;
+ bool needs_to_be_stored= 0;
+ longlong org_reserved_until= reserved_until;
+ longlong org_next_free_value= next_free_value;
+ ulonglong org_round= round;
+ DBUG_ENTER("SEQUENCE::set_value");
+
+ lock();
+ if (is_used)
+ next_val= increment_value(next_val);
+
+ if (round > next_round)
+ goto end;
+ if (round == next_round)
+ {
+ if (real_increment > 0 ?
+ next_val < next_free_value :
+ next_val > next_free_value)
+ goto end;
+ if (next_val == next_free_value)
+ {
+ error= 0;
+ goto end;
+ }
+ }
+ else if (cycle == 0)
+ goto end; // round < next_round && no cycles
+ else
+ needs_to_be_stored= 1;
+
+ round= next_round;
+ adjust_values(next_val);
+ if ((real_increment > 0 ?
+ next_free_value > reserved_until :
+ next_free_value < reserved_until) ||
+ needs_to_be_stored)
+ {
+ reserved_until= next_free_value;
+ if (write(table))
+ {
+ reserved_until= org_reserved_until;
+ next_free_value= org_next_free_value;
+ round= org_round;
+ goto end;
+ }
+ }
+ error= 0;
+
+end:
+ unlock();
+ DBUG_RETURN(error);
+}
+
+
+bool Sql_cmd_alter_sequence::execute(THD *thd)
+{
+ int error= 0;
+ int trapped_errors= 0;
+ LEX *lex= thd->lex;
+ TABLE_LIST *first_table= lex->query_tables;
+ TABLE *table;
+ sequence_definition *new_seq= lex->create_info.seq_create_info;
+ SEQUENCE *seq;
+ No_such_table_error_handler no_such_table_handler;
+ DBUG_ENTER("Sql_cmd_alter_sequence::execute");
+
+ if (check_access(thd, ALTER_ACL, first_table->db,
+ &first_table->grant.privilege,
+ &first_table->grant.m_internal,
+ 0, 0))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
+ if (check_grant(thd, ALTER_ACL, first_table, FALSE, UINT_MAX, FALSE))
+ DBUG_RETURN(TRUE); /* purecov: inspected */
+
+ if (lex->check_exists)
+ thd->push_internal_handler(&no_such_table_handler);
+ error= open_and_lock_tables(thd, first_table, FALSE, 0);
+ if (lex->check_exists)
+ {
+ trapped_errors= no_such_table_handler.safely_trapped_errors();
+ thd->pop_internal_handler();
+ }
+ if (error)
+ {
+ if (trapped_errors)
+ {
+ StringBuffer<FN_REFLEN> tbl_name;
+ tbl_name.append(first_table->db);
+ tbl_name.append('.');
+ tbl_name.append(first_table->table_name);
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
+ ER_UNKNOWN_SEQUENCES,
+ ER_THD(thd, ER_UNKNOWN_SEQUENCES),
+ tbl_name.c_ptr_safe());
+ my_ok(thd);
+ DBUG_RETURN(FALSE);
+ }
+ DBUG_RETURN(TRUE);
+ }
+
+ table= first_table->table;
+ seq= table->s->sequence;
+ new_seq->reserved_until= seq->reserved_until;
+
+ /* Copy from old sequence those fields that the user didn't specified */
+ if (!(new_seq->used_fields & seq_field_used_increment))
+ new_seq->increment= seq->increment;
+ if (!(new_seq->used_fields & seq_field_used_min_value))
+ new_seq->min_value= seq->min_value;
+ if (!(new_seq->used_fields & seq_field_used_max_value))
+ new_seq->max_value= seq->max_value;
+ if (!(new_seq->used_fields & seq_field_used_start))
+ new_seq->start= seq->start;
+ if (!(new_seq->used_fields & seq_field_used_cache))
+ new_seq->cache= seq->cache;
+ if (!(new_seq->used_fields & seq_field_used_cycle))
+ new_seq->cycle= seq->cycle;
+
+ /* If we should restart from a new value */
+ if (new_seq->used_fields & seq_field_used_restart)
+ {
+ if (!(new_seq->used_fields & seq_field_used_restart_value))
+ new_seq->restart= new_seq->start;
+ new_seq->reserved_until= new_seq->restart;
+ }
+
+ /* Let check_and_adjust think all fields are used */
+ new_seq->used_fields= ~0;
+ if (new_seq->check_and_adjust())
+ {
+ my_error(ER_SEQUENCE_INVALID_DATA, MYF(0),
+ first_table->db,
+ first_table->table_name);
+ error= 1;
+ goto end;
+ }
+
+ if (!(error= new_seq->write(table)))
+ {
+ /* Store the sequence values in table share */
+ table->s->sequence->copy(new_seq);
+ }
+ trans_commit_stmt(thd);
+ trans_commit_implicit(thd);
+ if (!error)
+ my_ok(thd);
+
+end:
+ close_thread_tables(thd);
+ DBUG_RETURN(error);
+}
diff --git a/sql/sql_sequence.h b/sql/sql_sequence.h
index f5534d55d9b..ffe5ded4cff 100644
--- a/sql/sql_sequence.h
+++ b/sql/sql_sequence.h
@@ -20,6 +20,11 @@
#define seq_field_used_min_value 1
#define seq_field_used_max_value 2
#define seq_field_used_start 4
+#define seq_field_used_increment 8
+#define seq_field_used_cache 16
+#define seq_field_used_cycle 32
+#define seq_field_used_restart 64
+#define seq_field_used_restart_value 128
/**
sequence_definition is used when defining a sequence as part of create
@@ -41,11 +46,14 @@ public:
ulonglong round;
bool cycle;
uint used_fields; // Which fields where used in CREATE
+ longlong restart; // alter sequence restart value
bool check_and_adjust();
void store_fields(TABLE *table);
void read_fields(TABLE *table);
- void print_dbug()
+ int write_initial_sequence(TABLE *table);
+ int write(TABLE *table);
+ inline void print_dbug()
{
DBUG_PRINT("sequence", ("reserved: %lld start: %lld increment: %lld min_value: %lld max_value: %lld cache: %lld round: %lld",
reserved_until, start, increment, min_value,
@@ -66,6 +74,7 @@ public:
class SEQUENCE :public sequence_definition
{
public:
+ enum seq_init { SEQ_UNINTIALIZED, SEQ_IN_PREPARE, SEQ_READY_TO_USE };
SEQUENCE();
~SEQUENCE();
int read_initial_values(TABLE *table);
@@ -79,16 +88,39 @@ public:
mysql_mutex_unlock(&mutex);
}
/* This must be called after sequence data has been updated */
- void adjust_values();
+ void adjust_values(longlong next_value);
void copy(sequence_definition *seq)
{
sequence_definition::operator= (*seq);
- adjust_values();
+ adjust_values(reserved_until);
}
longlong next_value(TABLE *table, bool second_round, int *error);
+ bool set_value(TABLE *table, longlong next_value, ulonglong round_arg,
+ bool is_used);
+ longlong increment_value(longlong value)
+ {
+ if (real_increment > 0)
+ {
+ if (value + real_increment > max_value ||
+ value > max_value - real_increment)
+ value= max_value + 1;
+ else
+ value+= real_increment;
+ }
+ else
+ {
+ if (value + real_increment < min_value ||
+ value < min_value - real_increment)
+ value= min_value - 1;
+ else
+ value+= real_increment;
+ }
+ return value;
+ }
- bool initialized; // If row has been read
bool all_values_used;
+ seq_init initialized;
+
private:
TABLE *table;
mysql_mutex_t mutex;
@@ -98,7 +130,6 @@ private:
merged with global auto_increment_offset and auto_increment_increment
*/
longlong real_increment;
- longlong offset;
};
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 2c75a5aa19e..e202552ac8a 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -2193,7 +2193,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0;
bool non_tmp_table_deleted= 0;
bool is_drop_tmp_if_exists_added= 0;
- bool was_view= 0, was_table, is_sequence;
+ bool was_view= 0, was_table= 0, is_sequence;
String built_query;
String built_trans_tmp_query, built_non_trans_tmp_query;
DBUG_ENTER("mysql_rm_table_no_locks");
@@ -2845,23 +2845,82 @@ bool check_duplicates_in_interval(const char *set_or_name,
}
+bool Column_definition::prepare_stage2_blob(handler *file,
+ ulonglong table_flags,
+ uint field_flags)
+{
+ if (table_flags & HA_NO_BLOBS)
+ {
+ my_error(ER_TABLE_CANT_HANDLE_BLOB, MYF(0), file->table_type());
+ return true;
+ }
+ pack_flag= field_flags |
+ pack_length_to_packflag(pack_length - portable_sizeof_char_ptr);
+ if (charset->state & MY_CS_BINSORT)
+ pack_flag|= FIELDFLAG_BINARY;
+ length= 8; // Unireg field length
+ return false;
+}
+
+
+bool Column_definition::prepare_stage2_typelib(const char *type_name,
+ uint field_flags,
+ uint *dup_val_count)
+{
+ pack_flag= pack_length_to_packflag(pack_length) | field_flags;
+ if (charset->state & MY_CS_BINSORT)
+ pack_flag|= FIELDFLAG_BINARY;
+ return check_duplicates_in_interval(type_name, field_name.str, interval,
+ charset, dup_val_count);
+}
+
+
+uint Column_definition::pack_flag_numeric(uint dec) const
+{
+ return (FIELDFLAG_NUMBER |
+ (flags & UNSIGNED_FLAG ? 0 : FIELDFLAG_DECIMAL) |
+ (flags & ZEROFILL_FLAG ? FIELDFLAG_ZEROFILL : 0) |
+ (dec << FIELDFLAG_DEC_SHIFT));
+}
+
+
+bool Column_definition::prepare_stage2_varchar(ulonglong table_flags)
+{
+#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
+ if (table_flags & HA_NO_VARCHAR)
+ {
+ /* convert VARCHAR to CHAR because handler is not yet up to date */
+ set_handler(&type_handler_var_string);
+ pack_length= type_handler()->calc_pack_length((uint) length);
+ if ((length / charset->mbmaxlen) > MAX_FIELD_CHARLENGTH)
+ {
+ my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name.str,
+ static_cast<ulong>(MAX_FIELD_CHARLENGTH));
+ return true;
+ }
+ }
+#endif
+ pack_flag= (charset->state & MY_CS_BINSORT) ? FIELDFLAG_BINARY : 0;
+ return false;
+}
+
+
/*
Prepare a Column_definition instance for packing
Members such as pack_flag are valid after this call.
- @param IN/OUT blob_columns - count for BLOBs
+ @param IN handler - storage engine handler,
+ or NULL if preparing for an SP variable
@param IN table_flags - table flags
@retval false - ok
@retval true - error (not supported type, bad definition, etc)
*/
-bool Column_definition::prepare_create_field(uint *blob_columns,
- ulonglong table_flags)
+bool Column_definition::prepare_stage2(handler *file,
+ ulonglong table_flags)
{
- uint dup_val_count;
- uint decimals_orig= decimals;
- DBUG_ENTER("Column_definition::prepare_create_field");
+ DBUG_ENTER("Column_definition::prepare_stage2");
/*
This code came from mysql_prepare_create_table.
@@ -2869,122 +2928,9 @@ bool Column_definition::prepare_create_field(uint *blob_columns,
*/
DBUG_ASSERT(charset);
- switch (real_field_type()) {
- case MYSQL_TYPE_BLOB:
- case MYSQL_TYPE_MEDIUM_BLOB:
- case MYSQL_TYPE_TINY_BLOB:
- case MYSQL_TYPE_LONG_BLOB:
- pack_flag= FIELDFLAG_BLOB |
- pack_length_to_packflag(pack_length - portable_sizeof_char_ptr);
- if (charset->state & MY_CS_BINSORT)
- pack_flag|= FIELDFLAG_BINARY;
- length= 8; // Unireg field length
- (*blob_columns)++;
- break;
- case MYSQL_TYPE_GEOMETRY:
-#ifdef HAVE_SPATIAL
- if (!(table_flags & HA_CAN_GEOMETRY))
- {
- my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "GEOMETRY");
- DBUG_RETURN(true);
- }
- pack_flag= FIELDFLAG_GEOM |
- pack_length_to_packflag(pack_length - portable_sizeof_char_ptr);
- if (charset->state & MY_CS_BINSORT)
- pack_flag|= FIELDFLAG_BINARY;
- length= 8; // Unireg field length
- (*blob_columns)++;
- break;
-#else
- my_error(ER_FEATURE_DISABLED, MYF(0),
- sym_group_geom.name, sym_group_geom.needed_define);
+ if (type_handler()->Column_definition_prepare_stage2(this, file, table_flags))
DBUG_RETURN(true);
-#endif /*HAVE_SPATIAL*/
- case MYSQL_TYPE_VARCHAR:
-#ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
- if (table_flags & HA_NO_VARCHAR)
- {
- /* convert VARCHAR to CHAR because handler is not yet up to date */
- set_handler(&type_handler_var_string);
- pack_length= calc_pack_length(real_field_type(), (uint) length);
- if ((length / charset->mbmaxlen) > MAX_FIELD_CHARLENGTH)
- {
- my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), field_name.str,
- static_cast<ulong>(MAX_FIELD_CHARLENGTH));
- DBUG_RETURN(true);
- }
- }
-#endif
- /* fall through */
- case MYSQL_TYPE_STRING:
- pack_flag= 0;
- if (charset->state & MY_CS_BINSORT)
- pack_flag|= FIELDFLAG_BINARY;
- break;
- case MYSQL_TYPE_ENUM:
- pack_flag= pack_length_to_packflag(pack_length) | FIELDFLAG_INTERVAL;
- if (charset->state & MY_CS_BINSORT)
- pack_flag|= FIELDFLAG_BINARY;
- if (check_duplicates_in_interval("ENUM", field_name.str, interval,
- charset, &dup_val_count))
- DBUG_RETURN(true);
- break;
- case MYSQL_TYPE_SET:
- pack_flag= pack_length_to_packflag(pack_length) | FIELDFLAG_BITFIELD;
- if (charset->state & MY_CS_BINSORT)
- pack_flag|= FIELDFLAG_BINARY;
- if (check_duplicates_in_interval("SET", field_name.str, interval,
- charset, &dup_val_count))
- DBUG_RETURN(true);
- /* Check that count of unique members is not more then 64 */
- if (interval->count - dup_val_count > sizeof(longlong)*8)
- {
- my_error(ER_TOO_BIG_SET, MYF(0), field_name.str);
- DBUG_RETURN(true);
- }
- break;
- case MYSQL_TYPE_DATE: // Rest of string types
- case MYSQL_TYPE_NEWDATE:
- case MYSQL_TYPE_TIME:
- case MYSQL_TYPE_DATETIME:
- case MYSQL_TYPE_TIME2:
- case MYSQL_TYPE_DATETIME2:
- case MYSQL_TYPE_NULL:
- pack_flag= f_settype((uint) real_field_type());
- break;
- case MYSQL_TYPE_BIT:
- /*
- We have sql_field->pack_flag already set here, see
- mysql_prepare_create_table().
- */
- break;
- case MYSQL_TYPE_NEWDECIMAL:
- pack_flag= (FIELDFLAG_NUMBER |
- (flags & UNSIGNED_FLAG ? 0 : FIELDFLAG_DECIMAL) |
- (flags & ZEROFILL_FLAG ? FIELDFLAG_ZEROFILL : 0) |
- (decimals_orig << FIELDFLAG_DEC_SHIFT));
- break;
- case MYSQL_TYPE_FLOAT:
- case MYSQL_TYPE_DOUBLE:
- /*
- User specified FLOAT() or DOUBLE() without precision. Change to
- FLOATING_POINT_DECIMALS to keep things compatible with earlier MariaDB
- versions.
- */
- if (decimals_orig >= FLOATING_POINT_DECIMALS)
- decimals_orig= FLOATING_POINT_DECIMALS;
- /* fall-trough */
- case MYSQL_TYPE_TIMESTAMP:
- case MYSQL_TYPE_TIMESTAMP2:
- /* fall-through */
- default:
- pack_flag= (FIELDFLAG_NUMBER |
- (flags & UNSIGNED_FLAG ? 0 : FIELDFLAG_DECIMAL) |
- (flags & ZEROFILL_FLAG ? FIELDFLAG_ZEROFILL : 0) |
- f_settype((uint) real_field_type()) |
- (decimals_orig << FIELDFLAG_DEC_SHIFT));
- break;
- }
+
if (!(flags & NOT_NULL_FLAG) ||
(vcol_info)) /* Make virtual columns allow NULL values */
pack_flag|= FIELDFLAG_MAYBE_NULL;
@@ -3007,7 +2953,7 @@ bool Column_definition::prepare_create_field(uint *blob_columns,
cs Character set
*/
-CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
+CHARSET_INFO* get_sql_field_charset(Column_definition *sql_field,
HA_CREATE_INFO *create_info)
{
CHARSET_INFO *cs= sql_field->charset;
@@ -3146,6 +3092,143 @@ static void check_duplicate_key(THD *thd, Key *key, KEY *key_info,
}
+bool Column_definition::prepare_stage1_typelib(THD *thd,
+ MEM_ROOT *mem_root,
+ handler *file,
+ ulonglong table_flags)
+{
+ /*
+ Pass the last parameter to prepare_interval_field() as follows:
+ - If we are preparing for an SP variable (file is NULL), we pass "false",
+ to force allocation and full copying of TYPELIB values on the given
+ mem_root, even if no character set conversion is needed. This is needed
+ because a life cycle of an SP variable is longer than the current query.
+
+ - If we are preparing for a CREATE TABLE, (file != NULL), we pass "true".
+ This will create the typelib in runtime memory - we will free the
+ occupied memory at the same time when we free this
+ sql_field -- at the end of execution.
+ Pass "true" as the last argument to reuse "interval_list"
+ values in "interval" in cases when no character conversion is needed,
+ to avoid extra copying.
+ */
+ if (prepare_interval_field(mem_root, file != NULL))
+ return true; // E.g. wrong values with commas: SET('a,b')
+ create_length_to_internal_length_typelib();
+
+ DBUG_ASSERT(file || !default_value); // SP variables have no default_value
+ if (default_value && default_value->expr->basic_const_item())
+ {
+ if ((charset != default_value->expr->collation.collation &&
+ prepare_stage1_convert_default(thd, mem_root, charset)) ||
+ prepare_stage1_check_typelib_default())
+ return true;
+ }
+ return false;
+}
+
+
+bool Column_definition::prepare_stage1_string(THD *thd,
+ MEM_ROOT *mem_root,
+ handler *file,
+ ulonglong table_flags)
+{
+ create_length_to_internal_length_string();
+ if (prepare_blob_field(thd))
+ return true;
+ DBUG_ASSERT(file || !default_value); // SP variables have no default_value
+ /*
+ Convert the default value from client character
+ set into the column character set if necessary.
+ We can only do this for constants as we have not yet run fix_fields.
+ */
+ if (default_value &&
+ default_value->expr->basic_const_item() &&
+ charset != default_value->expr->collation.collation)
+ {
+ if (prepare_stage1_convert_default(thd, mem_root, charset))
+ return true;
+ }
+ return false;
+}
+
+
+bool Column_definition::prepare_stage1_bit(THD *thd,
+ MEM_ROOT *mem_root,
+ handler *file,
+ ulonglong table_flags)
+{
+ pack_flag= FIELDFLAG_NUMBER;
+ if (!(table_flags & HA_CAN_BIT_FIELD))
+ pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
+ create_length_to_internal_length_bit();
+ return false;
+}
+
+
+bool Column_definition::prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ handler *file,
+ ulonglong table_flags)
+{
+ return type_handler()->Column_definition_prepare_stage1(thd, mem_root,
+ this, file,
+ table_flags);
+}
+
+
+bool Column_definition::prepare_stage1_convert_default(THD *thd,
+ MEM_ROOT *mem_root,
+ CHARSET_INFO *cs)
+{
+ DBUG_ASSERT(thd->mem_root == mem_root);
+ Item *item;
+ if (!(item= default_value->expr->safe_charset_converter(thd, cs)))
+ {
+ my_error(ER_INVALID_DEFAULT, MYF(0), field_name.str);
+ return true; // Could not convert
+ }
+ /* Fix for prepare statement */
+ thd->change_item_tree(&default_value->expr, item);
+ return false;
+}
+
+
+bool Column_definition::prepare_stage1_check_typelib_default()
+{
+ StringBuffer<MAX_FIELD_WIDTH> str;
+ String *def= default_value->expr->val_str(&str);
+ bool not_found;
+ if (def == NULL) /* SQL "NULL" maps to NULL */
+ {
+ not_found= flags & NOT_NULL_FLAG;
+ }
+ else
+ {
+ not_found= false;
+ if (real_field_type() == MYSQL_TYPE_SET)
+ {
+ char *not_used;
+ uint not_used2;
+ find_set(interval, def->ptr(), def->length(),
+ charset, &not_used, &not_used2, &not_found);
+ }
+ else /* MYSQL_TYPE_ENUM */
+ {
+ def->length(charset->cset->lengthsp(charset,
+ def->ptr(), def->length()));
+ not_found= !find_type2(interval, def->ptr(), def->length(), charset);
+ }
+ }
+ if (not_found)
+ {
+ my_error(ER_INVALID_DEFAULT, MYF(0), field_name.str);
+ return true;
+ }
+ return false;
+}
+
+
/*
Preparation for table creation
@@ -3180,7 +3263,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{
const char *key_name;
Create_field *sql_field,*dup_field;
- uint field,null_fields,blob_columns,max_key_length;
+ uint field,null_fields,max_key_length;
ulong record_offset= 0;
KEY *key_info;
KEY_PART_INFO *key_part_info;
@@ -3193,7 +3276,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
bool tmp_table= create_table_mode == C_ALTER_TABLE;
DBUG_ENTER("mysql_prepare_create_table");
- null_fields=blob_columns=0;
+ null_fields= 0;
create_info->varchar= 0;
max_key_length= file->max_key_length();
@@ -3215,8 +3298,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
select_field_pos= alter_info->create_list.elements - select_field_count;
for (field_no=0; (sql_field=it++) ; field_no++)
{
- CHARSET_INFO *save_cs;
-
/*
Initialize length from its original value (number of characters),
which was set in the parser. This is necessary if we're
@@ -3224,105 +3305,18 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
*/
sql_field->length= sql_field->char_length;
/* Set field charset. */
- save_cs= sql_field->charset= get_sql_field_charset(sql_field, create_info);
+ sql_field->charset= get_sql_field_charset(sql_field, create_info);
if ((sql_field->flags & BINCMP_FLAG) &&
- !(sql_field->charset= find_bin_collation(sql_field->charset)))
- DBUG_RETURN(TRUE);
-
- if (sql_field->real_field_type() == MYSQL_TYPE_SET ||
- sql_field->real_field_type() == MYSQL_TYPE_ENUM)
- {
- /*
- Create the typelib in runtime memory - we will free the
- occupied memory at the same time when we free this
- sql_field -- at the end of execution.
- Pass "true" as the last argument to reuse "interval_list"
- values in "interval" in cases when no character conversion is needed,
- to avoid extra copying.
- */
- if (sql_field->prepare_interval_field(thd->mem_root, true))
- DBUG_RETURN(true); // E.g. wrong values with commas: SET('a,b')
- }
-
- if (sql_field->real_field_type() == MYSQL_TYPE_BIT)
- {
- sql_field->pack_flag= FIELDFLAG_NUMBER;
- if (file->ha_table_flags() & HA_CAN_BIT_FIELD)
- total_uneven_bit_length+= sql_field->length & 7;
- else
- sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
- }
-
- sql_field->create_length_to_internal_length();
- if (sql_field->prepare_blob_field(thd))
- DBUG_RETURN(TRUE);
-
- /*
- Convert the default value from client character
- set into the column character set if necessary.
- We can only do this for constants as we have not yet run fix_fields.
- */
- if (sql_field->default_value &&
- sql_field->default_value->expr->basic_const_item() &&
- save_cs != sql_field->default_value->expr->collation.collation &&
- (sql_field->real_field_type() == MYSQL_TYPE_VAR_STRING ||
- sql_field->real_field_type() == MYSQL_TYPE_STRING ||
- sql_field->real_field_type() == MYSQL_TYPE_SET ||
- sql_field->real_field_type() == MYSQL_TYPE_TINY_BLOB ||
- sql_field->real_field_type() == MYSQL_TYPE_MEDIUM_BLOB ||
- sql_field->real_field_type() == MYSQL_TYPE_LONG_BLOB ||
- sql_field->real_field_type() == MYSQL_TYPE_BLOB ||
- sql_field->real_field_type() == MYSQL_TYPE_ENUM))
- {
- Item *item;
- if (!(item= sql_field->default_value->expr->
- safe_charset_converter(thd, save_cs)))
- {
- /* Could not convert */
- my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name.str);
- DBUG_RETURN(TRUE);
- }
- /* Fix for prepare statement */
- thd->change_item_tree(&sql_field->default_value->expr, item);
- }
+ !(sql_field->charset= find_bin_collation(sql_field->charset)))
+ DBUG_RETURN(true);
- if (sql_field->default_value &&
- sql_field->default_value->expr->basic_const_item() &&
- (sql_field->real_field_type() == MYSQL_TYPE_SET ||
- sql_field->real_field_type() == MYSQL_TYPE_ENUM))
- {
- StringBuffer<MAX_FIELD_WIDTH> str;
- String *def= sql_field->default_value->expr->val_str(&str);
- bool not_found;
- if (def == NULL) /* SQL "NULL" maps to NULL */
- {
- not_found= sql_field->flags & NOT_NULL_FLAG;
- }
- else
- {
- not_found= false;
- if (sql_field->real_field_type() == MYSQL_TYPE_SET)
- {
- char *not_used;
- uint not_used2;
- find_set(sql_field->interval, def->ptr(), def->length(),
- sql_field->charset, &not_used, &not_used2, &not_found);
- }
- else /* MYSQL_TYPE_ENUM */
- {
- def->length(sql_field->charset->cset->lengthsp(sql_field->charset,
- def->ptr(), def->length()));
- not_found= !find_type2(sql_field->interval, def->ptr(),
- def->length(), sql_field->charset);
- }
- }
+ if (sql_field->prepare_stage1(thd, thd->mem_root,
+ file, file->ha_table_flags()))
+ DBUG_RETURN(true);
- if (not_found)
- {
- my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name.str);
- DBUG_RETURN(TRUE);
- }
- }
+ if (sql_field->real_field_type() == MYSQL_TYPE_BIT &&
+ file->ha_table_flags() & HA_CAN_BIT_FIELD)
+ total_uneven_bit_length+= sql_field->length & 7;
if (!(sql_field->flags & NOT_NULL_FLAG))
null_fields++;
@@ -3419,7 +3413,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
{
DBUG_ASSERT(sql_field->charset != 0);
- if (sql_field->prepare_create_field(&blob_columns, file->ha_table_flags()))
+ if (sql_field->prepare_stage2(file, file->ha_table_flags()))
DBUG_RETURN(TRUE);
if (sql_field->real_field_type() == MYSQL_TYPE_VARCHAR)
create_info->varchar= TRUE;
@@ -3461,12 +3455,6 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE);
}
- if (blob_columns && (file->ha_table_flags() & HA_NO_BLOBS))
- {
- my_error(ER_TABLE_CANT_HANDLE_BLOB, MYF(0), file->table_type());
- DBUG_RETURN(TRUE);
- }
-
/*
CREATE TABLE[with auto_increment column] SELECT is unsafe as the rows
inserted in the created table depends on the order of the rows fetched
@@ -4237,7 +4225,7 @@ bool Column_definition::prepare_blob_field(THD *thd)
{
/* The user has given a length to the blob column */
set_handler(Type_handler::blob_type_handler(length));
- pack_length= calc_pack_length(real_field_type(), 0);
+ pack_length= type_handler()->calc_pack_length(0);
}
length= 0;
}
@@ -4262,30 +4250,8 @@ bool Column_definition::prepare_blob_field(THD *thd)
bool Column_definition::sp_prepare_create_field(THD *thd, MEM_ROOT *mem_root)
{
- if (real_field_type() == MYSQL_TYPE_SET ||
- real_field_type() == MYSQL_TYPE_ENUM)
- {
- /*
- Pass "false" as the last argument to allocate TYPELIB values on mem_root,
- even if no character set conversion is needed.
- */
- if (prepare_interval_field(mem_root, false))
- return true; // E.g. wrong values with commas: SET('a,b')
- }
-
- if (real_field_type() == MYSQL_TYPE_BIT)
- pack_flag= FIELDFLAG_NUMBER | FIELDFLAG_TREAT_BIT_AS_CHAR;
- create_length_to_internal_length();
- DBUG_ASSERT(default_value == 0);
- /*
- prepare_blob_field() can return an error on attempt to create a too long
- VARCHAR/VARBINARY field when the current sql_mode does not allow automatic
- conversion to TEXT/BLOB.
- */
- if (prepare_blob_field(thd))
- return true;
- uint unused1;
- return prepare_create_field(&unused1, HA_CAN_GEOMETRY);
+ return prepare_stage1(thd, mem_root, NULL, HA_CAN_GEOMETRY) ||
+ prepare_stage2(NULL, HA_CAN_GEOMETRY);
}
@@ -9631,6 +9597,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
thd->abort_on_warning= !ignore && thd->is_strict_mode();
from->file->info(HA_STATUS_VARIABLE);
+ to->file->extra(HA_EXTRA_PREPARE_FOR_ALTER_TABLE);
to->file->ha_start_bulk_insert(from->file->stats.records,
ignore ? 0 : HA_CREATE_UNIQUE_INDEX_BY_SORT);
diff --git a/sql/sql_table.h b/sql/sql_table.h
index 4fb6135e9cc..2e080462deb 100644
--- a/sql/sql_table.h
+++ b/sql/sql_table.h
@@ -253,7 +253,7 @@ bool quick_rm_table(THD *thd, handlerton *base, const char *db,
const char *table_path=0);
void close_cached_table(THD *thd, TABLE *table);
void sp_prepare_create_field(THD *thd, Column_definition *sql_field);
-CHARSET_INFO* get_sql_field_charset(Create_field *sql_field,
+CHARSET_INFO* get_sql_field_charset(Column_definition *sql_field,
HA_CREATE_INFO *create_info);
bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags);
int write_bin_log(THD *thd, bool clear_error,
diff --git a/sql/sql_type.cc b/sql/sql_type.cc
index 7d0bd9004da..90f8d674e67 100644
--- a/sql/sql_type.cc
+++ b/sql/sql_type.cc
@@ -380,6 +380,20 @@ Type_handler_hybrid_field_type::Type_handler_hybrid_field_type()
/***************************************************************************/
+
+/* number of bytes to store second_part part of the TIMESTAMP(N) */
+uint Type_handler_timestamp::m_sec_part_bytes[MAX_DATETIME_PRECISION + 1]=
+ { 0, 1, 1, 2, 2, 3, 3 };
+
+/* number of bytes to store DATETIME(N) */
+uint Type_handler_datetime::m_hires_bytes[MAX_DATETIME_PRECISION + 1]=
+ { 5, 6, 6, 7, 7, 7, 8 };
+
+/* number of bytes to store TIME(N) */
+uint Type_handler_time::m_hires_bytes[MAX_DATETIME_PRECISION + 1]=
+ { 3, 4, 4, 5, 5, 5, 6 };
+
+/***************************************************************************/
const Name Type_handler_row::m_name_row(C_STRING_WITH_LEN("row"));
const Name Type_handler_null::m_name_null(C_STRING_WITH_LEN("null"));
@@ -482,29 +496,18 @@ const Type_handler *Type_handler_row::type_handler_for_comparison() const
/***************************************************************************/
-const Type_handler *Type_handler_enum::type_handler_for_item_field() const
+const Type_handler *Type_handler_typelib::type_handler_for_item_field() const
{
return &type_handler_string;
}
-const Type_handler *Type_handler_enum::cast_to_int_type_handler() const
+const Type_handler *Type_handler_typelib::cast_to_int_type_handler() const
{
return &type_handler_longlong;
}
-const Type_handler *Type_handler_set::type_handler_for_item_field() const
-{
- return &type_handler_string;
-}
-
-
-const Type_handler *Type_handler_set::cast_to_int_type_handler() const
-{
- return &type_handler_longlong;
-}
-
/***************************************************************************/
bool
@@ -1392,6 +1395,452 @@ Field *Type_handler_set::make_conversion_table_field(TABLE *table,
}
/*************************************************************************/
+bool Type_handler_null::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return false;
+}
+
+bool Type_handler_tiny::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_int(MAX_TINYINT_WIDTH + def->sign_length());
+}
+
+bool Type_handler_short::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_int(MAX_SMALLINT_WIDTH + def->sign_length());
+}
+
+bool Type_handler_int24::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_int(MAX_MEDIUMINT_WIDTH + def->sign_length());
+}
+
+bool Type_handler_long::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_int(MAX_INT_WIDTH + def->sign_length());
+}
+
+bool Type_handler_longlong::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_int(MAX_BIGINT_WIDTH/*no sign_length() added*/);
+}
+
+bool Type_handler_newdecimal::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_decimal();
+}
+
+bool Type_handler_olddecimal::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ DBUG_ASSERT(0); // Obsolete
+ return true;
+}
+
+bool Type_handler_var_string::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ DBUG_ASSERT(0); // Obsolete
+ return true;
+}
+
+bool Type_handler_varchar::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ /*
+ Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
+ if they don't have a default value
+ */
+ return def->check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_FIELD_BLOBLENGTH);
+}
+
+bool Type_handler_string::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->check_length(ER_TOO_BIG_FIELDLENGTH, MAX_FIELD_CHARLENGTH);
+}
+
+bool Type_handler_blob_common::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ def->flags|= BLOB_FLAG;
+ return def->check_length(ER_TOO_BIG_DISPLAYWIDTH, MAX_FIELD_BLOBLENGTH);
+}
+
+#ifdef HAVE_SPATIAL
+bool Type_handler_geometry::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ def->flags|= BLOB_FLAG;
+ return false;
+}
+#endif
+
+bool Type_handler_year::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ if (!def->length || def->length != 2)
+ def->length= 4; // Default length
+ def->flags|= ZEROFILL_FLAG | UNSIGNED_FLAG;
+ return false;
+}
+
+bool Type_handler_float::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_real(MAX_FLOAT_STR_LENGTH);
+}
+
+
+bool Type_handler_double::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_real(DBL_DIG + 7);
+}
+
+bool Type_handler_timestamp_common::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ def->flags|= UNSIGNED_FLAG;
+ return def->fix_attributes_temporal_with_time(MAX_DATETIME_WIDTH);
+}
+
+bool Type_handler_date_common::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ // We don't support creation of MYSQL_TYPE_DATE anymore
+ def->set_handler(&type_handler_newdate);
+ def->length= MAX_DATE_WIDTH;
+ return false;
+}
+
+bool Type_handler_time_common::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_temporal_with_time(MIN_TIME_WIDTH);
+}
+
+bool Type_handler_datetime_common::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_temporal_with_time(MAX_DATETIME_WIDTH);
+}
+
+bool Type_handler_set::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ def->pack_length= get_set_pack_length(def->interval_list.elements);
+ return false;
+}
+
+bool Type_handler_enum::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ def->pack_length= get_enum_pack_length(def->interval_list.elements);
+ return false;
+}
+
+bool Type_handler_bit::
+ Column_definition_fix_attributes(Column_definition *def) const
+{
+ return def->fix_attributes_bit();
+}
+
+/*************************************************************************/
+
+bool Type_handler::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ def->create_length_to_internal_length_simple();
+ return false;
+}
+
+bool Type_handler_null::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ def->create_length_to_internal_length_null();
+ return false;
+}
+
+bool Type_handler_newdecimal::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ def->create_length_to_internal_length_newdecimal();
+ return false;
+}
+
+bool Type_handler_bit::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ return def->prepare_stage1_bit(thd, mem_root, file, table_flags);
+}
+
+bool Type_handler_typelib::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ return def->prepare_stage1_typelib(thd, mem_root, file, table_flags);
+}
+
+
+bool Type_handler_string_result::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ return def->prepare_stage1_string(thd, mem_root, file, table_flags);
+}
+
+
+#ifdef HAVE_SPATIAL
+bool Type_handler_geometry::
+ Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ def->create_length_to_internal_length_string();
+ return def->prepare_blob_field(thd);
+}
+#endif
+
+
+/*************************************************************************/
+
+bool Type_handler::
+ Column_definition_prepare_stage2_legacy(Column_definition *def,
+ enum_field_types type) const
+{
+ def->pack_flag= f_settype((uint) type);
+ return false;
+}
+
+bool Type_handler::
+ Column_definition_prepare_stage2_legacy_num(Column_definition *def,
+ enum_field_types type) const
+{
+ def->pack_flag= def->pack_flag_numeric(def->decimals) |
+ f_settype((uint) type);
+ return false;
+}
+
+bool Type_handler::
+ Column_definition_prepare_stage2_legacy_real(Column_definition *def,
+ enum_field_types type) const
+{
+ uint dec= def->decimals;
+ /*
+ User specified FLOAT() or DOUBLE() without precision. Change to
+ FLOATING_POINT_DECIMALS to keep things compatible with earlier MariaDB
+ versions.
+ */
+ if (dec >= FLOATING_POINT_DECIMALS)
+ dec= FLOATING_POINT_DECIMALS;
+ def->pack_flag= def->pack_flag_numeric(dec) | f_settype((uint) type);
+ return false;
+}
+
+bool Type_handler_newdecimal::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ def->pack_flag= def->pack_flag_numeric(def->decimals);
+ return false;
+}
+
+bool Type_handler_blob_common::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ return def->prepare_stage2_blob(file, table_flags, FIELDFLAG_BLOB);
+}
+
+#ifdef HAVE_SPATIAL
+bool Type_handler_geometry::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ if (!(table_flags & HA_CAN_GEOMETRY))
+ {
+ my_error(ER_CHECK_NOT_IMPLEMENTED, MYF(0), "GEOMETRY");
+ return true;
+ }
+ return def->prepare_stage2_blob(file, table_flags, FIELDFLAG_GEOM);
+}
+#endif
+
+bool Type_handler_varchar::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ return def->prepare_stage2_varchar(table_flags);
+}
+
+bool Type_handler_string::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ def->pack_flag= (def->charset->state & MY_CS_BINSORT) ? FIELDFLAG_BINARY : 0;
+ return false;
+}
+
+bool Type_handler_enum::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ uint dummy;
+ return def->prepare_stage2_typelib("ENUM", FIELDFLAG_INTERVAL, &dummy);
+}
+
+bool Type_handler_set::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ uint dup_count;
+ if (def->prepare_stage2_typelib("SET", FIELDFLAG_BITFIELD, &dup_count))
+ return true;
+ /* Check that count of unique members is not more then 64 */
+ if (def->interval->count - dup_count > sizeof(longlong)*8)
+ {
+ my_error(ER_TOO_BIG_SET, MYF(0), def->field_name.str);
+ return true;
+ }
+ return false;
+}
+
+bool Type_handler_bit::
+ Column_definition_prepare_stage2(Column_definition *def,
+ handler *file,
+ ulonglong table_flags) const
+{
+ /*
+ We have sql_field->pack_flag already set here, see
+ mysql_prepare_create_table().
+ */
+ return false;
+}
+
+/*************************************************************************/
+
+uint32 Type_handler_time::calc_pack_length(uint32 length) const
+{
+ return length > MIN_TIME_WIDTH ?
+ hires_bytes(length - 1 - MIN_TIME_WIDTH) : 3;
+}
+
+uint32 Type_handler_time2::calc_pack_length(uint32 length) const
+{
+ return length > MIN_TIME_WIDTH ?
+ my_time_binary_length(length - MIN_TIME_WIDTH - 1) : 3;
+}
+
+uint32 Type_handler_timestamp::calc_pack_length(uint32 length) const
+{
+ return length > MAX_DATETIME_WIDTH ?
+ 4 + sec_part_bytes(length - 1 - MAX_DATETIME_WIDTH) : 4;
+}
+
+uint32 Type_handler_timestamp2::calc_pack_length(uint32 length) const
+{
+ return length > MAX_DATETIME_WIDTH ?
+ my_timestamp_binary_length(length - MAX_DATETIME_WIDTH - 1) : 4;
+}
+
+uint32 Type_handler_datetime::calc_pack_length(uint32 length) const
+{
+ return length > MAX_DATETIME_WIDTH ?
+ hires_bytes(length - 1 - MAX_DATETIME_WIDTH) : 8;
+}
+
+uint32 Type_handler_datetime2::calc_pack_length(uint32 length) const
+{
+ return length > MAX_DATETIME_WIDTH ?
+ my_datetime_binary_length(length - MAX_DATETIME_WIDTH - 1) : 5;
+}
+
+uint32 Type_handler_tiny_blob::calc_pack_length(uint32 length) const
+{
+ return 1 + portable_sizeof_char_ptr;
+}
+
+uint32 Type_handler_blob::calc_pack_length(uint32 length) const
+{
+ return 2 + portable_sizeof_char_ptr;
+}
+
+uint32 Type_handler_medium_blob::calc_pack_length(uint32 length) const
+{
+ return 3 + portable_sizeof_char_ptr;
+}
+
+uint32 Type_handler_long_blob::calc_pack_length(uint32 length) const
+{
+ return 4 + portable_sizeof_char_ptr;
+}
+
+#ifdef HAVE_SPATIAL
+uint32 Type_handler_geometry::calc_pack_length(uint32 length) const
+{
+ return 4 + portable_sizeof_char_ptr;
+}
+#endif
+
+uint32 Type_handler_newdecimal::calc_pack_length(uint32 length) const
+{
+ abort(); // This shouldn't happen
+ return 0;
+}
+
+uint32 Type_handler_set::calc_pack_length(uint32 length) const
+{
+ abort(); // This shouldn't happen
+ return 0;
+}
+
+uint32 Type_handler_enum::calc_pack_length(uint32 length) const
+{
+ abort(); // This shouldn't happen
+ return 0;
+}
+
+
+/*************************************************************************/
Field *Type_handler::make_and_init_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2080,7 +2529,10 @@ Type_handler_temporal_result::Item_get_cache(THD *thd, const Item *item) const
/*************************************************************************/
bool Type_handler_int_result::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
uint unsigned_flag= items[0]->unsigned_flag;
@@ -2089,7 +2541,7 @@ bool Type_handler_int_result::
if (unsigned_flag != items[i]->unsigned_flag)
{
// Convert a mixture of signed and unsigned int to decimal
- func->set_handler(&type_handler_newdecimal);
+ handler->set_handler(&type_handler_newdecimal);
func->aggregate_attributes_decimal(items, nitems);
return false;
}
@@ -2100,7 +2552,10 @@ bool Type_handler_int_result::
bool Type_handler_real_result::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
func->aggregate_attributes_real(items, nitems);
@@ -2109,7 +2564,10 @@ bool Type_handler_real_result::
bool Type_handler_decimal_result::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
func->aggregate_attributes_decimal(items, nitems);
@@ -2118,26 +2576,59 @@ bool Type_handler_decimal_result::
bool Type_handler_string_result::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
- return func->aggregate_attributes_string(func->func_name(), items, nitems);
+ return func->aggregate_attributes_string(func_name, items, nitems);
+}
+
+
+
+/*
+ We can have enum/set type after merging only if we have one enum|set
+ field (or MIN|MAX(enum|set field)) and number of NULL fields
+*/
+bool Type_handler_typelib::
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
+ Item **items, uint nitems) const
+{
+ TYPELIB *typelib= NULL;
+ for (uint i= 0; i < nitems; i++)
+ {
+ if ((typelib= items[i]->get_typelib()))
+ break;
+ }
+ DBUG_ASSERT(typelib); // There must be at least one typelib
+ func->set_typelib(typelib);
+ return func->aggregate_attributes_string(func_name, items, nitems);
}
bool Type_handler_blob_common::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
- if (func->aggregate_attributes_string(func->func_name(), items, nitems))
+ if (func->aggregate_attributes_string(func_name, items, nitems))
return true;
- func->set_handler(blob_type_handler(func->max_length));
+ handler->set_handler(blob_type_handler(func->max_length));
return false;
}
bool Type_handler_date_common::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
func->fix_attributes_date();
@@ -2146,7 +2637,10 @@ bool Type_handler_date_common::
bool Type_handler_time_common::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
func->aggregate_attributes_temporal(MIN_TIME_WIDTH, items, nitems);
@@ -2155,7 +2649,10 @@ bool Type_handler_time_common::
bool Type_handler_datetime_common::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
func->aggregate_attributes_temporal(MAX_DATETIME_WIDTH, items, nitems);
@@ -2164,7 +2661,10 @@ bool Type_handler_datetime_common::
bool Type_handler_timestamp_common::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
func->aggregate_attributes_temporal(MAX_DATETIME_WIDTH, items, nitems);
@@ -2173,11 +2673,14 @@ bool Type_handler_timestamp_common::
#ifdef HAVE_SPATIAL
bool Type_handler_geometry::
- Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ Item_hybrid_func_fix_attributes(THD *thd,
+ const char *func_name,
+ Type_handler_hybrid_field_type *handler,
+ Type_all_attributes *func,
Item **items, uint nitems) const
{
DBUG_ASSERT(nitems > 0);
- Type_geometry_attributes gattr(items[0]);
+ Type_geometry_attributes gattr(items[0]->type_handler(), items[0]);
for (uint i= 1; i < nitems; i++)
gattr.join(items[i]);
func->set_geometry_type(gattr.get_geometry_type());
@@ -2185,7 +2688,7 @@ bool Type_handler_geometry::
func->unsigned_flag= false;
func->decimals= 0;
func->max_length= (uint32) UINT_MAX32;
- func->maybe_null= true;
+ func->set_maybe_null(true);
return false;
}
#endif
@@ -2202,7 +2705,8 @@ bool Type_handler::
with aggregating for CASE-alike functions (e.g. COALESCE)
for the majority of data type handlers.
*/
- return Item_hybrid_func_fix_attributes(thd, func, items, nitems);
+ return Item_hybrid_func_fix_attributes(thd, func->func_name(),
+ func, func, items, nitems);
}
@@ -3953,6 +4457,62 @@ uint Type_handler_temporal_result::
/***************************************************************************/
+uint Type_handler_string_result::Item_decimal_precision(const Item *item) const
+{
+ uint res= item->max_char_length();
+ /*
+ Return at least one decimal digit, even if Item::max_char_length()
+ returned 0. This is important to avoid attempts to create fields of types
+ INT(0) or DECIMAL(0,0) when converting NULL or empty strings to INT/DECIMAL:
+ CREATE TABLE t1 AS SELECT CONVERT(NULL,SIGNED) AS a;
+ */
+ return res ? MY_MIN(res, DECIMAL_MAX_PRECISION) : 1;
+}
+
+uint Type_handler_real_result::Item_decimal_precision(const Item *item) const
+{
+ uint res= item->max_char_length();
+ return res ? MY_MIN(res, DECIMAL_MAX_PRECISION) : 1;
+}
+
+uint Type_handler_decimal_result::Item_decimal_precision(const Item *item) const
+{
+ uint prec= my_decimal_length_to_precision(item->max_char_length(),
+ item->decimals,
+ item->unsigned_flag);
+ return MY_MIN(prec, DECIMAL_MAX_PRECISION);
+}
+
+uint Type_handler_int_result::Item_decimal_precision(const Item *item) const
+{
+ uint prec= my_decimal_length_to_precision(item->max_char_length(),
+ item->decimals,
+ item->unsigned_flag);
+ return MY_MIN(prec, DECIMAL_MAX_PRECISION);
+}
+
+uint Type_handler_time_common::Item_decimal_precision(const Item *item) const
+{
+ return 7 + MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
+}
+
+uint Type_handler_date_common::Item_decimal_precision(const Item *item) const
+{
+ return 8;
+}
+
+uint Type_handler_datetime_common::Item_decimal_precision(const Item *item) const
+{
+ return 14 + MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
+}
+
+uint Type_handler_timestamp_common::Item_decimal_precision(const Item *item) const
+{
+ return 14 + MY_MIN(item->decimals, TIME_SECOND_PART_DIGITS);
+}
+
+/***************************************************************************/
+
bool Type_handler_real_result::
subquery_type_allows_materialization(const Item *inner,
const Item *outer) const
@@ -4124,6 +4684,104 @@ bool Type_handler_time_common::
/***************************************************************************/
+bool Type_handler_row::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ DBUG_ASSERT(0);
+ param->set_null();
+ return true;
+}
+
+
+bool Type_handler_real_result::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ param->unsigned_flag= attr->unsigned_flag;
+ param->set_double(val->value.m_double);
+ param->set_handler(&type_handler_double);
+ return false;
+}
+
+
+bool Type_handler_int_result::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ param->unsigned_flag= attr->unsigned_flag;
+ param->set_int(val->value.m_longlong, MY_INT64_NUM_DECIMAL_DIGITS);
+ param->set_handler(&type_handler_longlong);
+ return false;
+}
+
+
+bool Type_handler_decimal_result::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ param->unsigned_flag= attr->unsigned_flag;
+ param->set_decimal(&val->m_decimal, attr->unsigned_flag);
+ param->set_handler(&type_handler_newdecimal);
+ return false;
+}
+
+
+bool Type_handler_string_result::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ param->unsigned_flag= false;
+ param->value.cs_info.set(thd, attr->collation.collation);
+ /*
+ Exact value of max_length is not known unless data is converted to
+ charset of connection, so we have to set it later.
+ */
+ param->set_handler(&type_handler_varchar);
+ return param->set_str(val->m_string.ptr(), val->m_string.length());
+}
+
+
+bool Type_handler_temporal_result::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ param->unsigned_flag= attr->unsigned_flag;
+ param->set_time(&val->value.m_time, attr->max_length, attr->decimals);
+ param->set_handler(this);
+ return false;
+}
+
+
+#ifdef HAVE_SPATIAL
+bool Type_handler_geometry::
+ Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *val) const
+{
+ param->unsigned_flag= false;
+ param->value.cs_info.set(thd, &my_charset_bin);
+ param->set_handler(&type_handler_geometry);
+ param->set_geometry_type(attr->uint_geometry_type());
+ return param->set_str(val->m_string.ptr(), val->m_string.length());
+}
+#endif
+
+/***************************************************************************/
+
bool Type_handler_null::
Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
diff --git a/sql/sql_type.h b/sql/sql_type.h
index c741e2117ec..28bb2a2edc9 100644
--- a/sql/sql_type.h
+++ b/sql/sql_type.h
@@ -27,7 +27,9 @@
#include "my_time.h"
class Field;
+class Column_definition;
class Item;
+class Item_param;
class Item_cache;
class Item_func_or_sum;
class Item_sum_hybrid;
@@ -60,10 +62,12 @@ class Item_func_div;
class Item_func_mod;
class cmp_item;
class in_vector;
+class Type_handler_hybrid_field_type;
class Sort_param;
class Arg_comparator;
struct st_value;
class Protocol;
+class handler;
struct TABLE;
struct SORT_FIELD_ATTR;
@@ -467,6 +471,7 @@ public:
:Type_std_attributes(other)
{ }
virtual ~Type_all_attributes() {}
+ virtual void set_maybe_null(bool maybe_null_arg)= 0;
// Returns total number of decimal digits
virtual uint decimal_precision() const= 0;
/*
@@ -476,7 +481,9 @@ public:
datatype indepented method.
*/
virtual uint uint_geometry_type() const= 0;
- virtual TYPELIB *get_typelib() const { return NULL; }
+ virtual void set_geometry_type(uint type)= 0;
+ virtual TYPELIB *get_typelib() const= 0;
+ virtual void set_typelib(TYPELIB *typelib)= 0;
};
@@ -543,6 +550,15 @@ protected:
bool Item_send_time(Item *item, Protocol *protocol, st_value *buf) const;
bool Item_send_date(Item *item, Protocol *protocol, st_value *buf) const;
bool Item_send_datetime(Item *item, Protocol *protocol, st_value *buf) const;
+ bool Column_definition_prepare_stage2_legacy(Column_definition *c,
+ enum_field_types type)
+ const;
+ bool Column_definition_prepare_stage2_legacy_num(Column_definition *c,
+ enum_field_types type)
+ const;
+ bool Column_definition_prepare_stage2_legacy_real(Column_definition *c,
+ enum_field_types type)
+ const;
public:
static const Type_handler *blob_type_handler(uint max_octet_length);
static const Type_handler *string_type_handler(uint max_octet_length);
@@ -598,6 +614,10 @@ public:
{
return false;
}
+ virtual bool type_can_have_auto_increment_attribute() const
+ {
+ return false;
+ }
/**
Prepared statement long data:
Check whether this parameter data type is compatible with long data.
@@ -639,6 +659,7 @@ public:
virtual uint Item_time_precision(Item *item) const;
virtual uint Item_datetime_precision(Item *item) const;
virtual uint Item_decimal_scale(const Item *item) const;
+ virtual uint Item_decimal_precision(const Item *item) const= 0;
/*
Returns how many digits a divisor adds into a division result.
See Item::divisor_precision_increment() in item.h for more comments.
@@ -680,6 +701,15 @@ public:
virtual Field *make_conversion_table_field(TABLE *TABLE,
uint metadata,
const Field *target) const= 0;
+ virtual bool Column_definition_fix_attributes(Column_definition *c) const= 0;
+ virtual bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+ virtual bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const= 0;
virtual Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -696,7 +726,12 @@ public:
SORT_FIELD_ATTR *attr) const= 0;
virtual uint32 max_display_length(const Item *item) const= 0;
+ virtual uint32 calc_pack_length(uint32 length) const= 0;
virtual bool Item_save_in_value(Item *item, st_value *value) const= 0;
+ virtual bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const= 0;
virtual bool Item_send(Item *item, Protocol *p, st_value *buf) const= 0;
virtual int Item_save_in_field(Item *item, Field *field,
bool no_conversions) const= 0;
@@ -768,7 +803,10 @@ public:
const Item *cmp) const= 0;
virtual Item_cache *Item_get_cache(THD *thd, const Item *item) const= 0;
virtual bool set_comparator_func(Arg_comparator *cmp) const= 0;
- virtual bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ virtual bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items,
uint nitems) const= 0;
virtual bool Item_func_min_max_fix_attributes(THD *thd,
@@ -911,6 +949,27 @@ public:
DBUG_ASSERT(0);
return NULL;
}
+ bool Column_definition_fix_attributes(Column_definition *c) const
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ {
+ DBUG_ASSERT(0);
+ return true;
+ }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -935,7 +994,21 @@ public:
DBUG_ASSERT(0);
return 0;
}
+ uint32 calc_pack_length(uint32 length) const
+ {
+ DBUG_ASSERT(0);
+ return 0;
+ }
+ uint Item_decimal_precision(const Item *item) const
+ {
+ DBUG_ASSERT(0);
+ return DECIMAL_MAX_PRECISION;
+ }
bool Item_save_in_value(Item *item, st_value *value) const;
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
DBUG_ASSERT(0);
@@ -958,7 +1031,10 @@ public:
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool set_comparator_func(Arg_comparator *cmp) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const
{
DBUG_ASSERT(0);
@@ -1156,12 +1232,20 @@ public:
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool set_comparator_func(Arg_comparator *cmp) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func,
Item **items, uint nitems) const;
@@ -1217,7 +1301,12 @@ public:
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
uint32 max_display_length(const Item *item) const;
+ uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_str(item, protocol, buf);
@@ -1226,7 +1315,10 @@ public:
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool set_comparator_func(Arg_comparator *cmp) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
@@ -1278,12 +1370,20 @@ public:
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool set_comparator_func(Arg_comparator *cmp) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
@@ -1320,6 +1420,13 @@ public:
};
+class Type_handler_general_purpose_int: public Type_handler_int_result
+{
+public:
+ bool type_can_have_auto_increment_attribute() const { return true; }
+};
+
+
class Type_handler_temporal_result: public Type_handler
{
protected:
@@ -1334,6 +1441,10 @@ public:
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
uint32 max_display_length(const Item *item) const;
bool can_change_cond_ref_to_const(Item_bool_func2 *target,
Item *target_expr, Item *target_value,
@@ -1399,6 +1510,11 @@ public:
void sortlength(THD *thd,
const Type_std_attributes *item,
SORT_FIELD_ATTR *attr) const;
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
uint32 max_display_length(const Item *item) const;
uint Item_time_precision(Item *item) const
{
@@ -1408,7 +1524,12 @@ public:
{
return Item_temporal_precision(item, false);
}
+ uint Item_decimal_precision(const Item *item) const;
bool Item_save_in_value(Item *item, st_value *value) const;
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_str(item, protocol, buf);
@@ -1427,7 +1548,10 @@ public:
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
Item_cache *Item_get_cache(THD *thd, const Item *item) const;
bool set_comparator_func(Arg_comparator *cmp) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
@@ -1491,7 +1615,7 @@ public:
*/
-class Type_handler_tiny: public Type_handler_int_result
+class Type_handler_tiny: public Type_handler_general_purpose_int
{
static const Name m_name_tiny;
public:
@@ -1499,12 +1623,18 @@ public:
const Name name() const { return m_name_tiny; }
enum_field_types field_type() const { return MYSQL_TYPE_TINY; }
uint32 max_display_length(const Item *item) const { return 4; }
+ uint32 calc_pack_length(uint32 length) const { return 1; }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_tiny(item, protocol, buf);
}
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_TINY); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1512,7 +1642,7 @@ public:
};
-class Type_handler_short: public Type_handler_int_result
+class Type_handler_short: public Type_handler_general_purpose_int
{
static const Name m_name_short;
public:
@@ -1524,8 +1654,14 @@ public:
return Item_send_short(item, protocol, buf);
}
uint32 max_display_length(const Item *item) const { return 6; }
+ uint32 calc_pack_length(uint32 length) const { return 2; }
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_SHORT); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1533,7 +1669,7 @@ public:
};
-class Type_handler_long: public Type_handler_int_result
+class Type_handler_long: public Type_handler_general_purpose_int
{
static const Name m_name_int;
public:
@@ -1544,12 +1680,18 @@ public:
{
return MY_INT32_NUM_DECIMAL_DIGITS;
}
+ uint32 calc_pack_length(uint32 length) const { return 4; }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_long(item, protocol, buf);
}
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_LONG); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1557,7 +1699,7 @@ public:
};
-class Type_handler_longlong: public Type_handler_int_result
+class Type_handler_longlong: public Type_handler_general_purpose_int
{
static const Name m_name_longlong;
public:
@@ -1565,12 +1707,20 @@ public:
const Name name() const { return m_name_longlong; }
enum_field_types field_type() const { return MYSQL_TYPE_LONGLONG; }
uint32 max_display_length(const Item *item) const { return 20; }
+ uint32 calc_pack_length(uint32 length) const { return 8; }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_longlong(item, protocol, buf);
}
Field *make_conversion_table_field(TABLE *TABLE, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ {
+ return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_LONGLONG);
+ }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1578,7 +1728,7 @@ public:
};
-class Type_handler_int24: public Type_handler_int_result
+class Type_handler_int24: public Type_handler_general_purpose_int
{
static const Name m_name_mediumint;
public:
@@ -1590,8 +1740,14 @@ public:
return Item_send_long(item, protocol, buf);
}
uint32 max_display_length(const Item *item) const { return 8; }
+ uint32 calc_pack_length(uint32 length) const { return 3; }
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_INT24); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1607,12 +1763,18 @@ public:
const Name name() const { return m_name_year; }
enum_field_types field_type() const { return MYSQL_TYPE_YEAR; }
uint32 max_display_length(const Item *item) const;
+ uint32 calc_pack_length(uint32 length) const { return 1; }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_short(item, protocol, buf);
}
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_YEAR); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1628,6 +1790,7 @@ public:
const Name name() const { return m_name_bit; }
enum_field_types field_type() const { return MYSQL_TYPE_BIT; }
uint32 max_display_length(const Item *item) const;
+ uint32 calc_pack_length(uint32 length) const { return length / 8; }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_str(item, protocol, buf);
@@ -1638,6 +1801,15 @@ public:
}
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1652,7 +1824,9 @@ public:
virtual ~Type_handler_float() {}
const Name name() const { return m_name_float; }
enum_field_types field_type() const { return MYSQL_TYPE_FLOAT; }
+ bool type_can_have_auto_increment_attribute() const { return true; }
uint32 max_display_length(const Item *item) const { return 25; }
+ uint32 calc_pack_length(uint32 length) const { return sizeof(float); }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_float(item, protocol, buf);
@@ -1660,6 +1834,11 @@ public:
Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_real(c, MYSQL_TYPE_FLOAT); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1674,13 +1853,20 @@ public:
virtual ~Type_handler_double() {}
const Name name() const { return m_name_double; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
+ bool type_can_have_auto_increment_attribute() const { return true; }
uint32 max_display_length(const Item *item) const { return 53; }
+ uint32 calc_pack_length(uint32 length) const { return sizeof(double); }
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
return Item_send_double(item, protocol, buf);
}
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_real(c, MYSQL_TYPE_DOUBLE); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1703,11 +1889,13 @@ public:
{
return Item_decimal_scale_with_seconds(item);
}
+ uint Item_decimal_precision(const Item *item) const;
uint Item_divisor_precision_increment(const Item *item) const
{
return Item_divisor_precision_increment_with_seconds(item);
}
const Type_handler *type_handler_for_comparison() const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
bool Item_save_in_value(Item *item, st_value *value) const;
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const
{
@@ -1715,7 +1903,10 @@ public:
}
int Item_save_in_field(Item *item, Field *field, bool no_conversions) const;
String *print_item_value(THD *thd, Item *item, String *str) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
Item *make_const_item_for_comparison(THD *, Item *src, const Item *cmp) const;
bool set_comparator_func(Arg_comparator *cmp) const;
@@ -1726,10 +1917,18 @@ public:
class Type_handler_time: public Type_handler_time_common
{
+ /* number of bytes to store TIME(N) */
+ static uint m_hires_bytes[MAX_DATETIME_PRECISION+1];
public:
+ static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
virtual ~Type_handler_time() {}
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_TIME); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1742,8 +1941,13 @@ class Type_handler_time2: public Type_handler_time_common
public:
virtual ~Type_handler_time2() {}
enum_field_types real_field_type() const { return MYSQL_TYPE_TIME2; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_TIME2); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1780,8 +1984,13 @@ public:
{
return MYSQL_TIMESTAMP_DATE;
}
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ uint Item_decimal_precision(const Item *item) const;
String *print_item_value(THD *thd, Item *item, String *str) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
};
@@ -1789,8 +1998,13 @@ class Type_handler_date: public Type_handler_date_common
{
public:
virtual ~Type_handler_date() {}
+ uint32 calc_pack_length(uint32 length) const { return 4; }
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_DATE); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1803,8 +2017,13 @@ class Type_handler_newdate: public Type_handler_date_common
public:
virtual ~Type_handler_newdate() {}
enum_field_types real_field_type() const { return MYSQL_TYPE_NEWDATE; }
+ uint32 calc_pack_length(uint32 length) const { return 3; }
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_NEWDATE); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1824,10 +2043,12 @@ public:
{
return MYSQL_TIMESTAMP_DATETIME;
}
+ bool Column_definition_fix_attributes(Column_definition *c) const;
uint Item_decimal_scale(const Item *item) const
{
return Item_decimal_scale_with_seconds(item);
}
+ uint Item_decimal_precision(const Item *item) const;
uint Item_divisor_precision_increment(const Item *item) const
{
return Item_divisor_precision_increment_with_seconds(item);
@@ -1837,17 +2058,28 @@ public:
return Item_send_datetime(item, protocol, buf);
}
String *print_item_value(THD *thd, Item *item, String *str) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
};
class Type_handler_datetime: public Type_handler_datetime_common
{
+ /* number of bytes to store DATETIME(N) */
+ static uint m_hires_bytes[MAX_DATETIME_PRECISION + 1];
public:
+ static uint hires_bytes(uint dec) { return m_hires_bytes[dec]; }
virtual ~Type_handler_datetime() {}
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_DATETIME); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1860,8 +2092,13 @@ class Type_handler_datetime2: public Type_handler_datetime_common
public:
virtual ~Type_handler_datetime2() {}
enum_field_types real_field_type() const { return MYSQL_TYPE_DATETIME2; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_DATETIME2); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1885,10 +2122,12 @@ public:
{
return true;
}
+ bool Column_definition_fix_attributes(Column_definition *c) const;
uint Item_decimal_scale(const Item *item) const
{
return Item_decimal_scale_with_seconds(item);
}
+ uint Item_decimal_precision(const Item *item) const;
uint Item_divisor_precision_increment(const Item *item) const
{
return Item_divisor_precision_increment_with_seconds(item);
@@ -1898,17 +2137,28 @@ public:
return Item_send_datetime(item, protocol, buf);
}
String *print_item_value(THD *thd, Item *item, String *str) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
};
class Type_handler_timestamp: public Type_handler_timestamp_common
{
+ /* number of bytes to store second_part part of the TIMESTAMP(N) */
+ static uint m_sec_part_bytes[MAX_DATETIME_PRECISION + 1];
public:
+ static uint sec_part_bytes(uint dec) { return m_sec_part_bytes[dec]; }
virtual ~Type_handler_timestamp() {}
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_TIMESTAMP); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1921,8 +2171,15 @@ class Type_handler_timestamp2: public Type_handler_timestamp_common
public:
virtual ~Type_handler_timestamp2() {}
enum_field_types real_field_type() const { return MYSQL_TYPE_TIMESTAMP2; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ {
+ return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_TIMESTAMP2);
+ }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1937,10 +2194,16 @@ public:
virtual ~Type_handler_olddecimal() {}
const Name name() const { return m_name_decimal; }
enum_field_types field_type() const { return MYSQL_TYPE_DECIMAL; }
+ uint32 calc_pack_length(uint32 length) const { return length; }
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
const Type_handler *type_handler_for_union(const Item *item) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_DECIMAL); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1955,8 +2218,18 @@ public:
virtual ~Type_handler_newdecimal() {}
const Name name() const { return m_name_decimal; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -1975,10 +2248,21 @@ public:
const Type_handler *type_handler_for_tmp_table(const Item *item) const;
const Type_handler *type_handler_for_union(const Item *) const;
uint32 max_display_length(const Item *item) const { return 0; }
+ uint32 calc_pack_length(uint32 length) const { return 0; }
bool Item_save_in_value(Item *item, st_value *value) const;
bool Item_send(Item *item, Protocol *protocol, st_value *buf) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy(c, MYSQL_TYPE_NULL); }
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2004,12 +2288,17 @@ public:
const Name name() const { return m_name_char; }
enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
bool is_param_long_data_type() const { return true; }
+ uint32 calc_pack_length(uint32 length) const { return length; }
const Type_handler *type_handler_for_tmp_table(const Item *item) const
{
return varstring_type_handler(item);
}
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2030,6 +2319,11 @@ public:
{
return varstring_type_handler(item);
}
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const
+ { return Column_definition_prepare_stage2_legacy_num(c, MYSQL_TYPE_STRING); }
const Type_handler *type_handler_for_union(const Item *item) const
{
return varstring_type_handler(item);
@@ -2044,6 +2338,10 @@ public:
virtual ~Type_handler_varchar() {}
const Name name() const { return m_name_varchar; }
enum_field_types field_type() const { return MYSQL_TYPE_VARCHAR; }
+ uint32 calc_pack_length(uint32 length) const
+ {
+ return (length + (length < 256 ? 1: 2));
+ }
const Type_handler *type_handler_for_tmp_table(const Item *item) const
{
return varstring_type_handler(item);
@@ -2055,6 +2353,10 @@ public:
bool is_param_long_data_type() const { return true; }
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2080,7 +2382,14 @@ public:
return false; // Materialization does not work with BLOB columns
}
bool is_param_long_data_type() const { return true; }
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
Item **items, uint nitems) const;
};
@@ -2092,6 +2401,7 @@ public:
virtual ~Type_handler_tiny_blob() {}
const Name name() const { return m_name_tinyblob; }
enum_field_types field_type() const { return MYSQL_TYPE_TINY_BLOB; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
@@ -2108,6 +2418,7 @@ public:
virtual ~Type_handler_medium_blob() {}
const Name name() const { return m_name_mediumblob; }
enum_field_types field_type() const { return MYSQL_TYPE_MEDIUM_BLOB; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
@@ -2124,6 +2435,7 @@ public:
virtual ~Type_handler_long_blob() {}
const Name name() const { return m_name_longblob; }
enum_field_types field_type() const { return MYSQL_TYPE_LONG_BLOB; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
@@ -2140,6 +2452,7 @@ public:
virtual ~Type_handler_blob() {}
const Name name() const { return m_name_blob; }
enum_field_types field_type() const { return MYSQL_TYPE_BLOB; }
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
Field *make_table_field(const LEX_CSTRING *name,
@@ -2158,6 +2471,7 @@ public:
const Name name() const { return m_name_geometry; }
enum_field_types field_type() const { return MYSQL_TYPE_GEOMETRY; }
bool is_param_long_data_type() const { return true; }
+ uint32 calc_pack_length(uint32 length) const;
const Type_handler *type_handler_for_comparison() const;
bool type_can_have_key_part() const
{
@@ -2168,8 +2482,21 @@ public:
{
return false; // Materialization does not work with GEOMETRY columns
}
+ bool Item_param_set_from_value(THD *thd,
+ Item_param *param,
+ const Type_all_attributes *attr,
+ const st_value *value) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2183,7 +2510,10 @@ public:
bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *) const;
bool Item_func_abs_fix_length_and_dec(Item_func_abs *) const;
bool Item_func_neg_fix_length_and_dec(Item_func_neg *) const;
- bool Item_hybrid_func_fix_attributes(THD *thd, Item_hybrid_func *func,
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *h,
+ Type_all_attributes *attr,
Item **items, uint nitems) const;
bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *) const;
bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *) const;
@@ -2203,18 +2533,40 @@ extern MYSQL_PLUGIN_IMPORT Type_handler_geometry type_handler_geometry;
#endif
-class Type_handler_enum: public Type_handler_string_result
+class Type_handler_typelib: public Type_handler_string_result
+{
+public:
+ virtual ~Type_handler_typelib() { }
+ enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
+ const Type_handler *type_handler_for_item_field() const;
+ const Type_handler *cast_to_int_type_handler() const;
+ bool Item_hybrid_func_fix_attributes(THD *thd,
+ const char *name,
+ Type_handler_hybrid_field_type *,
+ Type_all_attributes *atrr,
+ Item **items, uint nitems) const;
+ bool Column_definition_prepare_stage1(THD *thd,
+ MEM_ROOT *mem_root,
+ Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
+};
+
+
+class Type_handler_enum: public Type_handler_typelib
{
static const Name m_name_enum;
public:
virtual ~Type_handler_enum() {}
const Name name() const { return m_name_enum; }
- enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_ENUM; }
- const Type_handler *type_handler_for_item_field() const;
- const Type_handler *cast_to_int_type_handler() const;
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
@@ -2222,18 +2574,20 @@ public:
};
-class Type_handler_set: public Type_handler_string_result
+class Type_handler_set: public Type_handler_typelib
{
static const Name m_name_set;
public:
virtual ~Type_handler_set() {}
const Name name() const { return m_name_set; }
- enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
virtual enum_field_types real_field_type() const { return MYSQL_TYPE_SET; }
- const Type_handler *type_handler_for_item_field() const;
- const Type_handler *cast_to_int_type_handler() const;
+ uint32 calc_pack_length(uint32 length) const;
Field *make_conversion_table_field(TABLE *, uint metadata,
const Field *target) const;
+ bool Column_definition_fix_attributes(Column_definition *c) const;
+ bool Column_definition_prepare_stage2(Column_definition *c,
+ handler *file,
+ ulonglong table_flags) const;
Field *make_table_field(const LEX_CSTRING *name,
const Record_addr &addr,
const Type_all_attributes &attr,
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index bf25c0be74e..1c2ff2b012b 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -692,6 +692,179 @@ bool st_select_lex_unit::prepare_join(THD *thd_arg, SELECT_LEX *sl,
}
+class Type_holder: public Sql_alloc,
+ public Item_args,
+ public Type_handler_hybrid_field_type,
+ public Type_all_attributes,
+ public Type_geometry_attributes
+{
+ TYPELIB *m_typelib;
+ bool m_maybe_null;
+public:
+ Type_holder()
+ :m_typelib(NULL),
+ m_maybe_null(false)
+ { }
+
+ void set_maybe_null(bool maybe_null_arg) { m_maybe_null= maybe_null_arg; }
+ bool get_maybe_null() const { return m_maybe_null; }
+
+ uint decimal_precision() const
+ {
+ /*
+ Type_holder is not used directly to create fields, so
+ its virtual decimal_precision() is never called.
+ We should eventually extend create_result_table() to accept
+ an array of Type_holders directly, without having to allocate
+ Item_type_holder's and put them into List<Item>.
+ */
+ DBUG_ASSERT(0);
+ return 0;
+ }
+ void set_geometry_type(uint type)
+ {
+ Type_geometry_attributes::set_geometry_type(type);
+ }
+ uint uint_geometry_type() const
+ {
+ return Type_geometry_attributes::get_geometry_type();
+ }
+ void set_typelib(TYPELIB *typelib)
+ {
+ m_typelib= typelib;
+ }
+ TYPELIB *get_typelib() const
+ {
+ return m_typelib;
+ }
+
+ bool aggregate_attributes(THD *thd)
+ {
+ for (uint i= 0; i < arg_count; i++)
+ m_maybe_null|= args[i]->maybe_null;
+ return
+ type_handler()->Item_hybrid_func_fix_attributes(thd,
+ "UNION", this, this,
+ args, arg_count);
+ }
+};
+
+
+/**
+ Aggregate data type handlers for the "count" leftmost UNION parts.
+*/
+bool st_select_lex_unit::join_union_type_handlers(THD *thd_arg,
+ Type_holder *holders,
+ uint count)
+{
+ DBUG_ENTER("st_select_lex_unit::join_union_type_handlers");
+ SELECT_LEX *first_sl= first_select(), *sl= first_sl;
+ for (uint i= 0; i < count ; sl= sl->next_select(), i++)
+ {
+ Item *item;
+ List_iterator_fast<Item> it(sl->item_list);
+ for (uint pos= 0; (item= it++); pos++)
+ {
+ const Type_handler *item_type_handler= item->real_type_handler();
+ if (sl == first_sl)
+ holders[pos].set_handler(item_type_handler);
+ else
+ {
+ if (first_sl->item_list.elements != sl->item_list.elements)
+ {
+ my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
+ ER_THD(thd_arg, ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),
+ MYF(0));
+ DBUG_RETURN(true);
+ }
+ if (holders[pos].aggregate_for_result(item_type_handler))
+ {
+ my_error(ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION, MYF(0),
+ holders[pos].type_handler()->name().ptr(),
+ item_type_handler->name().ptr(),
+ "UNION");
+ DBUG_RETURN(true);
+ }
+ }
+ }
+ }
+ DBUG_RETURN(false);
+}
+
+
+/**
+ Aggregate data type attributes for the "count" leftmost UNION parts.
+*/
+bool st_select_lex_unit::join_union_type_attributes(THD *thd_arg,
+ Type_holder *holders,
+ uint count)
+{
+ DBUG_ENTER("st_select_lex_unit::join_union_type_attributes");
+ SELECT_LEX *sl, *first_sl= first_select();
+ uint item_pos;
+ for (uint pos= 0; pos < first_sl->item_list.elements; pos++)
+ {
+ if (holders[pos].alloc_arguments(thd_arg, count))
+ DBUG_RETURN(true);
+ }
+ for (item_pos= 0, sl= first_sl ;
+ item_pos < count;
+ sl= sl->next_select(), item_pos++)
+ {
+ Item *item_tmp;
+ List_iterator_fast<Item> itx(sl->item_list);
+ for (uint holder_pos= 0 ; (item_tmp= itx++); holder_pos++)
+ {
+ DBUG_ASSERT(item_tmp->fixed);
+ holders[holder_pos].add_argument(item_tmp);
+ }
+ }
+ for (uint pos= 0; pos < first_sl->item_list.elements; pos++)
+ {
+ if (holders[pos].aggregate_attributes(thd_arg))
+ DBUG_RETURN(true);
+ }
+ DBUG_RETURN(false);
+}
+
+
+/**
+ Join data types for the leftmost "count" UNION parts
+ and store corresponding Item_type_holder's into "types".
+*/
+bool st_select_lex_unit::join_union_item_types(THD *thd_arg,
+ List<Item> &types,
+ uint count)
+{
+ DBUG_ENTER("st_select_lex_unit::join_union_select_list_types");
+ SELECT_LEX *first_sl= first_select();
+ Type_holder *holders;
+
+ if (!(holders= new (thd_arg->mem_root)
+ Type_holder[first_sl->item_list.elements]) ||
+ join_union_type_handlers(thd_arg, holders, count) ||
+ join_union_type_attributes(thd_arg, holders, count))
+ DBUG_RETURN(true);
+
+ types.empty();
+ List_iterator_fast<Item> it(first_sl->item_list);
+ Item *item_tmp;
+ for (uint pos= 0; (item_tmp= it++); pos++)
+ {
+ /* Error's in 'new' will be detected after loop */
+ types.push_back(new (thd_arg->mem_root)
+ Item_type_holder(thd_arg,
+ &item_tmp->name,
+ holders[pos].type_handler(),
+ &holders[pos]/*Type_all_attributes*/,
+ holders[pos].get_maybe_null()));
+ }
+ if (thd_arg->is_fatal_error)
+ DBUG_RETURN(true); // out of memory
+ DBUG_RETURN(false);
+}
+
+
bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
ulong additional_options)
{
@@ -699,6 +872,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
SELECT_LEX *sl, *first_sl= first_select();
bool is_recursive= with_element && with_element->is_recursive;
bool is_rec_result_table_created= false;
+ uint union_part_count= 0;
select_result *tmp_result;
bool is_union_select;
bool have_except= FALSE, have_intersect= FALSE;
@@ -811,7 +985,7 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
goto cont;
}
- for (;sl; sl= sl->next_select())
+ for (;sl; sl= sl->next_select(), union_part_count++)
{
if (prepare_join(thd_arg, sl, tmp_result, additional_options,
is_union_select))
@@ -834,43 +1008,10 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
if (is_recursive)
{
if (derived->with->rename_columns_of_derived_unit(thd, this))
- goto err;
+ goto err;
if (check_duplicate_names(thd, sl->item_list, 0))
goto err;
}
- types.empty();
- List_iterator_fast<Item> it(sl->item_list);
- Item *item_tmp;
- while ((item_tmp= it++))
- {
- /* Error's in 'new' will be detected after loop */
- types.push_back(new (thd_arg->mem_root)
- Item_type_holder(thd_arg, item_tmp));
- }
-
- if (thd_arg->is_fatal_error)
- goto err; // out of memory
- }
- else
- {
- if (types.elements != sl->item_list.elements)
- {
- my_message(ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT,
- ER_THD(thd, ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT),MYF(0));
- goto err;
- }
- if (!is_rec_result_table_created)
- {
- List_iterator_fast<Item> it(sl->item_list);
- List_iterator_fast<Item> tp(types);
- Item *type, *item_tmp;
- while ((type= tp++, item_tmp= it++))
- {
- DBUG_ASSERT(item_tmp->fixed);
- if (((Item_type_holder*)type)->join_types(thd_arg, item_tmp))
- DBUG_RETURN(TRUE);
- }
- }
}
if (is_recursive)
{
@@ -883,6 +1024,9 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
ulonglong create_options;
create_options= (first_sl->options | thd_arg->variables.option_bits |
TMP_TABLE_ALL_COLUMNS);
+ // Join data types for all non-recursive parts of a recursive UNION
+ if (join_union_item_types(thd, types, union_part_count + 1))
+ goto err;
if (union_result->create_result_table(thd, &types,
MY_TEST(union_distinct),
create_options, derived->alias,
@@ -898,6 +1042,9 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
}
}
}
+ // In case of a non-recursive UNION, join data types for all UNION parts.
+ if (!is_recursive && join_union_item_types(thd, types, union_part_count))
+ goto err;
cont:
/*
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index 1a563145945..f7d6861fecc 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -782,6 +782,7 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
Create_field *create_field;
Spvar_definition *spvar_definition;
Row_definition_list *spvar_definition_list;
+ const Type_handler *type_handler;
CHARSET_INFO *charset;
Condition_information_item *cond_info_item;
DYNCALL_CREATE_DEF *dyncol_def;
@@ -836,7 +837,6 @@ Virtual_column_info *add_virtual_expression(THD *thd, Item *expr)
enum Item_udftype udf_type;
enum Key::Keytype key_type;
enum Statement_information_item::Name stmt_info_item_name;
- enum enum_field_types field_type;
enum enum_filetype filetype;
enum enum_tx_isolation tx_isolation;
enum enum_var_type var_type;
@@ -1387,6 +1387,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token REPLICATION
%token REQUIRE_SYM
%token RESET_SYM
+%token RESTART_SYM
%token RESIGNAL_SYM /* SQL-2003-R */
%token RESOURCES
%token RESTORE_SYM
@@ -1428,6 +1429,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SERVER_SYM
%token SERVER_OPTIONS
%token SET /* SQL-2003-R */
+%token SETVAL_SYM /* PostgreSQL sequence function */
%token SET_VAR
%token SHARE_SYM
%token SHIFT_LEFT /* OPERATOR */
@@ -1644,7 +1646,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <string>
text_string hex_or_bin_String opt_gconcat_separator
-%type <field_type> int_type real_type
+%type <type_handler> int_type real_type
%type <Lex_field_type> type_with_opt_collate field_type
field_type_numeric
@@ -1700,7 +1702,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
ws_nweights
ws_level_flag_desc ws_level_flag_reverse ws_level_flags
opt_ws_levels ws_level_list ws_level_list_item ws_level_number
- ws_level_range ws_level_list_or_range
+ ws_level_range ws_level_list_or_range bool
%type <ulonglong_number>
ulonglong_num real_ulonglong_num size_number
@@ -2633,14 +2635,15 @@ sequence_def:
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| NOMINVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| MAXVALUE_SYM opt_equal longlong_num
-
{
Lex->create_info.seq_create_info->max_value= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
@@ -2649,11 +2652,13 @@ sequence_def:
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| NOMAXVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| START_SYM opt_with longlong_num
{
@@ -2663,22 +2668,46 @@ sequence_def:
| INCREMENT_SYM opt_by longlong_num
{
Lex->create_info.seq_create_info->increment= $3;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment;
}
| CACHE_SYM opt_equal longlong_num
{
Lex->create_info.seq_create_info->cache= $3;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| NOCACHE_SYM
{
Lex->create_info.seq_create_info->cache= 0;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| CYCLE_SYM
{
Lex->create_info.seq_create_info->cycle= 1;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
}
| NOCYCLE_SYM
{
Lex->create_info.seq_create_info->cycle= 0;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
+ }
+ | RESTART_SYM
+ {
+ if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
+ YYABORT;
+ }
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart;
+ }
+ | RESTART_SYM opt_with longlong_num
+ {
+ if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
+ YYABORT;
+ }
+ Lex->create_info.seq_create_info->restart= $3;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value;
}
;
@@ -6268,7 +6297,7 @@ field_type_numeric:
| real_type opt_precision field_options { $$.set($1, $2); }
| FLOAT_SYM float_options field_options
{
- $$.set(MYSQL_TYPE_FLOAT, $2);
+ $$.set(&type_handler_float, $2);
if ($2.length() && !$2.dec())
{
int err;
@@ -6277,60 +6306,60 @@ field_type_numeric:
my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0),
Lex->last_field->field_name.str));
if (tmp_length > PRECISION_FOR_FLOAT)
- $$.set(MYSQL_TYPE_DOUBLE);
+ $$.set(&type_handler_double);
else
- $$.set(MYSQL_TYPE_FLOAT);
+ $$.set(&type_handler_float);
}
}
| BIT_SYM opt_field_length_default_1
{
- $$.set(MYSQL_TYPE_BIT, $2);
+ $$.set(&type_handler_bit, $2);
}
| BOOL_SYM
{
- $$.set(MYSQL_TYPE_TINY, "1");
+ $$.set(&type_handler_tiny, "1");
}
| BOOLEAN_SYM
{
- $$.set(MYSQL_TYPE_TINY, "1");
+ $$.set(&type_handler_tiny, "1");
}
| DECIMAL_SYM float_options field_options
- { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
+ { $$.set(&type_handler_newdecimal, $2);}
| NUMERIC_SYM float_options field_options
- { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
+ { $$.set(&type_handler_newdecimal, $2);}
| FIXED_SYM float_options field_options
- { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
+ { $$.set(&type_handler_newdecimal, $2);}
;
field_type_string:
char opt_field_length_default_1 opt_binary
{
- $$.set(MYSQL_TYPE_STRING, $2);
+ $$.set(&type_handler_string, $2);
}
| nchar opt_field_length_default_1 opt_bin_mod
{
- $$.set(MYSQL_TYPE_STRING, $2);
+ $$.set(&type_handler_string, $2);
bincmp_collation(national_charset_info, $3);
}
| BINARY opt_field_length_default_1
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_STRING, $2);
+ $$.set(&type_handler_string, $2);
}
| varchar field_length opt_binary
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| nvarchar field_length opt_bin_mod
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
bincmp_collation(national_charset_info, $3);
}
| VARBINARY field_length
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
;
@@ -6351,18 +6380,23 @@ field_type_temporal:
buff, "YEAR(4)");
}
}
- $$.set(MYSQL_TYPE_YEAR, $2);
+ $$.set(&type_handler_year, $2);
}
- | DATE_SYM
- { $$.set(MYSQL_TYPE_DATE); }
+ | DATE_SYM { $$.set(thd->type_handler_for_date()); }
| TIME_SYM opt_field_length
- { $$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); }
+ {
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_time2) :
+ static_cast<const Type_handler*>(&type_handler_time),
+ $2);
+ }
| TIMESTAMP opt_field_length
{
if (thd->variables.sql_mode & MODE_MAXDB)
$$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2);
+ static_cast<const Type_handler*>(&type_handler_datetime2) :
+ static_cast<const Type_handler*>(&type_handler_datetime),
+ $2);
else
{
/*
@@ -6371,13 +6405,19 @@ field_type_temporal:
*/
if (!opt_explicit_defaults_for_timestamp)
Lex->last_field->flags|= NOT_NULL_FLAG;
- $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2
- : MYSQL_TYPE_TIMESTAMP, $2);
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_timestamp2):
+ static_cast<const Type_handler*>(&type_handler_timestamp),
+ $2);
}
}
| DATETIME opt_field_length
- { $$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); }
+ {
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_datetime2) :
+ static_cast<const Type_handler*>(&type_handler_datetime),
+ $2);
+ }
;
@@ -6385,19 +6425,19 @@ field_type_lob:
TINYBLOB
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_TINY_BLOB);
+ $$.set(&type_handler_tiny_blob);
}
| BLOB_SYM opt_field_length
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_BLOB, $2);
+ $$.set(&type_handler_blob, $2);
}
| spatial_type float_options srid_option
{
#ifdef HAVE_SPATIAL
Lex->charset=&my_charset_bin;
Lex->last_field->geom_type= $1;
- $$.set(MYSQL_TYPE_GEOMETRY, $2);
+ $$.set(&type_handler_geometry, $2);
#else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define));
@@ -6406,38 +6446,38 @@ field_type_lob:
| MEDIUMBLOB
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_MEDIUM_BLOB);
+ $$.set(&type_handler_medium_blob);
}
| LONGBLOB
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_LONG_BLOB);
+ $$.set(&type_handler_long_blob);
}
| LONG_SYM VARBINARY
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_MEDIUM_BLOB);
+ $$.set(&type_handler_medium_blob);
}
| LONG_SYM varchar opt_binary
- { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ { $$.set(&type_handler_medium_blob); }
| TINYTEXT opt_binary
- { $$.set(MYSQL_TYPE_TINY_BLOB); }
+ { $$.set(&type_handler_tiny_blob); }
| TEXT_SYM opt_field_length opt_binary
- { $$.set(MYSQL_TYPE_BLOB, $2); }
+ { $$.set(&type_handler_blob, $2); }
| MEDIUMTEXT opt_binary
- { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ { $$.set(&type_handler_medium_blob); }
| LONGTEXT opt_binary
- { $$.set(MYSQL_TYPE_LONG_BLOB); }
+ { $$.set(&type_handler_long_blob); }
| LONG_SYM opt_binary
- { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ { $$.set(&type_handler_medium_blob); }
;
field_type_misc:
ENUM '(' string_list ')' opt_binary
- { $$.set(MYSQL_TYPE_ENUM); }
+ { $$.set(&type_handler_enum); }
| SET '(' string_list ')' opt_binary
- { $$.set(MYSQL_TYPE_SET); }
+ { $$.set(&type_handler_set); }
;
spatial_type:
@@ -6474,23 +6514,22 @@ nvarchar:
;
int_type:
- INT_SYM { $$=MYSQL_TYPE_LONG; }
- | TINYINT { $$=MYSQL_TYPE_TINY; }
- | SMALLINT { $$=MYSQL_TYPE_SHORT; }
- | MEDIUMINT { $$=MYSQL_TYPE_INT24; }
- | BIGINT { $$=MYSQL_TYPE_LONGLONG; }
+ INT_SYM { $$= &type_handler_long; }
+ | TINYINT { $$= &type_handler_tiny; }
+ | SMALLINT { $$= &type_handler_short; }
+ | MEDIUMINT { $$= &type_handler_int24; }
+ | BIGINT { $$= &type_handler_longlong; }
;
real_type:
REAL
{
$$= thd->variables.sql_mode & MODE_REAL_AS_FLOAT ?
- MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE;
+ static_cast<const Type_handler *>(&type_handler_float) :
+ static_cast<const Type_handler *>(&type_handler_double);
}
- | DOUBLE_SYM
- { $$=MYSQL_TYPE_DOUBLE; }
- | DOUBLE_SYM PRECISION
- { $$=MYSQL_TYPE_DOUBLE; }
+ | DOUBLE_SYM { $$= &type_handler_double; }
+ | DOUBLE_SYM PRECISION { $$= &type_handler_double; }
;
srid_option:
@@ -7277,6 +7316,33 @@ alter:
Lex->create_info.set($2);
Lex->sql_command= SQLCOM_ALTER_USER;
}
+ | ALTER SEQUENCE_SYM opt_if_exists_table_element
+ {
+ LEX *lex= Lex;
+ lex->name= null_clex_str;
+ lex->table_type= TABLE_TYPE_UNKNOWN;
+ lex->sql_command= SQLCOM_ALTER_SEQUENCE;
+ lex->create_info.init();
+ lex->no_write_to_binlog= 0;
+ DBUG_ASSERT(!lex->m_sql_cmd);
+ }
+ table_ident
+ {
+ LEX *lex= Lex;
+ if (!(lex->create_info.seq_create_info= new (thd->mem_root)
+ sequence_definition()) ||
+ !lex->select_lex.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_SEQUENCE,
+ TL_WRITE, MDL_EXCLUSIVE))
+ MYSQL_YYABORT;
+ }
+ sequence_defs
+ {
+ /* Create a generic ALTER SEQUENCE statment. */
+ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence();
+ if (Lex->m_sql_cmd == NULL)
+ MYSQL_YYABORT;
+ }
;
ev_alter_on_schedule_completion:
@@ -9409,6 +9475,21 @@ column_default_non_parenthesized_expr:
if (!($$= Lex->create_item_func_lastval(thd, $3)))
MYSQL_YYABORT;
}
+ | SETVAL_SYM '(' table_ident ',' longlong_num ')'
+ {
+ if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1)))
+ MYSQL_YYABORT;
+ }
+ | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ')'
+ {
+ if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7)))
+ MYSQL_YYABORT;
+ }
+ | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ',' ulonglong_num ')'
+ {
+ if (!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7)))
+ MYSQL_YYABORT;
+ }
;
simple_expr:
@@ -11954,6 +12035,12 @@ choice:
| DEFAULT { $$= HA_CHOICE_UNDEF; }
;
+bool:
+ ulong_num { $$= $1 != 0; }
+ | TRUE_SYM { $$= 1; }
+ | FALSE_SYM { $$= 0; }
+
+
procedure_clause:
PROCEDURE_SYM ident /* Procedure name */
{
@@ -14789,6 +14876,7 @@ keyword_sp_not_data_type:
| REPEATABLE_SYM {}
| REPLICATION {}
| RESOURCES {}
+ | RESTART_SYM {}
| RESUME_SYM {}
| RETURNED_SQLSTATE_SYM {}
| RETURNS_SYM {}
@@ -14808,6 +14896,7 @@ keyword_sp_not_data_type:
| SEQUENCE_SYM {}
| SERIALIZABLE_SYM {}
| SESSION_SYM {}
+ | SETVAL_SYM {}
| SIMPLE_SYM {}
| SHARE_SYM {}
| SLAVE_POS_SYM {}
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index a262dc8f0c2..89fd9b223f5 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -191,6 +191,7 @@ void ORAerror(THD *thd, const char *s)
Create_field *create_field;
Spvar_definition *spvar_definition;
Row_definition_list *spvar_definition_list;
+ const Type_handler *type_handler;
CHARSET_INFO *charset;
Condition_information_item *cond_info_item;
DYNCALL_CREATE_DEF *dyncol_def;
@@ -245,7 +246,6 @@ void ORAerror(THD *thd, const char *s)
enum Item_udftype udf_type;
enum Key::Keytype key_type;
enum Statement_information_item::Name stmt_info_item_name;
- enum enum_field_types field_type;
enum enum_filetype filetype;
enum enum_tx_isolation tx_isolation;
enum enum_var_type var_type;
@@ -796,6 +796,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token REPLICATION
%token REQUIRE_SYM
%token RESET_SYM
+%token RESTART_SYM
%token RESIGNAL_SYM /* SQL-2003-R */
%token RESOURCES
%token RESTORE_SYM
@@ -837,6 +838,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%token SERVER_SYM
%token SERVER_OPTIONS
%token SET /* SQL-2003-R */
+%token SETVAL_SYM /* PostgreSQL sequence function */
%token SET_VAR
%token SHARE_SYM
%token SHIFT_LEFT /* OPERATOR */
@@ -1058,7 +1060,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
%type <string>
text_string hex_or_bin_String opt_gconcat_separator
-%type <field_type> int_type real_type
+%type <type_handler> int_type real_type
%type <Lex_field_type> type_with_opt_collate field_type
sp_param_type_with_opt_collate
@@ -1118,7 +1120,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize);
ws_nweights
ws_level_flag_desc ws_level_flag_reverse ws_level_flags
opt_ws_levels ws_level_list ws_level_list_item ws_level_number
- ws_level_range ws_level_list_or_range
+ ws_level_range ws_level_list_or_range bool
%type <ulonglong_number>
ulonglong_num real_ulonglong_num size_number
@@ -2074,14 +2076,15 @@ sequence_def:
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| NOMINVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_min_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_min_value;
}
| MAXVALUE_SYM opt_equal longlong_num
-
{
Lex->create_info.seq_create_info->max_value= $3;
Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
@@ -2090,11 +2093,13 @@ sequence_def:
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| NOMAXVALUE_SYM
{
if (Lex->create_info.seq_create_info->used_fields & seq_field_used_max_value)
MYSQL_YYABORT;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_max_value;
}
| START_SYM opt_with longlong_num
{
@@ -2104,22 +2109,46 @@ sequence_def:
| INCREMENT_SYM opt_by longlong_num
{
Lex->create_info.seq_create_info->increment= $3;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_increment;
}
| CACHE_SYM opt_equal longlong_num
{
Lex->create_info.seq_create_info->cache= $3;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| NOCACHE_SYM
{
Lex->create_info.seq_create_info->cache= 0;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cache;
}
| CYCLE_SYM
{
Lex->create_info.seq_create_info->cycle= 1;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
}
| NOCYCLE_SYM
{
Lex->create_info.seq_create_info->cycle= 0;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_cycle;
+ }
+ | RESTART_SYM
+ {
+ if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
+ YYABORT;
+ }
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart;
+ }
+ | RESTART_SYM opt_with longlong_num
+ {
+ if (Lex->sql_command != SQLCOM_ALTER_SEQUENCE)
+ {
+ thd->parse_error(ER_SYNTAX_ERROR, "RESTART");
+ YYABORT;
+ }
+ Lex->create_info.seq_create_info->restart= $3;
+ Lex->create_info.seq_create_info->used_fields|= seq_field_used_restart | seq_field_used_restart_value;
}
;
@@ -6150,7 +6179,7 @@ field_type_numeric:
| real_type opt_precision field_options { $$.set($1, $2); }
| FLOAT_SYM float_options field_options
{
- $$.set(MYSQL_TYPE_FLOAT, $2);
+ $$.set(&type_handler_float, $2);
if ($2.length() && !$2.dec())
{
int err;
@@ -6159,76 +6188,76 @@ field_type_numeric:
my_yyabort_error((ER_WRONG_FIELD_SPEC, MYF(0),
Lex->last_field->field_name.str));
if (tmp_length > PRECISION_FOR_FLOAT)
- $$.set(MYSQL_TYPE_DOUBLE);
+ $$.set(&type_handler_double);
else
- $$.set(MYSQL_TYPE_FLOAT);
+ $$.set(&type_handler_float);
}
}
| BIT_SYM opt_field_length_default_1
{
- $$.set(MYSQL_TYPE_BIT, $2);
+ $$.set(&type_handler_bit, $2);
}
| BOOL_SYM
{
- $$.set(MYSQL_TYPE_TINY, "1");
+ $$.set(&type_handler_tiny, "1");
}
| BOOLEAN_SYM
{
- $$.set(MYSQL_TYPE_TINY, "1");
+ $$.set(&type_handler_tiny, "1");
}
| DECIMAL_SYM float_options field_options
- { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
+ { $$.set(&type_handler_newdecimal, $2);}
| NUMBER_SYM float_options field_options
{
if ($2.length() != 0)
- $$.set(MYSQL_TYPE_NEWDECIMAL, $2);
+ $$.set(&type_handler_newdecimal, $2);
else
- $$.set(MYSQL_TYPE_DOUBLE);
+ $$.set(&type_handler_double);
}
| NUMERIC_SYM float_options field_options
- { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
+ { $$.set(&type_handler_newdecimal, $2);}
| FIXED_SYM float_options field_options
- { $$.set(MYSQL_TYPE_NEWDECIMAL, $2);}
+ { $$.set(&type_handler_newdecimal, $2);}
;
field_type_string:
char opt_field_length_default_1 opt_binary
{
- $$.set(MYSQL_TYPE_STRING, $2);
+ $$.set(&type_handler_string, $2);
}
| nchar opt_field_length_default_1 opt_bin_mod
{
- $$.set(MYSQL_TYPE_STRING, $2);
+ $$.set(&type_handler_string, $2);
bincmp_collation(national_charset_info, $3);
}
| BINARY opt_field_length_default_1
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_STRING, $2);
+ $$.set(&type_handler_string, $2);
}
| varchar field_length opt_binary
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| VARCHAR2 field_length opt_binary
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| nvarchar field_length opt_bin_mod
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
bincmp_collation(national_charset_info, $3);
}
| VARBINARY field_length
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| RAW field_length
{
Lex->charset= &my_charset_bin;
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
;
@@ -6236,40 +6265,40 @@ field_type_string:
sp_param_field_type_string:
char opt_field_length_default_sp_param_char opt_binary
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| nchar opt_field_length_default_sp_param_char opt_bin_mod
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
bincmp_collation(national_charset_info, $3);
}
| BINARY opt_field_length_default_sp_param_char
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| varchar opt_field_length_default_sp_param_varchar opt_binary
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| VARCHAR2 opt_field_length_default_sp_param_varchar opt_binary
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| nvarchar opt_field_length_default_sp_param_varchar opt_bin_mod
{
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
bincmp_collation(national_charset_info, $3);
}
| VARBINARY opt_field_length_default_sp_param_varchar
{
Lex->charset= &my_charset_bin;
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
| RAW opt_field_length_default_sp_param_varchar
{
Lex->charset= &my_charset_bin;
- $$.set(MYSQL_TYPE_VARCHAR, $2);
+ $$.set(&type_handler_varchar, $2);
}
;
@@ -6291,19 +6320,23 @@ field_type_temporal:
buff, "YEAR(4)");
}
}
- $$.set(MYSQL_TYPE_YEAR, $2);
+ $$.set(&type_handler_year, $2);
}
- | DATE_SYM
- { $$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, 0); }
+ | DATE_SYM { $$.set(thd->type_handler_for_date()); }
| TIME_SYM opt_field_length
- { $$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_TIME2 : MYSQL_TYPE_TIME, $2); }
+ {
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_time2) :
+ static_cast<const Type_handler*>(&type_handler_time),
+ $2);
+ }
| TIMESTAMP opt_field_length
{
if (thd->variables.sql_mode & MODE_MAXDB)
$$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2);
+ static_cast<const Type_handler*>(&type_handler_datetime2) :
+ static_cast<const Type_handler*>(&type_handler_datetime),
+ $2);
else
{
/*
@@ -6312,13 +6345,19 @@ field_type_temporal:
*/
if (!opt_explicit_defaults_for_timestamp)
Lex->last_field->flags|= NOT_NULL_FLAG;
- $$.set(opt_mysql56_temporal_format ? MYSQL_TYPE_TIMESTAMP2
- : MYSQL_TYPE_TIMESTAMP, $2);
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_timestamp2):
+ static_cast<const Type_handler*>(&type_handler_timestamp),
+ $2);
}
}
| DATETIME opt_field_length
- { $$.set(opt_mysql56_temporal_format ?
- MYSQL_TYPE_DATETIME2 : MYSQL_TYPE_DATETIME, $2); }
+ {
+ $$.set(opt_mysql56_temporal_format ?
+ static_cast<const Type_handler*>(&type_handler_datetime2) :
+ static_cast<const Type_handler*>(&type_handler_datetime),
+ $2);
+ }
;
@@ -6326,19 +6365,19 @@ field_type_lob:
TINYBLOB
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_TINY_BLOB);
+ $$.set(&type_handler_tiny_blob);
}
| BLOB_SYM opt_field_length
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_LONG_BLOB);
+ $$.set(&type_handler_long_blob);
}
| spatial_type float_options srid_option
{
#ifdef HAVE_SPATIAL
Lex->charset=&my_charset_bin;
Lex->last_field->geom_type= $1;
- $$.set(MYSQL_TYPE_GEOMETRY, $2);
+ $$.set(&type_handler_geometry, $2);
#else
my_yyabort_error((ER_FEATURE_DISABLED, MYF(0), sym_group_geom.name,
sym_group_geom.needed_define));
@@ -6347,40 +6386,40 @@ field_type_lob:
| MEDIUMBLOB
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_MEDIUM_BLOB);
+ $$.set(&type_handler_medium_blob);
}
| LONGBLOB
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_LONG_BLOB);
+ $$.set(&type_handler_long_blob);
}
| LONG_SYM VARBINARY
{
Lex->charset=&my_charset_bin;
- $$.set(MYSQL_TYPE_MEDIUM_BLOB);
+ $$.set(&type_handler_medium_blob);
}
| LONG_SYM varchar opt_binary
- { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ { $$.set(&type_handler_medium_blob); }
| TINYTEXT opt_binary
- { $$.set(MYSQL_TYPE_TINY_BLOB); }
+ { $$.set(&type_handler_tiny_blob); }
| TEXT_SYM opt_field_length opt_binary
- { $$.set(MYSQL_TYPE_BLOB, $2); }
+ { $$.set(&type_handler_blob, $2); }
| MEDIUMTEXT opt_binary
- { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ { $$.set(&type_handler_medium_blob); }
| LONGTEXT opt_binary
- { $$.set(MYSQL_TYPE_LONG_BLOB); }
+ { $$.set(&type_handler_long_blob); }
| CLOB opt_binary
- { $$.set(MYSQL_TYPE_LONG_BLOB); }
+ { $$.set(&type_handler_long_blob); }
| LONG_SYM opt_binary
- { $$.set(MYSQL_TYPE_MEDIUM_BLOB); }
+ { $$.set(&type_handler_medium_blob); }
;
field_type_misc:
ENUM '(' string_list ')' opt_binary
- { $$.set(MYSQL_TYPE_ENUM); }
+ { $$.set(&type_handler_enum); }
| SET '(' string_list ')' opt_binary
- { $$.set(MYSQL_TYPE_SET); }
+ { $$.set(&type_handler_set); }
;
spatial_type:
@@ -6417,23 +6456,22 @@ nvarchar:
;
int_type:
- INT_SYM { $$=MYSQL_TYPE_LONG; }
- | TINYINT { $$=MYSQL_TYPE_TINY; }
- | SMALLINT { $$=MYSQL_TYPE_SHORT; }
- | MEDIUMINT { $$=MYSQL_TYPE_INT24; }
- | BIGINT { $$=MYSQL_TYPE_LONGLONG; }
+ INT_SYM { $$= &type_handler_long; }
+ | TINYINT { $$= &type_handler_tiny; }
+ | SMALLINT { $$= &type_handler_short; }
+ | MEDIUMINT { $$= &type_handler_int24; }
+ | BIGINT { $$= &type_handler_longlong; }
;
real_type:
REAL
{
$$= thd->variables.sql_mode & MODE_REAL_AS_FLOAT ?
- MYSQL_TYPE_FLOAT : MYSQL_TYPE_DOUBLE;
+ static_cast<const Type_handler *>(&type_handler_float) :
+ static_cast<const Type_handler *>(&type_handler_double);
}
- | DOUBLE_SYM
- { $$=MYSQL_TYPE_DOUBLE; }
- | DOUBLE_SYM PRECISION
- { $$=MYSQL_TYPE_DOUBLE; }
+ | DOUBLE_SYM { $$= &type_handler_double; }
+ | DOUBLE_SYM PRECISION { $$= &type_handler_double; }
;
srid_option:
@@ -7260,6 +7298,33 @@ alter:
Lex->create_info.set($2);
Lex->sql_command= SQLCOM_ALTER_USER;
}
+ | ALTER SEQUENCE_SYM opt_if_exists_table_element
+ {
+ LEX *lex= Lex;
+ lex->name= null_clex_str;
+ lex->table_type= TABLE_TYPE_UNKNOWN;
+ lex->sql_command= SQLCOM_ALTER_SEQUENCE;
+ lex->create_info.init();
+ lex->no_write_to_binlog= 0;
+ DBUG_ASSERT(!lex->m_sql_cmd);
+ }
+ table_ident
+ {
+ LEX *lex= Lex;
+ if (!(lex->create_info.seq_create_info= new (thd->mem_root)
+ sequence_definition()) ||
+ !lex->select_lex.add_table_to_list(thd, $5, NULL,
+ TL_OPTION_SEQUENCE,
+ TL_WRITE, MDL_EXCLUSIVE))
+ MYSQL_YYABORT;
+ }
+ sequence_defs
+ {
+ /* Create a generic ALTER SEQUENCE statment. */
+ Lex->m_sql_cmd= new (thd->mem_root) Sql_cmd_alter_sequence();
+ if (Lex->m_sql_cmd == NULL)
+ MYSQL_YYABORT;
+ }
;
ev_alter_on_schedule_completion:
@@ -9461,6 +9526,21 @@ column_default_non_parenthesized_expr:
if (!($$= Lex->create_item_func_lastval(thd, $3)))
MYSQL_YYABORT;
}
+ | SETVAL_SYM '(' table_ident ',' longlong_num ')'
+ {
+ if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, 1)))
+ MYSQL_YYABORT;
+ }
+ | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ')'
+ {
+ if (!($$= Lex->create_item_func_setval(thd, $3, $5, 0, $7)))
+ MYSQL_YYABORT;
+ }
+ | SETVAL_SYM '(' table_ident ',' longlong_num ',' bool ',' ulonglong_num ')'
+ {
+ if (!($$= Lex->create_item_func_setval(thd, $3, $5, $9, $7)))
+ MYSQL_YYABORT;
+ }
;
simple_expr:
@@ -12036,6 +12116,12 @@ choice:
| DEFAULT { $$= HA_CHOICE_UNDEF; }
;
+bool:
+ ulong_num { $$= $1 != 0; }
+ | TRUE_SYM { $$= 1; }
+ | FALSE_SYM { $$= 0; }
+
+
procedure_clause:
PROCEDURE_SYM ident /* Procedure name */
{
@@ -14983,6 +15069,7 @@ keyword_sp_not_data_type:
| REPEATABLE_SYM {}
| REPLICATION {}
| RESOURCES {}
+ | RESTART_SYM {}
| RESUME_SYM {}
| RETURNED_SQLSTATE_SYM {}
| RETURNS_SYM {}
@@ -15001,6 +15088,7 @@ keyword_sp_not_data_type:
| SEQUENCE_SYM {}
| SERIALIZABLE_SYM {}
| SESSION_SYM {}
+ | SETVAL_SYM {}
| SIMPLE_SYM {}
| SHARE_SYM {}
| SLAVE_POS_SYM {}
diff --git a/sql/structs.h b/sql/structs.h
index 1a143602eea..80371b1b8b6 100644
--- a/sql/structs.h
+++ b/sql/structs.h
@@ -29,6 +29,7 @@
#include <mysql_com.h> /* USERNAME_LENGTH */
struct TABLE;
+class Type_handler;
class Field;
class Index_statistics;
@@ -581,27 +582,27 @@ public:
struct Lex_field_type_st: public Lex_length_and_dec_st
{
private:
- enum_field_types m_type;
- void set(enum_field_types type, const char *length, const char *dec)
+ const Type_handler *m_handler;
+ void set(const Type_handler *handler, const char *length, const char *dec)
{
- m_type= type;
+ m_handler= handler;
Lex_length_and_dec_st::set(length, dec);
}
public:
- void set(enum_field_types type, Lex_length_and_dec_st length_and_dec)
+ void set(const Type_handler *handler, Lex_length_and_dec_st length_and_dec)
{
- m_type= type;
+ m_handler= handler;
Lex_length_and_dec_st::operator=(length_and_dec);
}
- void set(enum_field_types type, const char *length)
+ void set(const Type_handler *handler, const char *length)
{
- set(type, length, 0);
+ set(handler, length, 0);
}
- void set(enum_field_types type)
+ void set(const Type_handler *handler)
{
- set(type, 0, 0);
+ set(handler, 0, 0);
}
- enum_field_types field_type() const { return m_type; }
+ const Type_handler *type_handler() const { return m_handler; }
};
diff --git a/sql/sys_vars.ic b/sql/sys_vars.ic
index a157538d528..f9acfb3b657 100644
--- a/sql/sys_vars.ic
+++ b/sql/sys_vars.ic
@@ -612,7 +612,9 @@ public:
/* parse and feel list with default values */
if (thd)
{
+#ifndef DBUG_OFF
bool res=
+#endif
sysvartrack_validate_value(thd,
var->save_result.string_value.str,
var->save_result.string_value.length);
diff --git a/sql/table.cc b/sql/table.cc
index fa8ed3c2587..9c3613a879c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1177,7 +1177,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
char *keynames, *names, *comment_pos;
const uchar *forminfo, *extra2;
const uchar *frm_image_end = frm_image + frm_length;
- uchar *record, *null_flags, *null_pos, *mysql57_vcol_null_pos;
+ uchar *record, *null_flags, *null_pos, *mysql57_vcol_null_pos= 0;
const uchar *disk_buff, *strpos;
ulong pos, record_offset;
ulong rec_buff_length;
@@ -2387,6 +2387,8 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
DBUG_ASSERT(field_nr < share->fields);
reg_field= share->field[field_nr];
}
+ else
+ reg_field= 0; // Safety
vcol_screen_pos+= FRM_VCOL_NEW_HEADER_SIZE;
vcol_info->set_vcol_type((enum_vcol_info_type) type);
@@ -7368,7 +7370,7 @@ int TABLE::update_virtual_fields(handler *h, enum_vcol_update_mode update_mode)
DBUG_ASSERT(vcol_info);
DBUG_ASSERT(vcol_info->expr);
- bool update, swap_values= 0;
+ bool update= 0, swap_values= 0;
switch (update_mode) {
case VCOL_UPDATE_FOR_READ:
update= !vcol_info->stored_in_db
diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc
index 42b7bc81261..ad5ef9c5c55 100644
--- a/sql/wsrep_binlog.cc
+++ b/sql/wsrep_binlog.cc
@@ -452,7 +452,7 @@ void wsrep_dump_rbr_buf_with_header(THD *thd, const void *rbr_buf,
File file;
IO_CACHE cache;
Log_event_writer writer(&cache, 0);
- Format_description_log_event *ev;
+ Format_description_log_event *ev= 0;
int len= my_snprintf(filename, PATH_MAX, "%s/GRA_%lld_%lld_v2.log",
wsrep_data_home_dir, (longlong) thd->thread_id,
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index 09681d4daa4..1b6078cc3d9 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -2692,7 +2692,7 @@ PCFIL ha_connect::CheckCond(PGLOBAL g, PCFIL filp, const Item *cond)
htrc("Cond type=%d\n", cond->type());
if (cond->type() == COND::COND_ITEM) {
- char *pb0, *pb1, *pb2, *ph0, *ph1, *ph2;
+ char *pb0, *pb1, *pb2, *ph0= 0, *ph1= 0, *ph2= 0;
bool bb = false, bh = false;
Item_cond *cond_item= (Item_cond *)cond;
diff --git a/storage/connect/tabext.cpp b/storage/connect/tabext.cpp
index e3518126a49..b099321eff5 100644
--- a/storage/connect/tabext.cpp
+++ b/storage/connect/tabext.cpp
@@ -293,7 +293,7 @@ bool TDBEXT::MakeSQL(PGLOBAL g, bool cnt)
if (Srcdef) {
if ((catp = strstr(Srcdef, "%s"))) {
- char *fil1, *fil2;
+ char *fil1= 0, *fil2;
PSZ ph = ((EXTDEF*)To_Def)->Phpos;
if (!ph)
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index d0c0316bf13..7b0597f27ea 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -1873,7 +1873,7 @@ buf_flush_batch(
buf_pool_mutex_enter(buf_pool);
- ulint count = 0;
+ ulint count __attribute__((unused))= 0;
/* Note: The buffer pool mutex is released and reacquired within
the flush functions. */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 72cf0418e81..f6a912c460b 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -2009,7 +2009,7 @@ innobase_release_temporary_latches(
DBUG_ASSERT(hton == innodb_hton_ptr);
if (!srv_was_started) {
- } else if (trx_t* trx = thd_to_trx(thd)) {
+ } else if (trx_t* trx __attribute__((unused))= thd_to_trx(thd)) {
trx_assert_no_search_latch(trx);
}
@@ -13043,7 +13043,7 @@ create_table_info_t::set_tablespace_type(
int
create_table_info_t::initialize()
{
- trx_t* parent_trx;
+ trx_t* parent_trx __attribute__((unused));
DBUG_ENTER("create_table_info_t::initialize");
diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h
index 706579a3b9f..a860196e3db 100644
--- a/storage/innobase/include/ut0dbg.h
+++ b/storage/innobase/include/ut0dbg.h
@@ -62,7 +62,7 @@ ut_dbg_assertion_failed(
/** Debug assertion */
#define ut_ad DBUG_ASSERT
-#ifdef UNIV_DEBUG
+#if defined(UNIV_DEBUG) || !defined(DBUG_OFF)
/** Debug statement. Does nothing unless UNIV_DEBUG is defined. */
#define ut_d(EXPR) EXPR
#else
diff --git a/storage/innobase/include/ut0stage.h b/storage/innobase/include/ut0stage.h
index baad5cd77b4..a4ff0a1c874 100644
--- a/storage/innobase/include/ut0stage.h
+++ b/storage/innobase/include/ut0stage.h
@@ -272,7 +272,7 @@ current phase.
inline
void
ut_stage_alter_t::inc(
- ulint inc_val /* = 1 */)
+ ulint inc_val __attribute__((unused)) /* = 1 */)
{
if (m_progress == NULL) {
return;
diff --git a/storage/maria/ma_create.c b/storage/maria/ma_create.c
index 0ddd8b226e2..959e31c3598 100644
--- a/storage/maria/ma_create.c
+++ b/storage/maria/ma_create.c
@@ -55,7 +55,7 @@ int maria_create(const char *name, enum data_file_type datafile_type,
uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
ulong reclength, real_reclength,min_pack_length;
char kfilename[FN_REFLEN], klinkname[FN_REFLEN], *klinkname_ptr;
- char dfilename[FN_REFLEN], dlinkname[FN_REFLEN], *dlinkname_ptr;
+ char dfilename[FN_REFLEN], dlinkname[FN_REFLEN], *dlinkname_ptr= 0;
ulong pack_reclength;
ulonglong tot_length,max_rows, tmp;
enum en_fieldtype type;
diff --git a/storage/maria/ma_ft_update.c b/storage/maria/ma_ft_update.c
index 51f27520dc1..ddf2a7251ab 100644
--- a/storage/maria/ma_ft_update.c
+++ b/storage/maria/ma_ft_update.c
@@ -28,6 +28,8 @@ void _ma_ft_segiterator_init(MARIA_HA *info, uint keynr, const uchar *record,
ftsi->num=info->s->keyinfo[keynr].keysegs;
ftsi->seg=info->s->keyinfo[keynr].seg;
ftsi->rec=record;
+ ftsi->pos= 0; /* Avoid warnings from gcc */
+ ftsi->len= 0; /* Avoid warnings from gcc */
DBUG_VOID_RETURN;
}
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 2c83c3f891e..cb353db53b0 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -463,6 +463,9 @@ static const char *mrn_inspect_extra_function(enum ha_extra_function operation)
case HA_EXTRA_PREPARE_FOR_DROP:
inspected = "HA_EXTRA_PREPARE_FOR_DROP";
break;
+ case HA_EXTRA_PREPARE_FOR_ALTER_TABLE:
+ inspected = "HA_EXTRA_PREPARE_FOR_ALTER_TABLE";
+ break;
case HA_EXTRA_PREPARE_FOR_UPDATE:
inspected = "HA_EXTRA_PREPARE_FOR_UPDATE";
break;
diff --git a/storage/myisam/ft_update.c b/storage/myisam/ft_update.c
index 8f437476121..f851c0236ae 100644
--- a/storage/myisam/ft_update.c
+++ b/storage/myisam/ft_update.c
@@ -28,6 +28,8 @@ void _mi_ft_segiterator_init(MI_INFO *info, uint keynr, const uchar *record,
ftsi->num=info->s->keyinfo[keynr].keysegs;
ftsi->seg=info->s->keyinfo[keynr].seg;
ftsi->rec=record;
+ ftsi->pos= 0; /* Avoid warnings from gcc */
+ ftsi->len= 0; /* Avoid warnings from gcc */
DBUG_VOID_RETURN;
}
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index c0967a60d13..ab45a16a96c 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -47,7 +47,7 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
uint internal_table= flags & HA_CREATE_INTERNAL_TABLE;
ulong reclength, real_reclength,min_pack_length;
char kfilename[FN_REFLEN],klinkname[FN_REFLEN], *klinkname_ptr;
- char dfilename[FN_REFLEN],dlinkname[FN_REFLEN], *dlinkname_ptr;
+ char dfilename[FN_REFLEN],dlinkname[FN_REFLEN], *dlinkname_ptr= 0;
ulong pack_reclength;
ulonglong tot_length,max_rows, tmp;
enum en_fieldtype type;
diff --git a/storage/tokudb/mysql-test/tokudb/r/type_float.result b/storage/tokudb/mysql-test/tokudb/r/type_float.result
index 6387cea5384..f8ce24f08c4 100644
--- a/storage/tokudb/mysql-test/tokudb/r/type_float.result
+++ b/storage/tokudb/mysql-test/tokudb/r/type_float.result
@@ -233,12 +233,12 @@ insert into t2 values ("1.23456780");
create table t3 select * from t2 union select * from t1;
select * from t3;
d
-1.2345678
-100000000
+1.234567800
+100000000.000000000
show create table t3;
Table Create Table
t3 CREATE TABLE `t3` (
- `d` double DEFAULT NULL
+ `d` double(18,9) DEFAULT NULL
) ENGINE=ENGINE DEFAULT CHARSET=latin1
drop table t1, t2, t3;
create table t1 select 105213674794682365.00 + 0.0 x;
diff --git a/support-files/build-tags b/support-files/build-tags
index e0616661a75..8e8ed251cd7 100755
--- a/support-files/build-tags
+++ b/support-files/build-tags
@@ -8,7 +8,7 @@ then
echo sql mysys strings client storage dbug libmysql sql-common \
extra mysys_ssl strings regex pcre vio include \
tools unittest plugin libmysqld | \
- xargs -n1 git ls-files | grep -v '\.jar$' | \
+ xargs -n1 git ls-files | grep -v '\.jar$' | grep -v '\xz$' |
xargs etags -o TAGS --append
else
find . -type f ! -name "*.jar" |