summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2019-01-03 13:09:41 +0100
committerSergei Golubchik <serg@mariadb.org>2019-01-03 13:09:41 +0100
commit6bb11efa4a7ba813eb4aa2548f95b7297d70f3d7 (patch)
tree3c2dfb2dfbbb0a2471bdcfb0f0c122f823cc80ab
parentab4bc8442094a2be8cdb74bfcddfccede81ac03d (diff)
parent842402e4df35c230e7a416ce3ef8df3055f03d60 (diff)
downloadmariadb-git-6bb11efa4a7ba813eb4aa2548f95b7297d70f3d7.tar.gz
Merge branch '10.2' into 10.3
-rw-r--r--CMakeLists.txt1
-rw-r--r--Docs/README-wsrep32
-rw-r--r--cmake/cpack_rpm.cmake2
-rw-r--r--cmake/mariadb_connector_c.cmake5
-rw-r--r--cmake/zlib.cmake5
-rw-r--r--debian/control2
-rw-r--r--extra/mariabackup/fil_cur.cc175
-rw-r--r--extra/mariabackup/xtrabackup.cc53
-rw-r--r--extra/mariabackup/xtrabackup.h1
m---------libmariadb0
-rw-r--r--mysql-test/main/alter_table_errors.result19
-rw-r--r--mysql-test/main/alter_table_errors.test11
-rw-r--r--mysql-test/main/check.result10
-rw-r--r--mysql-test/main/check.test12
-rw-r--r--mysql-test/main/func_group_innodb.result24
-rw-r--r--mysql-test/main/func_group_innodb.test19
-rw-r--r--mysql-test/main/grant5.result7
-rw-r--r--mysql-test/main/grant5.test10
-rw-r--r--mysql-test/main/innodb_ext_key.result1
-rw-r--r--mysql-test/main/innodb_ext_key.test1
-rw-r--r--mysql-test/main/mysqldump.result6
-rw-r--r--mysql-test/main/mysqldump.test2
-rw-r--r--mysql-test/main/partition_alter.test2
-rw-r--r--mysql-test/main/partition_innodb.result23
-rw-r--r--mysql-test/main/partition_innodb.test25
-rw-r--r--mysql-test/main/range_innodb.result18
-rw-r--r--mysql-test/main/range_innodb.test17
-rw-r--r--mysql-test/main/read_only.result16
-rw-r--r--mysql-test/main/read_only.test23
-rw-r--r--mysql-test/main/udf.result14
-rw-r--r--mysql-test/main/udf.test13
-rw-r--r--mysql-test/main/win.result23
-rw-r--r--mysql-test/main/win.test19
-rw-r--r--mysql-test/r/ps_error.result73
-rw-r--r--mysql-test/std_data/mdev17909#P#p20181029.MYD0
-rw-r--r--mysql-test/std_data/mdev17909#P#p20181029.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/mdev17909#P#p20181128.MYD0
-rw-r--r--mysql-test/std_data/mdev17909#P#p20181128.MYIbin0 -> 1024 bytes
-rw-r--r--mysql-test/std_data/mdev17909.frmbin0 -> 3284 bytes
-rw-r--r--mysql-test/std_data/mdev17909.parbin0 -> 48 bytes
-rw-r--r--mysql-test/suite/encryption/r/innodb-bad-key-change.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-encryption-disable.result1
-rw-r--r--mysql-test/suite/encryption/r/innodb-missing-key.result1
-rw-r--r--mysql-test/suite/encryption/t/innodb-bad-key-change.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-encryption-disable.test1
-rw-r--r--mysql-test/suite/encryption/t/innodb-missing-key.test1
-rw-r--r--mysql-test/suite/innodb/include/crc32.pl33
-rw-r--r--mysql-test/suite/innodb/r/data_types.result12
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter-debug.result23
-rw-r--r--mysql-test/suite/innodb/r/innodb-alter.result21
-rw-r--r--mysql-test/suite/innodb/t/data_types.test11
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter-debug.test32
-rw-r--r--mysql-test/suite/innodb/t/innodb-alter.test13
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_compressed.opt6
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_compressed.result7
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_compressed.test48
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_corruption.result4
-rw-r--r--mysql-test/suite/mariabackup/encrypted_page_corruption.test43
-rw-r--r--mysql-test/suite/mariabackup/huge_lsn.opt4
-rw-r--r--mysql-test/suite/mariabackup/partition_partial.opt1
-rw-r--r--mysql-test/suite/mariabackup/partition_partial.result31
-rw-r--r--mysql-test/suite/mariabackup/partition_partial.test44
-rw-r--r--mysql-test/suite/mariabackup/unencrypted_page_compressed.result11
-rw-r--r--mysql-test/suite/mariabackup/unencrypted_page_compressed.test50
-rw-r--r--mysql-test/suite/rpl/r/rpl_idempotency.result17
-rw-r--r--mysql-test/suite/rpl/t/rpl_idempotency.test21
-rw-r--r--mysql-test/suite/storage_engine/type_bool.result4
-rw-r--r--mysql-test/suite/vcol/r/upgrade.result16
-rw-r--r--mysql-test/suite/vcol/t/upgrade.test15
-rw-r--r--mysql-test/t/ps_error.test66
-rw-r--r--sql/handler.h12
-rw-r--r--sql/item.cc4
-rw-r--r--sql/item_func.cc2
-rw-r--r--sql/opt_range.cc4
-rw-r--r--sql/partition_info.cc4
-rw-r--r--sql/sql_acl.cc6
-rw-r--r--sql/sql_const.h12
-rw-r--r--sql/sql_db.cc9
-rw-r--r--sql/sql_db.h3
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_select.cc4
-rw-r--r--sql/sql_table.cc16
-rw-r--r--sql/table.cc10
-rw-r--r--sql/temporary_tables.cc50
-rw-r--r--storage/connect/global.h6
-rw-r--r--storage/connect/ha_connect.cc4
-rw-r--r--storage/connect/jsonudf.cpp12
-rw-r--r--storage/connect/mysql-test/connect/r/jdbc_oracle.result18
-rw-r--r--storage/connect/plugutil.cpp28
-rw-r--r--storage/connect/reldef.cpp11
-rw-r--r--storage/connect/tabfmt.h2
-rw-r--r--storage/connect/tabjson.cpp10
-rw-r--r--storage/connect/tabjson.h6
-rw-r--r--storage/connect/tabodbc.cpp317
-rw-r--r--storage/connect/tabxml.cpp13
-rw-r--r--storage/connect/tabxml.h5
-rw-r--r--storage/connect/user_connect.cc4
-rw-r--r--storage/innobase/btr/btr0cur.cc15
-rw-r--r--storage/innobase/buf/buf0buf.cc4
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc8
-rw-r--r--storage/innobase/gis/gis0sea.cc2
-rw-r--r--storage/innobase/handler/ha_innodb.cc191
-rw-r--r--storage/innobase/handler/handler0alter.cc32
-rw-r--r--storage/innobase/os/os0event.cc21
-rw-r--r--storage/innobase/row/row0mysql.cc17
-rw-r--r--storage/innobase/ut/ut0dbg.cc2
-rw-r--r--storage/rocksdb/CMakeLists.txt4
-rw-r--r--storage/rocksdb/ha_rocksdb.cc1
-rwxr-xr-xstorage/rocksdb/myrocks_hotbackup.py (renamed from storage/rocksdb/myrocks_hotbackup)2
-rw-r--r--storage/tokudb/CMakeLists.txt47
-rw-r--r--storage/tokudb/mysql-test/tokudb/disabled.def4
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_bin.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_char.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_int.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py0
-rw-r--r--[-rwxr-xr-x]storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py0
-rw-r--r--unittest/mysys/lf-t.c5
-rw-r--r--unittest/mysys/my_atomic-t.c17
-rw-r--r--unittest/mysys/thr_template.c31
-rw-r--r--unittest/mysys/waiting_threads-t.c4
125 files changed, 1578 insertions, 608 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 6b172204120..a7c419e127e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -334,6 +334,7 @@ MYSQL_CHECK_SSL()
MYSQL_CHECK_READLINE()
SET(MALLOC_LIBRARY "system")
+SET(PYTHON_SHEBANG "/usr/bin/env python")
CHECK_PCRE()
diff --git a/Docs/README-wsrep b/Docs/README-wsrep
index 02642e80efb..166901e111f 100644
--- a/Docs/README-wsrep
+++ b/Docs/README-wsrep
@@ -60,7 +60,7 @@ CONTENTS:
Wsrep API developed by Codership Oy is a modern generic (database-agnostic)
replication API for transactional databases with a goal to make database
replication/logging subsystem completely modular and pluggable. It is developed
-with flexibility and completeness in mind to satisfy broad range of modern
+with flexibility and completeness in mind to satisfy a broad range of modern
replication scenarios. It is equally suitable for synchronous and asynchronous,
master-slave and multi-master replication.
@@ -87,7 +87,7 @@ Upgrade from mysql-server-5.0 to mysql-wsrep is not supported yet, please
upgrade to mysql-server-5.1 first.
If you're installing over an existing mysql installation, mysql-server-wsrep
-will conflict with mysql-server-5.1 package, so remove it first:
+will conflict with the mysql-server-5.1 package, so remove it first:
$ sudo apt-get remove mysql-server-5.1 mysql-server-core-5.1
@@ -105,7 +105,7 @@ For example, installation of required packages on Debian Lenny:
$ sudo apt-get install psmisc
$ sudo apt-get -t lenny-backports install mysql-client-5.1
-Now you should be able to install mysql-wsrep package:
+Now you should be able to install the mysql-wsrep package:
$ sudo dpkg -i <mysql-server-wsrep DEB>
@@ -150,7 +150,7 @@ and can be ignored unless specific functionality is needed.
3. FIRST TIME SETUP
Unless you're upgrading an already installed mysql-wsrep package, you will need
-to set up a few things to prepare server for operation.
+to set up a few things to prepare the server for operation.
3.1 CONFIGURATION FILES
@@ -162,7 +162,7 @@ to set up a few things to prepare server for operation.
* Make sure system-wide my.cnf contains "!includedir /etc/mysql/conf.d/" line.
* Edit /etc/mysql/conf.d/wsrep.cnf and set wsrep_provider option by specifying
- a path to provider library. If you don't have a provider, leave it as it is.
+ a path to the provider library. If you don't have a provider, leave it as it is.
* When a new node joins the cluster it'll have to receive a state snapshot from
one of the peers. This requires a privileged MySQL account with access from
@@ -267,7 +267,7 @@ innodb_autoinc_lock_mode=2
This is a required parameter. Without it INSERTs into tables with
AUTO_INCREMENT column may fail.
autoinc lock modes 0 and 1 can cause unresolved deadlock, and make
- system unresponsive.
+ the system unresponsive.
innodb_locks_unsafe_for_binlog=1
This option is required for parallel applying.
@@ -299,14 +299,14 @@ wsrep_node_address=
results (multiple network interfaces, NAT, etc.)
If not explicitly overridden by wsrep_sst_receive_address, the <address> part
will be used to listen for SST (see below). And the whole <address>[:port]
- will be passed to wsrep provider to be used as a base address in its
+ will be passed to the wsrep provider to be used as a base address in its
communications.
wsrep_node_name=
Human readable node name (for easier log reading only). Defaults to hostname.
wsrep_slave_threads=1
- Number of threads dedicated to processing of writesets from other nodes.
+ The number of threads dedicated to the processing of writesets from other nodes.
For best performance should be few per CPU core.
wsrep_dbug_option
@@ -326,7 +326,7 @@ wsrep_convert_LOCK_to_trx=0
wsrep_retry_autocommit=1
Retry autocommit queries and single statement transactions should they fail
certification test. This is analogous to rescheduling an autocommit query
- should it go into deadlock with other transactions in the database lock
+ should it go into a deadlock with other transactions in the database lock
manager.
wsrep_auto_increment_control=1
@@ -357,7 +357,7 @@ wsrep_OSU_method=TOI
is not replicating and may be unable to process replication events (due to
table lock). Once DDL operation is complete, the node will catch up and sync
with the cluster to become fully operational again. The DDL statement or
- its effects are not replicated, so it is user's responsibility to manually
+ its effects are not replicated, so it is the user's responsibility to manually
perform this operation on each of the nodes.
wsrep_forced_binlog_format=none
@@ -412,8 +412,8 @@ wsrep_sst_auth=
wsrep_sst_donor=
A name of the node which should serve as state snapshot donor. This allows
- to control which node will serve state snapshot request. By default the
- most suitable node is chosen by wsrep provider. This is the same as given in
+ controlling which node will serve the state snapshot request. By default the
+ most suitable node is chosen by the wsrep provider. This is the same as given in
wsrep_node_name.
@@ -423,7 +423,7 @@ wsrep_sst_donor=
for the database. They change the database structure and are non-
transactional.
- Release 22.3 brings a new method for performing schema upgrades. User can
+ Release 22.3 brings a new method for performing schema upgrades. A user can
now choose whether to use the traditional total order isolation or new
rolling schema upgrade method. The OSU method choice is done by global
parameter: 'wsrep_OSU_method'.
@@ -439,7 +439,7 @@ wsrep_sst_donor=
6.2 Rolling Schema Upgrade (RSU)
- Rolling schema upgrade is new DDL processing method, where DDL will be
+ Rolling schema upgrade is a new DDL processing method, where DDL will be
processed locally for the node. The node is disconnected of the replication
for the duration of the DDL processing, so that there is only DDL statement
processing in the node and it does not block the rest of the cluster. When
@@ -468,7 +468,7 @@ wsrep_sst_donor=
* LOCK/UNLOCK TABLES cannot be supported in multi-master setups.
* lock functions (GET_LOCK(), RELEASE_LOCK()... )
-4) Query log cannot be directed to table. If you enable query logging,
+4) Query log cannot be directed to a table. If you enable query logging,
you must forward the log to a file:
log_output = FILE
Use general_log and general_log_file to choose query logging and the
@@ -480,7 +480,7 @@ wsrep_sst_donor=
6) Due to cluster level optimistic concurrency control, transaction issuing
COMMIT may still be aborted at that stage. There can be two transactions.
writing to same rows and committing in separate cluster nodes, and only one
- of the them can successfully commit. The failing one will be aborted.
+ of them can successfully commit. The failing one will be aborted.
For cluster level aborts, MySQL/galera cluster gives back deadlock error.
code (Error: 1213 SQLSTATE: 40001 (ER_LOCK_DEADLOCK)).
diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake
index d96638ed5df..36d426257ea 100644
--- a/cmake/cpack_rpm.cmake
+++ b/cmake/cpack_rpm.cmake
@@ -214,6 +214,8 @@ ELSEIF(RPM MATCHES "fedora" OR RPM MATCHES "(rhel|centos)7")
ALTERNATIVE_NAME("server" "mariadb-server")
ALTERNATIVE_NAME("server" "mysql-compat-server")
ALTERNATIVE_NAME("test" "mariadb-test")
+ELSEIF(RPM MATCHES "(rhel|centos)8")
+ SET(PYTHON_SHEBANG "/usr/bin/python3")
ENDIF()
# workaround for lots of perl dependencies added by rpmbuild
diff --git a/cmake/mariadb_connector_c.cmake b/cmake/mariadb_connector_c.cmake
index c36087cb862..368a6cc8da5 100644
--- a/cmake/mariadb_connector_c.cmake
+++ b/cmake/mariadb_connector_c.cmake
@@ -6,10 +6,7 @@ ENDIF()
SET(CONC_WITH_SIGNCODE ${SIGNCODE})
SET(SIGN_OPTIONS ${SIGNTOOL_PARAMETERS})
-
-IF(NOT TARGET zlib)
- SET(CONC_WITH_EXTERNAL_ZLIB ON)
-ENDIF()
+SET(CONC_WITH_EXTERNAL_ZLIB ON)
IF(SSL_DEFINES MATCHES "YASSL")
IF(WIN32)
diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake
index 4b7faacc466..e269c473f36 100644
--- a/cmake/zlib.cmake
+++ b/cmake/zlib.cmake
@@ -34,11 +34,6 @@ ENDMACRO()
MACRO (MYSQL_CHECK_ZLIB_WITH_COMPRESS)
- # For NDBCLUSTER: Use bundled zlib by default
- IF (NOT WITH_ZLIB)
- SET(WITH_ZLIB "bundled" CACHE STRING "By default use bundled zlib on this platform")
- ENDIF()
-
IF(WITH_ZLIB STREQUAL "bundled")
MYSQL_USE_BUNDLED_ZLIB()
ELSE()
diff --git a/debian/control b/debian/control
index d352f9a3712..a2ab4970db1 100644
--- a/debian/control
+++ b/debian/control
@@ -571,7 +571,7 @@ Description: OQGraph storage engine for MariaDB
Package: mariadb-plugin-tokudb
Architecture: amd64
Depends: mariadb-server-10.3 (= ${binary:Version}),
- libjemalloc1 (>= 3.0.0~),
+ libjemalloc1 (>= 3.0.0~) | libjemalloc2,
${misc:Depends},
${shlibs:Depends}
Breaks: mariadb-server-10.0,
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc
index 27d957693ed..d283d0be617 100644
--- a/extra/mariabackup/fil_cur.cc
+++ b/extra/mariabackup/fil_cur.cc
@@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
#include "fil_cur.h"
#include "fil0crypt.h"
+#include "fil0pagecompress.h"
#include "common.h"
#include "read_filt.h"
#include "xtrabackup.h"
@@ -270,6 +271,102 @@ xb_fil_cur_open(
return(XB_FIL_CUR_SUCCESS);
}
+static bool page_is_corrupted(byte *page, ulint page_no, xb_fil_cur_t *cursor,
+ fil_space_t *space)
+{
+ byte tmp_frame[UNIV_PAGE_SIZE_MAX];
+ byte tmp_page[UNIV_PAGE_SIZE_MAX];
+ const ulint page_size = cursor->page_size.physical();
+ ulint page_type = mach_read_from_2(page + FIL_PAGE_TYPE);
+
+ /* We ignore the doublewrite buffer pages.*/
+ if (cursor->space_id == TRX_SYS_SPACE
+ && page_no >= FSP_EXTENT_SIZE
+ && page_no < FSP_EXTENT_SIZE * 3) {
+ return false;
+ }
+
+ /* Validate page number. */
+ if (mach_read_from_4(page + FIL_PAGE_OFFSET) != page_no
+ && cursor->space_id != TRX_SYS_SPACE) {
+ /* On pages that are not all zero, the
+ page number must match.
+
+ There may be a mismatch on tablespace ID,
+ because files may be renamed during backup.
+ We disable the page number check
+ on the system tablespace, because it may consist
+ of multiple files, and here we count the pages
+ from the start of each file.)
+
+ The first 38 and last 8 bytes are never encrypted. */
+ const ulint* p = reinterpret_cast<ulint*>(page);
+ const ulint* const end = reinterpret_cast<ulint*>(
+ page + page_size);
+ do {
+ if (*p++) {
+ return true;
+ }
+ } while (p != end);
+
+ /* Whole zero page is valid. */
+ return false;
+ }
+
+ /* Validate encrypted pages. The first page is never encrypted.
+ In the system tablespace, the first page would be written with
+ FIL_PAGE_FILE_FLUSH_LSN at shutdown, and if the LSN exceeds
+ 4,294,967,295, the mach_read_from_4() below would wrongly
+ interpret the page as encrypted. We prevent that by checking
+ page_no first. */
+ if (page_no
+ && mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
+ && space->crypt_data
+ && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED) {
+
+ if (!fil_space_verify_crypt_checksum(page, cursor->page_size))
+ return true;
+
+ /* Compressed encrypted need to be decrypted
+ and decompressed for verification. */
+ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
+ && !opt_extended_validation)
+ return false;
+
+ memcpy(tmp_page, page, page_size);
+
+ bool decrypted = false;
+ if (!fil_space_decrypt(space, tmp_frame, tmp_page, &decrypted)) {
+ return true;
+ }
+
+ if (page_type != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ return buf_page_is_corrupted(true, tmp_page,
+ cursor->page_size, space);
+ }
+ }
+
+ if (page_type == FIL_PAGE_PAGE_COMPRESSED) {
+ memcpy(tmp_page, page, page_size);
+ }
+
+ if (page_type == FIL_PAGE_PAGE_COMPRESSED
+ || page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ ulint decomp = fil_page_decompress(tmp_frame, tmp_page);
+ page_type = mach_read_from_2(tmp_page + FIL_PAGE_TYPE);
+
+ return (!decomp
+ || (decomp != srv_page_size
+ && cursor->page_size.is_compressed())
+ || page_type == FIL_PAGE_PAGE_COMPRESSED
+ || page_type == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED
+ || buf_page_is_corrupted(true, tmp_page,
+ cursor->page_size, space));
+ }
+
+ return buf_page_is_corrupted(true, page, cursor->page_size, space);
+}
+
/************************************************************************
Reads and verifies the next block of pages from the source
file. Positions the cursor after the last read non-corrupted page.
@@ -288,8 +385,6 @@ xb_fil_cur_read(
xb_fil_cur_result_t ret;
ib_int64_t offset;
ib_int64_t to_read;
- byte tmp_frame[UNIV_PAGE_SIZE_MAX];
- byte tmp_page[UNIV_PAGE_SIZE_MAX];
const ulint page_size = cursor->page_size.physical();
xb_ad(!cursor->is_system() || page_size == srv_page_size);
@@ -327,7 +422,7 @@ xb_fil_cur_read(
xb_a((to_read & (page_size - 1)) == 0);
- npages = (ulint) (to_read / cursor->page_size.physical());
+ npages = (ulint) (to_read / page_size);
retry_count = 10;
ret = XB_FIL_CUR_SUCCESS;
@@ -344,7 +439,7 @@ read_retry:
cursor->buf_read = 0;
cursor->buf_npages = 0;
cursor->buf_offset = offset;
- cursor->buf_page_no = (ulint)(offset / cursor->page_size.physical());
+ cursor->buf_page_no = (ulint)(offset / page_size);
if (!os_file_read(IORequestRead, cursor->file, cursor->buf, offset,
(ulint) to_read)) {
@@ -357,58 +452,28 @@ read_retry:
page += page_size, i++) {
ulint page_no = cursor->buf_page_no + i;
- if (cursor->space_id == TRX_SYS_SPACE &&
- page_no >= FSP_EXTENT_SIZE &&
- page_no < FSP_EXTENT_SIZE * 3) {
- /* We ignore the doublewrite buffer pages */
- } else if (mach_read_from_4(
- page
- + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION)
- && space->crypt_data
- && space->crypt_data->type
- != CRYPT_SCHEME_UNENCRYPTED
- && fil_space_verify_crypt_checksum(
- page, cursor->page_size)) {
- ut_ad(mach_read_from_4(page + FIL_PAGE_SPACE_ID)
- == space->id);
-
- bool decrypted = false;
-
- memcpy(tmp_page, page, page_size);
-
- if (!fil_space_decrypt(space, tmp_frame,
- tmp_page, &decrypted)
- || buf_page_is_corrupted(true, tmp_page,
- cursor->page_size,
- space)) {
- goto corrupted;
+ if (page_is_corrupted(page, page_no, cursor, space)){
+ retry_count--;
+
+ if (retry_count == 0) {
+ msg("[%02u] mariabackup: "
+ "Error: failed to read page after "
+ "10 retries. File %s seems to be "
+ "corrupted.\n", cursor->thread_n,
+ cursor->abs_path);
+ ret = XB_FIL_CUR_ERROR;
+ break;
}
- } else if (buf_page_is_corrupted(true, page, cursor->page_size,
- space)) {
-corrupted:
- retry_count--;
- if (retry_count == 0) {
- msg("[%02u] mariabackup: "
- "Error: failed to read page after "
- "10 retries. File %s seems to be "
- "corrupted.\n", cursor->thread_n,
- cursor->abs_path);
- ret = XB_FIL_CUR_ERROR;
- break;
- }
-
- if (retry_count == 9) {
- msg("[%02u] mariabackup: "
- "Database page corruption detected at page "
- ULINTPF ", retrying...\n",
- cursor->thread_n, page_no);
- }
-
- os_thread_sleep(100000);
- goto read_retry;
- }
- cursor->buf_read += page_size;
- cursor->buf_npages++;
+ msg("[%02u] mariabackup: "
+ "Database page corruption detected at page "
+ ULINTPF ", retrying...\n", cursor->thread_n,
+ page_no);
+
+ os_thread_sleep(100000);
+ goto read_retry;
+ }
+ cursor->buf_read += page_size;
+ cursor->buf_npages++;
}
posix_fadvise(cursor->file, offset, to_read, POSIX_FADV_DONTNEED);
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index 75760ad352b..af56a9ed5d2 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -200,6 +200,7 @@ static char* log_ignored_opt;
extern my_bool opt_use_ssl;
my_bool opt_ssl_verify_server_cert;
+my_bool opt_extended_validation;
/* === metadata of backup === */
#define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints"
@@ -760,6 +761,7 @@ enum options_xtrabackup
OPT_XTRA_DATABASES,
OPT_XTRA_DATABASES_FILE,
OPT_XTRA_PARALLEL,
+ OPT_XTRA_EXTENDED_VALIDATION,
OPT_XTRA_STREAM,
OPT_XTRA_COMPRESS,
OPT_XTRA_COMPRESS_THREADS,
@@ -1217,6 +1219,14 @@ struct my_option xb_server_options[] =
(G_PTR*) &xtrabackup_parallel, (G_PTR*) &xtrabackup_parallel, 0, GET_INT,
REQUIRED_ARG, 1, 1, INT_MAX, 0, 0, 0},
+ {"extended_validation", OPT_XTRA_EXTENDED_VALIDATION,
+ "Enable extended validation for Innodb data pages during backup phase."
+ "Will slow down backup considerably, in case encryption is used.",
+ (G_PTR*)&opt_extended_validation,
+ (G_PTR*)&opt_extended_validation,
+ 0, GET_BOOL, NO_ARG, FALSE, 0, 0, 0, 0, 0},
+
+
{"log", OPT_LOG, "Ignored option for MySQL option compatibility",
(G_PTR*) &log_ignored_opt, (G_PTR*) &log_ignored_opt, 0,
GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0},
@@ -1453,7 +1463,7 @@ debug_sync_point(const char *name)
}
-static std::vector<std::string> tables_for_export;
+static std::set<std::string> tables_for_export;
static void append_export_table(const char *dbname, const char *tablename, bool is_remote)
{
@@ -1465,7 +1475,15 @@ static void append_export_table(const char *dbname, const char *tablename, bool
char *p=strrchr(buf, '.');
if (p) *p=0;
- tables_for_export.push_back(ut_get_name(0,buf));
+ std::string name=ut_get_name(0, buf);
+ /* Strip partition name comment from table name, if any */
+ if (ends_with(name.c_str(), "*/"))
+ {
+ size_t pos= name.rfind("/*");
+ if (pos != std::string::npos)
+ name.resize(pos);
+ }
+ tables_for_export.insert(name);
}
}
@@ -1480,9 +1498,10 @@ static int create_bootstrap_file()
fputs("SET NAMES UTF8;\n",f);
enumerate_ibd_files(append_export_table);
- for (size_t i= 0; i < tables_for_export.size(); i++)
+ for (std::set<std::string>::iterator it = tables_for_export.begin();
+ it != tables_for_export.end(); it++)
{
- const char *tab = tables_for_export[i].c_str();
+ const char *tab = it->c_str();
fprintf(f,
"BEGIN NOT ATOMIC "
"DECLARE CONTINUE HANDLER FOR NOT FOUND,SQLEXCEPTION BEGIN END;"
@@ -1512,7 +1531,7 @@ static int prepare_export()
snprintf(cmdline, sizeof cmdline,
IF_WIN("\"","") "\"%s\" --mysqld \"%s\" "
" --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
- " --innodb --innodb-fast-shutdown=0"
+ " --innodb --innodb-fast-shutdown=0 --loose-partition"
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
" --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe,
@@ -1524,7 +1543,7 @@ static int prepare_export()
sprintf(cmdline,
IF_WIN("\"","") "\"%s\" --mysqld"
" --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=."
- " --innodb --innodb-fast-shutdown=0"
+ " --innodb --innodb-fast-shutdown=0 --loose-partition"
" --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu"
" --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""),
mariabackup_exe,
@@ -3356,8 +3375,15 @@ xb_load_tablespaces()
return(DB_ERROR);
}
- err = srv_sys_space.open_or_create(false, false, &sum_of_new_sizes,
- &flush_lsn);
+ for (int i= 0; i < 10; i++) {
+ err = srv_sys_space.open_or_create(false, false, &sum_of_new_sizes,
+ &flush_lsn);
+ if (err == DB_PAGE_CORRUPTED || err == DB_CORRUPTION) {
+ my_sleep(1000);
+ }
+ else
+ break;
+ }
if (err != DB_SUCCESS) {
msg("mariabackup: Could not open data files.\n");
@@ -5769,7 +5795,6 @@ check_all_privileges()
mysql_free_result(result);
int check_result = PRIVILEGE_OK;
- bool reload_checked = false;
/* FLUSH TABLES WITH READ LOCK */
if (!opt_no_lock)
@@ -5777,7 +5802,6 @@ check_all_privileges()
check_result |= check_privilege(
granted_privileges,
"RELOAD", "*", "*");
- reload_checked = true;
}
if (!opt_no_lock)
@@ -6426,3 +6450,12 @@ static int get_exepath(char *buf, size_t size, const char *argv0)
return my_realpath(buf, argv0, 0);
}
+
+
+#if defined (__SANITIZE_ADDRESS__) && defined (__linux__)
+/* Avoid LeakSanitizer's false positives. */
+const char* __asan_default_options()
+{
+ return "detect_leaks=0";
+}
+#endif
diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h
index 857c253f803..7de28d1ea31 100644
--- a/extra/mariabackup/xtrabackup.h
+++ b/extra/mariabackup/xtrabackup.h
@@ -111,6 +111,7 @@ extern my_bool opt_noversioncheck;
extern my_bool opt_no_backup_locks;
extern my_bool opt_decompress;
extern my_bool opt_remove_original;
+extern my_bool opt_extended_validation;
extern my_bool opt_lock_ddl_per_table;
extern char *opt_incremental_history_name;
diff --git a/libmariadb b/libmariadb
-Subproject 334964f0711c3fd027f634a239eee57bc912f7f
+Subproject 34f8887af03d022416dd6593de91d0706e57f46
diff --git a/mysql-test/main/alter_table_errors.result b/mysql-test/main/alter_table_errors.result
index 020a30304d0..b26409e3d05 100644
--- a/mysql-test/main/alter_table_errors.result
+++ b/mysql-test/main/alter_table_errors.result
@@ -8,3 +8,22 @@ t CREATE TABLE `t` (
`v` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
drop table t;
+create temporary table t1 (a int, v int as (a));
+alter table t1 change column a b int, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+show create table t1;
+Table Create Table
+t1 CREATE TEMPORARY TABLE `t1` (
+ `a` int(11) DEFAULT NULL,
+ `v` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+create temporary table t2 (a int, v int as (a));
+lock table t2 write;
+alter table t2 change column a b int, algorithm=inplace;
+ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY
+show create table t2;
+Table Create Table
+t2 CREATE TEMPORARY TABLE `t2` (
+ `a` int(11) DEFAULT NULL,
+ `v` int(11) GENERATED ALWAYS AS (`a`) VIRTUAL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
diff --git a/mysql-test/main/alter_table_errors.test b/mysql-test/main/alter_table_errors.test
index d9982ac26f4..8fa65b0f330 100644
--- a/mysql-test/main/alter_table_errors.test
+++ b/mysql-test/main/alter_table_errors.test
@@ -8,3 +8,14 @@ create table t (a int, v int as (a)) engine=innodb;
alter table t change column a b tinyint, algorithm=inplace;
show create table t;
drop table t;
+
+create temporary table t1 (a int, v int as (a));
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t1 change column a b int, algorithm=inplace;
+show create table t1;
+
+create temporary table t2 (a int, v int as (a));
+lock table t2 write;
+--error ER_ALTER_OPERATION_NOT_SUPPORTED
+alter table t2 change column a b int, algorithm=inplace;
+show create table t2;
diff --git a/mysql-test/main/check.result b/mysql-test/main/check.result
index e3dcda773f4..e882a4cdbe6 100644
--- a/mysql-test/main/check.result
+++ b/mysql-test/main/check.result
@@ -85,3 +85,13 @@ t1 CREATE TABLE `t1` (
`c` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t1;
+create temporary table t1 (
+id int not null auto_increment primary key,
+f int not null default 0
+);
+insert into t1 () values ();
+alter ignore table t1 add constraint check (f > 0);
+Warnings:
+Warning 4025 CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1`
+alter table t1;
+drop table t1;
diff --git a/mysql-test/main/check.test b/mysql-test/main/check.test
index cce8fd34c9c..475a7996a09 100644
--- a/mysql-test/main/check.test
+++ b/mysql-test/main/check.test
@@ -103,3 +103,15 @@ CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM;
ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`;
SHOW CREATE TABLE t1;
DROP TABLE t1;
+
+#
+# MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table
+#
+create temporary table t1 (
+ id int not null auto_increment primary key,
+ f int not null default 0
+);
+insert into t1 () values ();
+alter ignore table t1 add constraint check (f > 0);
+alter table t1;
+drop table t1;
diff --git a/mysql-test/main/func_group_innodb.result b/mysql-test/main/func_group_innodb.result
index 27493ae710b..e149997af4f 100644
--- a/mysql-test/main/func_group_innodb.result
+++ b/mysql-test/main/func_group_innodb.result
@@ -246,4 +246,28 @@ EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL b 263 NULL 3 Using index for group-by
DROP TABLE t1;
+#
+# MDEV-17589: Stack-buffer-overflow with indexed varchar (utf8) field
+#
+CREATE TABLE t1 (v1 varchar(1020), v2 varchar(2), v3 varchar(2),
+KEY k1 (v3,v2,v1)) ENGINE=InnoDB CHARACTER SET=utf8 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES ('king', 'qu','qu'), ('bad','go','go');
+explain
+SELECT MIN(t1.v1) FROM t1 where t1.v2='qu' and t1.v3='qu';
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
+SELECT MIN(t1.v1) FROM t1 where t1.v2='qu' and t1.v3='qu';
+MIN(t1.v1)
+king
+drop table t1;
+CREATE TABLE t1 (v1 varchar(1024) CHARACTER SET utf8, KEY v1 (v1)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES ('king'), ('bad');
+explain
+SELECT MIN(x.v1) FROM (SELECT t1.* FROM t1 WHERE t1.v1 >= 'p') x;
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No matching min/max row
+SELECT MIN(x.v1) FROM (SELECT t1.* FROM t1 WHERE t1.v1 >= 'p') x;
+MIN(x.v1)
+NULL
+drop table t1;
End of 5.5 tests
diff --git a/mysql-test/main/func_group_innodb.test b/mysql-test/main/func_group_innodb.test
index 1d175f85ed9..c4914b97641 100644
--- a/mysql-test/main/func_group_innodb.test
+++ b/mysql-test/main/func_group_innodb.test
@@ -192,4 +192,23 @@ EXPLAIN SELECT MIN(c) FROM t1 GROUP BY b;
DROP TABLE t1;
+--echo #
+--echo # MDEV-17589: Stack-buffer-overflow with indexed varchar (utf8) field
+--echo #
+
+CREATE TABLE t1 (v1 varchar(1020), v2 varchar(2), v3 varchar(2),
+ KEY k1 (v3,v2,v1)) ENGINE=InnoDB CHARACTER SET=utf8 ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES ('king', 'qu','qu'), ('bad','go','go');
+explain
+SELECT MIN(t1.v1) FROM t1 where t1.v2='qu' and t1.v3='qu';
+SELECT MIN(t1.v1) FROM t1 where t1.v2='qu' and t1.v3='qu';
+drop table t1;
+
+CREATE TABLE t1 (v1 varchar(1024) CHARACTER SET utf8, KEY v1 (v1)) ENGINE=InnoDB ROW_FORMAT=DYNAMIC;
+INSERT INTO t1 VALUES ('king'), ('bad');
+explain
+SELECT MIN(x.v1) FROM (SELECT t1.* FROM t1 WHERE t1.v1 >= 'p') x;
+SELECT MIN(x.v1) FROM (SELECT t1.* FROM t1 WHERE t1.v1 >= 'p') x;
+drop table t1;
+
--echo End of 5.5 tests
diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result
index 24abc61a348..c0fecf0c369 100644
--- a/mysql-test/main/grant5.result
+++ b/mysql-test/main/grant5.result
@@ -18,3 +18,10 @@ ERROR 42000: Access denied for user 'test'@'%' to database 'mysql'
connection default;
drop user test, foo;
drop role foo;
+CREATE TABLE t1 (a INT);
+LOCK TABLE t1 WRITE;
+REVOKE EXECUTE ON PROCEDURE sp FROM u;
+ERROR HY000: Table 'user' was not locked with LOCK TABLES
+REVOKE PROCESS ON *.* FROM u;
+ERROR HY000: Table 'user' was not locked with LOCK TABLES
+DROP TABLE t1;
diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test
index 14f2fd65020..649bba7d1ca 100644
--- a/mysql-test/main/grant5.test
+++ b/mysql-test/main/grant5.test
@@ -23,3 +23,13 @@ show grants for foo@'%'; # user
drop user test, foo;
drop role foo;
+#
+# MDEV-17975 Assertion `! is_set()' or `!is_set() || (m_status == DA_OK_BULK && is_bulk_op())' failed upon REVOKE under LOCK TABLE
+#
+CREATE TABLE t1 (a INT);
+LOCK TABLE t1 WRITE;
+--error ER_TABLE_NOT_LOCKED
+REVOKE EXECUTE ON PROCEDURE sp FROM u;
+--error ER_TABLE_NOT_LOCKED
+REVOKE PROCESS ON *.* FROM u;
+DROP TABLE t1;
diff --git a/mysql-test/main/innodb_ext_key.result b/mysql-test/main/innodb_ext_key.result
index c55e8d138f8..7a994730738 100644
--- a/mysql-test/main/innodb_ext_key.result
+++ b/mysql-test/main/innodb_ext_key.result
@@ -1089,6 +1089,7 @@ from
t0 A, t0 B, t0 C;
drop table t0,t1;
#
+#
# MDEV-10360: Extended keys: index properties depend on index order
#
create table t0 (a int);
diff --git a/mysql-test/main/innodb_ext_key.test b/mysql-test/main/innodb_ext_key.test
index a721943e8bc..4104ac5f787 100644
--- a/mysql-test/main/innodb_ext_key.test
+++ b/mysql-test/main/innodb_ext_key.test
@@ -726,6 +726,7 @@ if ($rows < 2)
drop table t0,t1;
--echo #
+--echo #
--echo # MDEV-10360: Extended keys: index properties depend on index order
--echo #
create table t0 (a int);
diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result
index 1366f9bdd12..556245df9cd 100644
--- a/mysql-test/main/mysqldump.result
+++ b/mysql-test/main/mysqldump.result
@@ -4333,12 +4333,12 @@ second ee1 root@localhost UTC ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL E
show create event ee1;
Event sql_mode time_zone Create Event character_set_client collation_connection Database Collation
ee1 UTC CREATE DEFINER=`root`@`localhost` EVENT `ee1` ON SCHEDULE AT '2035-12-31 20:01:23' ON COMPLETION NOT PRESERVE ENABLE DO set @a=5 latin1 latin1_swedish_ci latin1_swedish_ci
-create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
+create event ee2 on schedule at '2030-12-31 21:01:22' do set @a=5;
create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
show events;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
second ee1 root@localhost UTC ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
-second ee2 root@localhost UTC ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
+second ee2 root@localhost UTC ONE TIME 2030-12-31 21:01:22 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
second ee3 root@localhost UTC ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
drop database second;
create database third;
@@ -4346,7 +4346,7 @@ use third;
show events;
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
third ee1 root@localhost UTC ONE TIME 2035-12-31 20:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
-third ee2 root@localhost UTC ONE TIME 2018-12-31 21:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
+third ee2 root@localhost UTC ONE TIME 2030-12-31 21:01:22 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
third ee3 root@localhost UTC ONE TIME 2030-12-31 22:01:23 NULL NULL NULL NULL ENABLED 1 latin1 latin1_swedish_ci latin1_swedish_ci
drop database third;
set time_zone = 'SYSTEM';
diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test
index 6567596c35c..dbd32f3e74a 100644
--- a/mysql-test/main/mysqldump.test
+++ b/mysql-test/main/mysqldump.test
@@ -1810,7 +1810,7 @@ show create event ee1;
## prove three works (with spaces and tabs on the end)
# start with one from the previous restore
-create event ee2 on schedule at '2018-12-31 21:01:23' do set @a=5;
+create event ee2 on schedule at '2030-12-31 21:01:22' do set @a=5;
create event ee3 on schedule at '2030-12-31 22:01:23' do set @a=5;
show events;
--exec $MYSQL_DUMP --events second > $MYSQLTEST_VARDIR/tmp/bug16853-2.sql
diff --git a/mysql-test/main/partition_alter.test b/mysql-test/main/partition_alter.test
index 62a3e1c0777..91ae67e2f7b 100644
--- a/mysql-test/main/partition_alter.test
+++ b/mysql-test/main/partition_alter.test
@@ -79,7 +79,6 @@ partition p1 values less than ('2016-10-18'),
partition p2 values less than ('2020-10-19'));
insert t1 values (0, '2000-01-02', 0);
insert t1 values (1, '2020-01-02', 10);
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
--error ER_CONSTRAINT_FAILED
alter table t1 add check (b in (0, 1));
alter table t1 add check (b in (0, 10));
@@ -96,7 +95,6 @@ partition p1 values less than ('2016-10-18'),
partition p2 values less than ('2020-10-19'));
insert t1 values (0, '2000-01-02', 0);
insert t1 values (1, '2020-01-02', 10);
---replace_regex /#sql-[0-9a-f_]*/#sql-temporary/
--error ER_CONSTRAINT_FAILED
alter table t1 add check (b in (0, 1));
alter table t1 add check (b in (0, 10));
diff --git a/mysql-test/main/partition_innodb.result b/mysql-test/main/partition_innodb.result
index 3d8d2040a48..cdfe619cb29 100644
--- a/mysql-test/main/partition_innodb.result
+++ b/mysql-test/main/partition_innodb.result
@@ -954,6 +954,26 @@ test_jfg test_jfg11
test_jfg test_jfg12#P#p1000
test_jfg test_jfg12#P#pmax
DROP DATABASE test_jfg;
+create table t1 (a int) engine=innodb;
+create table t2 (
+b int,
+c int,
+d bit not null default 0,
+v bit as (d) virtual,
+key (b,v)
+) engine=innodb partition by hash (b);
+insert into t1 values (1),(2);
+insert into t2 (b,c,d) values (1,1,0),(2,2,0);
+explain select t1.* from t1 join t2 on (v = a);
+id select_type table type possible_keys key key_len ref rows Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2
+1 SIMPLE t2 index NULL b 7 NULL 2 Using where; Using index; Using join buffer (flat, BNL join)
+select t1.* from t1 join t2 on (v = a);
+a
+drop table t1, t2;
+#
+# End of 10.2 tests
+#
#
# MDEV-16241 Assertion `inited==RND' failed in handler::ha_rnd_end()
#
@@ -965,3 +985,6 @@ SELECT COUNT(*) FROM t1 WHERE x IS NULL AND y IS NULL AND z IS NULL;
COUNT(*)
2
DROP TABLE t1;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/partition_innodb.test b/mysql-test/main/partition_innodb.test
index 4b4662da47b..57d644d293d 100644
--- a/mysql-test/main/partition_innodb.test
+++ b/mysql-test/main/partition_innodb.test
@@ -1048,6 +1048,27 @@ database_name = 'test_jfg';
DROP DATABASE test_jfg;
+#
+# MDEV-17755 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index) || (!(ptr >= table->record[0] && ptr < table->record[0] + table->s->reclength)))' failed in Field_bit::val_int upon SELECT with JOIN, partitions, indexed virtual column
+#
+create table t1 (a int) engine=innodb;
+create table t2 (
+ b int,
+ c int,
+ d bit not null default 0,
+ v bit as (d) virtual,
+ key (b,v)
+) engine=innodb partition by hash (b);
+insert into t1 values (1),(2);
+insert into t2 (b,c,d) values (1,1,0),(2,2,0);
+explain select t1.* from t1 join t2 on (v = a);
+select t1.* from t1 join t2 on (v = a);
+drop table t1, t2;
+
+--echo #
+--echo # End of 10.2 tests
+--echo #
+
--echo #
--echo # MDEV-16241 Assertion `inited==RND' failed in handler::ha_rnd_end()
--echo #
@@ -1057,3 +1078,7 @@ PARTITION BY SYSTEM_TIME (PARTITION p1 HISTORY, PARTITION pn CURRENT);
INSERT INTO t1 VALUES (1, 7, 8, 9), (2, NULL, NULL, NULL), (3, NULL, NULL, NULL);
SELECT COUNT(*) FROM t1 WHERE x IS NULL AND y IS NULL AND z IS NULL;
DROP TABLE t1;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/main/range_innodb.result b/mysql-test/main/range_innodb.result
index 794e6c7b3cc..8bb1c833a56 100644
--- a/mysql-test/main/range_innodb.result
+++ b/mysql-test/main/range_innodb.result
@@ -37,3 +37,21 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10
1 SIMPLE t2 range a,b b 5 NULL 201 Using where; Using join buffer (flat, BNL join)
drop table t0,t1,t2;
+CREATE TABLE t1 (
+pk INT PRIMARY KEY, f1 INT, f2 CHAR(1), f3 CHAR(1),
+KEY(f1), KEY(f2)
+) ENGINE=InnoDB;
+INSERT INTO t1 VALUES
+(1,4,'v',NULL),(2,6,'v',NULL),(3,7,'c',NULL),(4,1,'e',NULL),(5,0,'x',NULL),
+(6,7,'i',NULL),(7,7,'e',NULL),(8,1,'p',NULL),(9,7,'s',NULL),(10,1,'j',NULL),
+(11,5,'z',NULL),(12,2,'c',NULL),(13,0,'a',NULL),(14,1,'q',NULL),(15,8,'y',NULL),
+(16,1,'m',NULL),(17,1,'r',NULL),(18,9,'v',NULL),(19,1,'n',NULL);
+CREATE TABLE t2 (f4 INT, f5 CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (4,'q'),(NULL,'j');
+SELECT * FROM t1 AS t1_1, t1 AS t1_2, t2
+WHERE f5 = t1_2.f2 AND ( t1_1.f1 = 103 AND t1_1.f2 = 'o' OR t1_1.pk < f4 );
+pk f1 f2 f3 pk f1 f2 f3 f4 f5
+1 4 v NULL 14 1 q NULL 4 q
+2 6 v NULL 14 1 q NULL 4 q
+3 7 c NULL 14 1 q NULL 4 q
+drop table t1,t2;
diff --git a/mysql-test/main/range_innodb.test b/mysql-test/main/range_innodb.test
index f76794814ef..605006587cc 100644
--- a/mysql-test/main/range_innodb.test
+++ b/mysql-test/main/range_innodb.test
@@ -45,3 +45,20 @@ explain select * from t0 left join t2 on t2.a <t0.a and t2.b between 50 and 250;
drop table t0,t1,t2;
+CREATE TABLE t1 (
+ pk INT PRIMARY KEY, f1 INT, f2 CHAR(1), f3 CHAR(1),
+ KEY(f1), KEY(f2)
+) ENGINE=InnoDB;
+
+INSERT INTO t1 VALUES
+(1,4,'v',NULL),(2,6,'v',NULL),(3,7,'c',NULL),(4,1,'e',NULL),(5,0,'x',NULL),
+(6,7,'i',NULL),(7,7,'e',NULL),(8,1,'p',NULL),(9,7,'s',NULL),(10,1,'j',NULL),
+(11,5,'z',NULL),(12,2,'c',NULL),(13,0,'a',NULL),(14,1,'q',NULL),(15,8,'y',NULL),
+(16,1,'m',NULL),(17,1,'r',NULL),(18,9,'v',NULL),(19,1,'n',NULL);
+
+CREATE TABLE t2 (f4 INT, f5 CHAR(1)) ENGINE=InnoDB;
+INSERT INTO t2 VALUES (4,'q'),(NULL,'j');
+
+SELECT * FROM t1 AS t1_1, t1 AS t1_2, t2
+WHERE f5 = t1_2.f2 AND ( t1_1.f1 = 103 AND t1_1.f2 = 'o' OR t1_1.pk < f4 );
+drop table t1,t2;
diff --git a/mysql-test/main/read_only.result b/mysql-test/main/read_only.result
index 2029413c0f0..83dfada5f29 100644
--- a/mysql-test/main/read_only.result
+++ b/mysql-test/main/read_only.result
@@ -170,11 +170,24 @@ flush privileges;
drop database mysqltest_db1;
set global read_only= @start_read_only;
#
+# MDEV-16987 - ALTER DATABASE possible in read-only mode
+#
+CREATE USER user1@localhost;
+GRANT ALTER ON test1.* TO user1@localhost;
+CREATE DATABASE test1;
+SET GLOBAL read_only=1;
+ALTER DATABASE test1 CHARACTER SET utf8;
+ERROR HY000: The MariaDB server is running with the --read-only option so it cannot execute this statement
+SET GLOBAL read_only=0;
+DROP DATABASE test1;
+DROP USER user1@localhost;
+USE test;
+# End of 5.5 tests
+#
# WL#5968 Implement START TRANSACTION READ (WRITE|ONLY);
#
#
# Test interaction with read_only system variable.
-DROP TABLE IF EXISTS t1;
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1), (2);
CREATE USER user1;
@@ -211,3 +224,4 @@ connection default;
DROP USER user1;
SET GLOBAL read_only= 0;
DROP TABLE t1;
+# End of 10.0 tests
diff --git a/mysql-test/main/read_only.test b/mysql-test/main/read_only.test
index a05f813346e..5314b11154f 100644
--- a/mysql-test/main/read_only.test
+++ b/mysql-test/main/read_only.test
@@ -283,6 +283,23 @@ flush privileges;
drop database mysqltest_db1;
set global read_only= @start_read_only;
+--echo #
+--echo # MDEV-16987 - ALTER DATABASE possible in read-only mode
+--echo #
+CREATE USER user1@localhost;
+GRANT ALTER ON test1.* TO user1@localhost;
+CREATE DATABASE test1;
+SET GLOBAL read_only=1;
+change_user user1;
+--error ER_OPTION_PREVENTS_STATEMENT
+ALTER DATABASE test1 CHARACTER SET utf8;
+change_user root;
+SET GLOBAL read_only=0;
+DROP DATABASE test1;
+DROP USER user1@localhost;
+USE test;
+
+--echo # End of 5.5 tests
--echo #
--echo # WL#5968 Implement START TRANSACTION READ (WRITE|ONLY);
@@ -291,10 +308,6 @@ set global read_only= @start_read_only;
--echo #
--echo # Test interaction with read_only system variable.
---disable_warnings
-DROP TABLE IF EXISTS t1;
---enable_warnings
-
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES (1), (2);
@@ -344,3 +357,5 @@ DROP TABLE t1;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
+
+--echo # End of 10.0 tests
diff --git a/mysql-test/main/udf.result b/mysql-test/main/udf.result
index 6af6b167511..edbae7e046f 100644
--- a/mysql-test/main/udf.result
+++ b/mysql-test/main/udf.result
@@ -465,3 +465,17 @@ a b
Hello HL
DROP FUNCTION METAPHON;
DROP TABLE t1;
+#
+# MDEV-15424: Unreasonal SQL Error (1356) on select from view
+#
+CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "UDF_EXAMPLE_LIB";
+create table t1(a int , b int);
+insert into t1 values(100, 54), (200, 199);
+create view v1 as select myfunc_int(max(a) over (order by b) , b) from t1;
+select * from v1;
+myfunc_int(max(a) over (order by b) , b)
+154
+399
+drop view v1;
+drop function myfunc_int;
+drop table t1;
diff --git a/mysql-test/main/udf.test b/mysql-test/main/udf.test
index c3a25c6bcce..d2c0dad8398 100644
--- a/mysql-test/main/udf.test
+++ b/mysql-test/main/udf.test
@@ -528,3 +528,16 @@ DROP FUNCTION METAPHON;
#INSERT INTO t1 (a) VALUES ('Hello');
#SELECT * FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-15424: Unreasonal SQL Error (1356) on select from view
+--echo #
+--replace_result $UDF_EXAMPLE_SO UDF_EXAMPLE_LIB
+eval CREATE FUNCTION myfunc_int RETURNS INTEGER SONAME "$UDF_EXAMPLE_SO";
+create table t1(a int , b int);
+insert into t1 values(100, 54), (200, 199);
+create view v1 as select myfunc_int(max(a) over (order by b) , b) from t1;
+select * from v1;
+drop view v1;
+drop function myfunc_int;
+drop table t1;
diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result
index 6ee6f01ba8d..73f9c65b41f 100644
--- a/mysql-test/main/win.result
+++ b/mysql-test/main/win.result
@@ -3471,7 +3471,25 @@ MIN(b1) OVER ()
1
drop table t1;
#
-# Start of 10.3 tests
+# MDEV-15424: Unreasonal SQL Error (1356) on select from view
+#
+create table t1 (id int, n1 int);
+insert into t1 values (1,1), (2,1), (3,2), (4,4);
+create view v1 as SELECT ifnull(max(n1) over (partition by n1),'aaa') FROM t1;
+explain select * from v1;
+id select_type table type possible_keys key key_len ref rows Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
+2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using temporary
+select * from v1;
+ifnull(max(n1) over (partition by n1),'aaa')
+1
+1
+2
+4
+drop table t1;
+drop view v1;
+#
+# End of 10.2 tests
#
#
# MDEV-16489 when lead() returns null on a datetime field, the result is treated as the literal string '[NULL]'
@@ -3490,3 +3508,6 @@ d x
00:00:01 00:00:02
00:00:02 NULL
DROP TABLE t1;
+#
+# End of 10.3 tests
+#
diff --git a/mysql-test/main/win.test b/mysql-test/main/win.test
index 1b49ac681f4..15e96ec7e8e 100644
--- a/mysql-test/main/win.test
+++ b/mysql-test/main/win.test
@@ -2229,7 +2229,20 @@ SELECT DISTINCT MIN(b1) OVER () FROM t1;
drop table t1;
--echo #
---echo # Start of 10.3 tests
+--echo # MDEV-15424: Unreasonal SQL Error (1356) on select from view
+--echo #
+
+create table t1 (id int, n1 int);
+insert into t1 values (1,1), (2,1), (3,2), (4,4);
+
+create view v1 as SELECT ifnull(max(n1) over (partition by n1),'aaa') FROM t1;
+explain select * from v1;
+select * from v1;
+drop table t1;
+drop view v1;
+
+--echo #
+--echo # End of 10.2 tests
--echo #
--echo #
@@ -2245,3 +2258,7 @@ CREATE TABLE t1 (d time);
INSERT INTO t1 VALUES ('00:00:01'),('00:00:02');
SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1;
DROP TABLE t1;
+
+--echo #
+--echo # End of 10.3 tests
+--echo #
diff --git a/mysql-test/r/ps_error.result b/mysql-test/r/ps_error.result
new file mode 100644
index 00000000000..c3c312e82f5
--- /dev/null
+++ b/mysql-test/r/ps_error.result
@@ -0,0 +1,73 @@
+#
+# MDEV-17741 Assertion `thd->Item_change_list::is_empty()' failed in mysql_parse after unsuccessful PS
+#
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'foo'
+EXECUTE stmt;
+ERROR 22007: Truncated incorrect INTEGER value: 'foo'
+SELECT a FROM t1 GROUP BY NULL WITH ROLLUP;
+a
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'foo'
+EXECUTE stmt;
+ERROR 22007: Truncated incorrect INTEGER value: 'foo'
+SET @a = REPLACE( @@global.optimizer_switch, '=on', '=off' ) ;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+#
+# MDEV-17738 Server crashes in Item::delete_self on closing connection after unsuccessful PS
+#
+SET SQL_MODE='STRICT_ALL_TABLES';
+PREPARE stmt FROM "CREATE TABLE ps AS SELECT 1 FROM DUAL WHERE 'foo' && 0";
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'foo'
+EXECUTE stmt;
+ERROR 22007: Truncated incorrect INTEGER value: 'foo'
+SELECT 'All done';
+All done
+All done
+SET SQL_MODE=DEFAULT;
+SET SQL_MODE='STRICT_ALL_TABLES';
+PREPARE stmt FROM "CREATE TABLE ps AS SELECT 1 FROM DUAL WHERE 'foo' && 0";
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'foo'
+EXECUTE stmt;
+ERROR 22007: Truncated incorrect INTEGER value: 'foo'
+DEALLOCATE PREPARE stmt;
+SELECT 'All done';
+All done
+All done
+SET SQL_MODE=DEFAULT;
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'foo'
+EXECUTE stmt;
+ERROR 22007: Truncated incorrect INTEGER value: 'foo'
+SELECT a FROM t1 GROUP BY a;
+a
+SELECT * FROM t1;
+a
+DROP TABLE t1;
+SET SQL_MODE=DEFAULT;
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+Warnings:
+Warning 1292 Truncated incorrect INTEGER value: 'foo'
+EXECUTE stmt;
+ERROR 22007: Truncated incorrect INTEGER value: 'foo'
+SELECT a FROM t1 GROUP BY a;
+a
+INSERT t1 SELECT * FROM ( SELECT * FROM t1 ) sq;
+DROP TABLE t1;
+SET SQL_MODE=DEFAULT;
diff --git a/mysql-test/std_data/mdev17909#P#p20181029.MYD b/mysql-test/std_data/mdev17909#P#p20181029.MYD
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mysql-test/std_data/mdev17909#P#p20181029.MYD
diff --git a/mysql-test/std_data/mdev17909#P#p20181029.MYI b/mysql-test/std_data/mdev17909#P#p20181029.MYI
new file mode 100644
index 00000000000..dcdd088b4dc
--- /dev/null
+++ b/mysql-test/std_data/mdev17909#P#p20181029.MYI
Binary files differ
diff --git a/mysql-test/std_data/mdev17909#P#p20181128.MYD b/mysql-test/std_data/mdev17909#P#p20181128.MYD
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/mysql-test/std_data/mdev17909#P#p20181128.MYD
diff --git a/mysql-test/std_data/mdev17909#P#p20181128.MYI b/mysql-test/std_data/mdev17909#P#p20181128.MYI
new file mode 100644
index 00000000000..dcdd088b4dc
--- /dev/null
+++ b/mysql-test/std_data/mdev17909#P#p20181128.MYI
Binary files differ
diff --git a/mysql-test/std_data/mdev17909.frm b/mysql-test/std_data/mdev17909.frm
new file mode 100644
index 00000000000..575ecd2c70f
--- /dev/null
+++ b/mysql-test/std_data/mdev17909.frm
Binary files differ
diff --git a/mysql-test/std_data/mdev17909.par b/mysql-test/std_data/mdev17909.par
new file mode 100644
index 00000000000..d9141dd0dee
--- /dev/null
+++ b/mysql-test/std_data/mdev17909.par
Binary files differ
diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
index 179be43cc41..5812ff6dce9 100644
--- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result
+++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result
@@ -3,6 +3,7 @@ call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
+call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1");
call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found");
# Start server with keys2.txt
SET GLOBAL innodb_file_per_table = ON;
diff --git a/mysql-test/suite/encryption/r/innodb-encryption-disable.result b/mysql-test/suite/encryption/r/innodb-encryption-disable.result
index d8d37ba7493..94b47103dd0 100644
--- a/mysql-test/suite/encryption/r/innodb-encryption-disable.result
+++ b/mysql-test/suite/encryption/r/innodb-encryption-disable.result
@@ -1,6 +1,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
+call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1");
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
create table t5 (
`intcol1` int(32) DEFAULT NULL,
diff --git a/mysql-test/suite/encryption/r/innodb-missing-key.result b/mysql-test/suite/encryption/r/innodb-missing-key.result
index 32ae29ca76b..6f4a45d817a 100644
--- a/mysql-test/suite/encryption/r/innodb-missing-key.result
+++ b/mysql-test/suite/encryption/r/innodb-missing-key.result
@@ -1,6 +1,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
+call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file .*test.t[12].ibd looks corrupted; key_version=1");
# Start server with keys2.txt
CREATE TABLE t1(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=19;
CREATE TABLE t2(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1;
diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.test b/mysql-test/suite/encryption/t/innodb-bad-key-change.test
index 5c424d8752b..a832880c494 100644
--- a/mysql-test/suite/encryption/t/innodb-bad-key-change.test
+++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test
@@ -13,6 +13,7 @@ call mtr.add_suppression("Plugin 'file_key_management' registration.*failed");
call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
+call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1");
call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found");
--echo # Start server with keys2.txt
diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.test b/mysql-test/suite/encryption/t/innodb-encryption-disable.test
index 0994078788e..6d6f1c40d4c 100644
--- a/mysql-test/suite/encryption/t/innodb-encryption-disable.test
+++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.test
@@ -10,6 +10,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
+call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1");
# Suppression for builds where file_key_management plugin is linked statically
call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.test b/mysql-test/suite/encryption/t/innodb-missing-key.test
index cf851a54def..c2a73d594b4 100644
--- a/mysql-test/suite/encryption/t/innodb-missing-key.test
+++ b/mysql-test/suite/encryption/t/innodb-missing-key.test
@@ -10,6 +10,7 @@
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|is corrupted)");
call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\.");
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
+call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file .*test.t[12].ibd looks corrupted; key_version=1");
--echo # Start server with keys2.txt
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
diff --git a/mysql-test/suite/innodb/include/crc32.pl b/mysql-test/suite/innodb/include/crc32.pl
new file mode 100644
index 00000000000..c2bce09dd36
--- /dev/null
+++ b/mysql-test/suite/innodb/include/crc32.pl
@@ -0,0 +1,33 @@
+# The following is Public Domain / Creative Commons CC0 from
+# http://billauer.co.il/blog/2011/05/perl-crc32-crc-xs-module/
+
+sub mycrc32 {
+ my ($input, $init_value, $polynomial) = @_;
+
+ $init_value = 0 unless (defined $init_value);
+ $polynomial = 0xedb88320 unless (defined $polynomial);
+
+ my @lookup_table;
+
+ for (my $i=0; $i<256; $i++) {
+ my $x = $i;
+ for (my $j=0; $j<8; $j++) {
+ if ($x & 1) {
+ $x = ($x >> 1) ^ $polynomial;
+ } else {
+ $x = $x >> 1;
+ }
+ }
+ push @lookup_table, $x;
+ }
+
+ my $crc = $init_value ^ 0xffffffff;
+
+ foreach my $x (unpack ('C*', $input)) {
+ $crc = (($crc >> 8) & 0xffffff) ^ $lookup_table[ ($crc ^ $x) & 0xff ];
+ }
+
+ $crc = $crc ^ 0xffffffff;
+
+ return $crc;
+}
diff --git a/mysql-test/suite/innodb/r/data_types.result b/mysql-test/suite/innodb/r/data_types.result
index 4e919e37cee..1394431b09d 100644
--- a/mysql-test/suite/innodb/r/data_types.result
+++ b/mysql-test/suite/innodb/r/data_types.result
@@ -77,7 +77,9 @@ t1_VARCHAR_500_BINARY VARCHAR(500) BINARY,
t1_YEAR_2 YEAR(2),
t1_YEAR_4 YEAR(4),
t1_CHAR_0 CHAR(0),
-t1_MYSQL_0 CHAR(0) CHARACTER SET utf8
+t1_MYSQL_0 CHAR(0) CHARACTER SET utf8,
+t1_VARCHAR_0 VARCHAR(0),
+t1_VARMYSQL_0 VARCHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
Warnings:
Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead
@@ -151,10 +153,12 @@ t1_TINYINT DATA_INT
t1_TINYINT_UNSIGNED DATA_INT UNSIGNED
t1_TINYTEXT DATA_BLOB
t1_VARBINARY_100 DATA_BINARY
+t1_VARCHAR_0 DATA_VARCHAR
t1_VARCHAR_10 DATA_VARCHAR
t1_VARCHAR_10_BINARY DATA_VARMYSQL
t1_VARCHAR_500 DATA_VARCHAR
t1_VARCHAR_500_BINARY DATA_VARMYSQL
+t1_VARMYSQL_0 DATA_VARMYSQL
t1_YEAR_2 DATA_INT UNSIGNED
t1_YEAR_4 DATA_INT UNSIGNED
DROP TABLE t1;
@@ -164,3 +168,9 @@ DROP TABLE t1;
CREATE TABLE t1 (c CHAR(0), KEY(c)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('');
DROP TABLE t1;
+#
+# MDEV-18039 Assertion failed in btr_node_ptr_max_size for VARCHAR(0)
+#
+CREATE TABLE t1 (c VARCHAR(0), KEY(c)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('');
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result
index 73037247272..51ba58aa1ef 100644
--- a/mysql-test/suite/innodb/r/innodb-alter-debug.result
+++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result
@@ -75,3 +75,26 @@ connection default;
ERROR 23000: Duplicate entry '1' for key 'a'
SET DEBUG_SYNC='RESET';
DROP TABLE t1;
+#
+# MDEV-17470 Orphan temporary files after interrupted ALTER
+# cause InnoDB: Operating system error number 17 and eventual
+# fatal error 71
+#
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, i INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (NULL,1),(NULL,2),(NULL,3),(NULL,4),(NULL,5),(NULL,6),(NULL,7),(NULL,8);
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+LOCK TABLE t1 READ;
+connect con1,localhost,root,,test;
+ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+connection default;
+kill query @id;
+connection con1;
+ERROR 70100: Query execution was interrupted
+disconnect con1;
+connection default;
+UNLOCK TABLES;
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/r/innodb-alter.result b/mysql-test/suite/innodb/r/innodb-alter.result
index e9f827c004e..528cd07770b 100644
--- a/mysql-test/suite/innodb/r/innodb-alter.result
+++ b/mysql-test/suite/innodb/r/innodb-alter.result
@@ -879,6 +879,27 @@ NAME
a
b
DROP TABLE t1;
+# and an MDEV-18041 regression related to indexes prefixes
+create table `test` (
+`test_old` varchar(255) NOT NULL,
+`other` varchar(255) NOT NULL,
+PRIMARY KEY (`test_old`,`other`),
+UNIQUE KEY uk (`test_old`(100), `other`)
+) ENGINE=InnoDB;
+select name, pos from information_schema.innodb_SYS_FIELDS where name in ('test_old', 'other', 'test_new');
+name pos
+test_old 0
+other 1
+test_old 0
+other 1
+alter table `test` CHANGE COLUMN `test_old` `test_new` varchar(255) NOT NULL;
+select name, pos from information_schema.innodb_SYS_FIELDS where name in ('test_old', 'other', 'test_new');
+name pos
+test_new 0
+other 1
+test_new 0
+other 1
+drop table `test`;
#
# BUG 20029625 - HANDLE_FATAL_SIGNAL (SIG=11) IN
# DICT_MEM_TABLE_COL_RENAME_LOW
diff --git a/mysql-test/suite/innodb/t/data_types.test b/mysql-test/suite/innodb/t/data_types.test
index c8e80c9db27..cfdd5201af2 100644
--- a/mysql-test/suite/innodb/t/data_types.test
+++ b/mysql-test/suite/innodb/t/data_types.test
@@ -90,7 +90,9 @@ CREATE TABLE t1
t1_YEAR_2 YEAR(2),
t1_YEAR_4 YEAR(4),
t1_CHAR_0 CHAR(0),
- t1_MYSQL_0 CHAR(0) CHARACTER SET utf8
+ t1_MYSQL_0 CHAR(0) CHARACTER SET utf8,
+ t1_VARCHAR_0 VARCHAR(0),
+ t1_VARMYSQL_0 VARCHAR(0) CHARACTER SET utf8
) ENGINE=InnoDB;
INSERT INTO t1 () VALUES ();
@@ -127,3 +129,10 @@ DROP TABLE t1;
CREATE TABLE t1 (c CHAR(0), KEY(c)) ENGINE=InnoDB;
INSERT INTO t1 VALUES ('');
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-18039 Assertion failed in btr_node_ptr_max_size for VARCHAR(0)
+--echo #
+CREATE TABLE t1 (c VARCHAR(0), KEY(c)) ENGINE=InnoDB;
+INSERT INTO t1 VALUES ('');
+DROP TABLE t1;
diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test
index 5c8025265e5..00300bfdccc 100644
--- a/mysql-test/suite/innodb/t/innodb-alter-debug.test
+++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test
@@ -98,5 +98,37 @@ SET DEBUG_SYNC='RESET';
DROP TABLE t1;
+--echo #
+--echo # MDEV-17470 Orphan temporary files after interrupted ALTER
+--echo # cause InnoDB: Operating system error number 17 and eventual
+--echo # fatal error 71
+--echo #
+CREATE TABLE t1 (pk INT AUTO_INCREMENT PRIMARY KEY, i INT) ENGINE=InnoDB;
+INSERT INTO t1 VALUES (NULL,1),(NULL,2),(NULL,3),(NULL,4),(NULL,5),(NULL,6),(NULL,7),(NULL,8);
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+INSERT INTO t1 SELECT NULL, i FROM t1;
+
+LOCK TABLE t1 READ;
+
+--connect (con1,localhost,root,,test)
+let $ID= `SELECT @id := CONNECTION_ID()`;
+send ALTER TABLE t1 FORCE, ALGORITHM=COPY;
+
+--connection default
+let $wait_condition= select 1 from information_schema.processlist where state='Waiting for table metadata lock';
+source include/wait_condition.inc;
+let $ignore= `SELECT @id := $ID`;
+kill query @id;
+--connection con1
+--error ER_QUERY_INTERRUPTED
+reap;
+--disconnect con1
+--connection default
+UNLOCK TABLES;
+DROP TABLE t1;
+
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc
diff --git a/mysql-test/suite/innodb/t/innodb-alter.test b/mysql-test/suite/innodb/t/innodb-alter.test
index 7c9eb47252d..28ff110fc01 100644
--- a/mysql-test/suite/innodb/t/innodb-alter.test
+++ b/mysql-test/suite/innodb/t/innodb-alter.test
@@ -545,6 +545,19 @@ SELECT C.NAME FROM INFORMATION_SCHEMA.INNODB_SYS_COLUMNS C INNER JOIN
WHERE T.NAME='test/t1';
DROP TABLE t1;
+--echo # and an MDEV-18041 regression related to indexes prefixes
+create table `test` (
+ `test_old` varchar(255) NOT NULL,
+ `other` varchar(255) NOT NULL,
+ PRIMARY KEY (`test_old`,`other`),
+ UNIQUE KEY uk (`test_old`(100), `other`)
+) ENGINE=InnoDB;
+
+select name, pos from information_schema.innodb_SYS_FIELDS where name in ('test_old', 'other', 'test_new');
+alter table `test` CHANGE COLUMN `test_old` `test_new` varchar(255) NOT NULL;
+select name, pos from information_schema.innodb_SYS_FIELDS where name in ('test_old', 'other', 'test_new');
+drop table `test`;
+
--echo #
--echo # BUG 20029625 - HANDLE_FATAL_SIGNAL (SIG=11) IN
diff --git a/mysql-test/suite/mariabackup/encrypted_page_compressed.opt b/mysql-test/suite/mariabackup/encrypted_page_compressed.opt
new file mode 100644
index 00000000000..e5a02a1a1c9
--- /dev/null
+++ b/mysql-test/suite/mariabackup/encrypted_page_compressed.opt
@@ -0,0 +1,6 @@
+--innodb-encryption-rotate-key-age=2
+--innodb-encryption-threads=4
+--innodb-tablespaces-encryption
+--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
+--loose-file-key-management
+--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/logkey.txt
diff --git a/mysql-test/suite/mariabackup/encrypted_page_compressed.result b/mysql-test/suite/mariabackup/encrypted_page_compressed.result
new file mode 100644
index 00000000000..293addd2b03
--- /dev/null
+++ b/mysql-test/suite/mariabackup/encrypted_page_compressed.result
@@ -0,0 +1,7 @@
+call mtr.add_suppression("InnoDB: Table `test`.`t1` has an unreadable root page");
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes encrypted=yes;
+insert into t1(b, c) values("mariadb", "mariabackup");
+# Corrupt the table
+# xtrabackup backup
+FOUND 1 /Database page corruption detected.*/ in backup.log
+drop table t1;
diff --git a/mysql-test/suite/mariabackup/encrypted_page_compressed.test b/mysql-test/suite/mariabackup/encrypted_page_compressed.test
new file mode 100644
index 00000000000..b4ca7eded14
--- /dev/null
+++ b/mysql-test/suite/mariabackup/encrypted_page_compressed.test
@@ -0,0 +1,48 @@
+source include/have_file_key_management.inc;
+call mtr.add_suppression("InnoDB: Table `test`.`t1` has an unreadable root page");
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes encrypted=yes;
+insert into t1(b, c) values("mariadb", "mariabackup");
+
+let $MYSQLD_DATADIR=`select @@datadir`;
+let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd;
+let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
+
+--source include/shutdown_mysqld.inc
+
+--echo # Corrupt the table
+
+perl;
+use strict;
+use warnings;
+use Fcntl qw(:DEFAULT :seek);
+
+my $ibd_file = $ENV{'t1_IBD'};
+
+my $chunk;
+my $page_size = $ENV{'INNODB_PAGE_SIZE'};
+
+sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file";
+sysseek IBD_FILE, $page_size * 3 + 75, SEEK_CUR;
+$chunk = '\xAA\xAA\xAA\xAA';
+syswrite IBD_FILE, $chunk, 4;
+
+close IBD_FILE;
+EOF
+
+--source include/start_mysqld.inc
+
+echo # xtrabackup backup;
+--disable_result_log
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log;
+--error 1
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backuplog;
+--enable_result_log
+
+--let SEARCH_PATTERN=Database page corruption detected.*
+--let SEARCH_FILE=$backuplog
+--source include/search_pattern_in_file.inc
+remove_file $backuplog;
+
+drop table t1;
+rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/encrypted_page_corruption.result b/mysql-test/suite/mariabackup/encrypted_page_corruption.result
index 8ae34b2a6f0..9a6202a5ea1 100644
--- a/mysql-test/suite/mariabackup/encrypted_page_corruption.result
+++ b/mysql-test/suite/mariabackup/encrypted_page_corruption.result
@@ -1,8 +1,8 @@
-call mtr.add_suppression("\\[ERROR\\] InnoDB: The page .* in file .* cannot be decrypted.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` has an unreadable root page");
CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes;
insert into t1 select repeat('a',100);
# Corrupt the table
# xtrabackup backup
-FOUND 1 /Database page corruption detected/ in backup.log
+FOUND 1 /Database page corruption detected.*/ in backup.log
drop table t1;
diff --git a/mysql-test/suite/mariabackup/encrypted_page_corruption.test b/mysql-test/suite/mariabackup/encrypted_page_corruption.test
index 923875275e6..4491c235ac4 100644
--- a/mysql-test/suite/mariabackup/encrypted_page_corruption.test
+++ b/mysql-test/suite/mariabackup/encrypted_page_corruption.test
@@ -1,12 +1,13 @@
--source include/have_file_key_management.inc
+--source include/innodb_page_size.inc
-call mtr.add_suppression("\\[ERROR\\] InnoDB: The page .* in file .* cannot be decrypted.");
+call mtr.add_suppression("\\[ERROR\\] InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted.");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` has an unreadable root page");
CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB, encrypted=yes;
insert into t1 select repeat('a',100);
-let $MYSQLD_DATADIR=`select @@datadir`;
-let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd;
+let MYSQLD_DATADIR=`select @@datadir`;
+let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
--source include/shutdown_mysqld.inc
@@ -16,17 +17,29 @@ perl;
use strict;
use warnings;
use Fcntl qw(:DEFAULT :seek);
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
-my $ibd_file = $ENV{'t1_IBD'};
+my $page_size = $ENV{INNODB_PAGE_SIZE};
-my $chunk;
-my $len;
+sysopen IBD_FILE, "$ENV{MYSQLD_DATADIR}/test/t1.ibd", O_RDWR
+|| die "Cannot open t1.ibd\n";
+sysread(IBD_FILE, $_, 38) || die "Cannot read t1.ibd\n";
+my $space = unpack("x[34]N", $_);
+sysseek(IBD_FILE, $page_size * 3, SEEK_SET) || die "Cannot seek t1.ibd\n";
-sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file";
-sysseek IBD_FILE, 16384 * 3, SEEK_CUR;
-$chunk = '\xAA\xAA\xAA\xAA';
-syswrite IBD_FILE, $chunk, 4;
+my $head = pack("Nx[18]", 3); # better to have a valid page number
+my $body = chr(0) x ($page_size - 38 - 8);
+# Calculate innodb_checksum_algorithm=crc32 for the unencrypted page.
+# The following bytes are excluded:
+# bytes 0..3 (the checksum is stored there)
+# bytes 26..37 (encryption key version, post-encryption checksum, tablespace id)
+# bytes $page_size-8..$page_size-1 (checksum, LSB of FIL_PAGE_LSN)
+my $polynomial = 0x82f63b78; # CRC-32C
+my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial);
+
+my $page= pack("N",$ck).$head.pack("NNN",1,$ck,$space).$body.pack("Nx[4]",$ck);
+die unless syswrite(IBD_FILE, $page, $page_size) == $page_size;
close IBD_FILE;
EOF
@@ -38,14 +51,20 @@ let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log;
--disable_result_log
--error 1
-exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backuplog;
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --extended-validation --target-dir=$targetdir > $backuplog;
--enable_result_log
---let SEARCH_PATTERN=Database page corruption detected
+--let SEARCH_PATTERN=Database page corruption detected.*
--let SEARCH_FILE=$backuplog
--source include/search_pattern_in_file.inc
remove_file $backuplog;
+rmdir $targetdir;
+
+# Due to very constructed nature of the "corruption" (faking checksums), the "corruption" won't be found without --extended-validation
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+--enable_result_log
drop table t1;
rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/huge_lsn.opt b/mysql-test/suite/mariabackup/huge_lsn.opt
index 74a6450a1ef..c65b76fb7d2 100644
--- a/mysql-test/suite/mariabackup/huge_lsn.opt
+++ b/mysql-test/suite/mariabackup/huge_lsn.opt
@@ -1,4 +1,8 @@
--innodb-encrypt-log=ON
+--innodb-tablespaces-encryption
+--innodb-encrypt-tables=ON
+--innodb-encryption-rotate-key-age=1
+--innodb-encryption-threads=4
--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
--loose-file-key-management
--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/filekeys-data.key
diff --git a/mysql-test/suite/mariabackup/partition_partial.opt b/mysql-test/suite/mariabackup/partition_partial.opt
new file mode 100644
index 00000000000..508cf185695
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_partial.opt
@@ -0,0 +1 @@
+--innodb --loose-partition
diff --git a/mysql-test/suite/mariabackup/partition_partial.result b/mysql-test/suite/mariabackup/partition_partial.result
new file mode 100644
index 00000000000..62b7adf75f8
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_partial.result
@@ -0,0 +1,31 @@
+CREATE TABLE t1(i INT) ENGINE INNODB
+PARTITION BY RANGE (i)
+(PARTITION p1 VALUES LESS THAN (100),
+PARTITION p2 VALUES LESS THAN (200),
+PARTITION p3 VALUES LESS THAN (300),
+PARTITION p4 VALUES LESS THAN (400));
+INSERT INTO t1 VALUES (1), (101), (201), (301);
+# xtrabackup backup
+INSERT INTO t1 VALUES (1), (101), (201), (301);
+# xtrabackup prepare
+CREATE TABLE t1_placeholder (i INT) ENGINE INNODB;
+ALTER TABLE t1_placeholder DISCARD TABLESPACE;
+ALTER TABLE t1_placeholder IMPORT TABLESPACE;
+ALTER TABLE t1 EXCHANGE PARTITION p4 WITH TABLE t1_placeholder;
+ALTER TABLE t1_placeholder DISCARD TABLESPACE;
+ALTER TABLE t1_placeholder IMPORT TABLESPACE;
+ALTER TABLE t1 EXCHANGE PARTITION p3 WITH TABLE t1_placeholder;
+ALTER TABLE t1_placeholder DISCARD TABLESPACE;
+ALTER TABLE t1_placeholder IMPORT TABLESPACE;
+ALTER TABLE t1 EXCHANGE PARTITION p2 WITH TABLE t1_placeholder;
+ALTER TABLE t1_placeholder DISCARD TABLESPACE;
+ALTER TABLE t1_placeholder IMPORT TABLESPACE;
+ALTER TABLE t1 EXCHANGE PARTITION p1 WITH TABLE t1_placeholder;
+SELECT * FROM t1;
+i
+1
+101
+201
+301
+DROP TABLE t1;
+DROP TABLE t1_placeholder;
diff --git a/mysql-test/suite/mariabackup/partition_partial.test b/mysql-test/suite/mariabackup/partition_partial.test
new file mode 100644
index 00000000000..8e288ec997f
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_partial.test
@@ -0,0 +1,44 @@
+#--source include/innodb_page_size.inc
+
+# import partitioned table from table from partial backup
+
+CREATE TABLE t1(i INT) ENGINE INNODB
+PARTITION BY RANGE (i)
+(PARTITION p1 VALUES LESS THAN (100),
+ PARTITION p2 VALUES LESS THAN (200),
+ PARTITION p3 VALUES LESS THAN (300),
+ PARTITION p4 VALUES LESS THAN (400));
+
+INSERT INTO t1 VALUES (1), (101), (201), (301);
+
+echo # xtrabackup backup;
+
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.t1" --target-dir=$targetdir;
+--enable_result_log
+INSERT INTO t1 VALUES (1), (101), (201), (301);
+
+
+echo # xtrabackup prepare;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir;
+--enable_result_log
+
+
+let $MYSQLD_DATADIR= `select @@datadir`;
+CREATE TABLE t1_placeholder (i INT) ENGINE INNODB;
+let $i=4;
+while($i)
+{
+ eval ALTER TABLE t1_placeholder DISCARD TABLESPACE;
+ copy_file $targetdir/test/t1#P#p$i.cfg $MYSQLD_DATADIR/test/t1_placeholder.cfg;
+ copy_file $targetdir/test/t1#P#p$i.ibd $MYSQLD_DATADIR/test/t1_placeholder.ibd;
+ eval ALTER TABLE t1_placeholder IMPORT TABLESPACE;
+ eval ALTER TABLE t1 EXCHANGE PARTITION p$i WITH TABLE t1_placeholder;
+ dec $i;
+}
+SELECT * FROM t1;
+DROP TABLE t1;
+DROP TABLE t1_placeholder;
+rmdir $targetdir;
diff --git a/mysql-test/suite/mariabackup/unencrypted_page_compressed.result b/mysql-test/suite/mariabackup/unencrypted_page_compressed.result
new file mode 100644
index 00000000000..71eac085769
--- /dev/null
+++ b/mysql-test/suite/mariabackup/unencrypted_page_compressed.result
@@ -0,0 +1,11 @@
+call mtr.add_suppression("InnoDB: Table `test`.`t1` has an unreadable root page");
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes;
+insert into t1(b, c) values("mariadb", "mariabackup");
+InnoDB 0 transactions not purged
+# Corrupt the table
+# xtrabackup backup
+FOUND 1 /Database page corruption detected.*/ in backup.log
+drop table t1;
+Warnings:
+Warning 192 Table test/t1 in file ./test/t1.ibd is encrypted but encryption service or used key_id is not available. Can't continue reading table.
diff --git a/mysql-test/suite/mariabackup/unencrypted_page_compressed.test b/mysql-test/suite/mariabackup/unencrypted_page_compressed.test
new file mode 100644
index 00000000000..b41d177e572
--- /dev/null
+++ b/mysql-test/suite/mariabackup/unencrypted_page_compressed.test
@@ -0,0 +1,50 @@
+call mtr.add_suppression("InnoDB: Table `test`.`t1` has an unreadable root page");
+SET GLOBAL innodb_purge_rseg_truncate_frequency = 1;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes;
+insert into t1(b, c) values("mariadb", "mariabackup");
+--source ../innodb/include/wait_all_purged.inc
+
+let $MYSQLD_DATADIR=`select @@datadir`;
+let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd;
+let INNODB_PAGE_SIZE=`select @@innodb_page_size`;
+
+--source include/shutdown_mysqld.inc
+
+--echo # Corrupt the table
+
+perl;
+use strict;
+use warnings;
+use Fcntl qw(:DEFAULT :seek);
+
+my $ibd_file = $ENV{'t1_IBD'};
+
+my $chunk;
+my $page_size = $ENV{'INNODB_PAGE_SIZE'};
+
+sysopen IBD_FILE, $ibd_file, O_RDWR || die "Unable to open $ibd_file";
+sysseek IBD_FILE, 16384 * 3 + 75, SEEK_CUR;
+$chunk = '\xAA\xAA\xAA\xAA';
+syswrite IBD_FILE, $chunk, 4;
+
+close IBD_FILE;
+EOF
+
+--let $restart_parameters= --skip-innodb-buffer-pool-load-at-startup
+--source include/start_mysqld.inc
+
+echo # xtrabackup backup;
+--disable_result_log
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log;
+--error 1
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backuplog;
+--enable_result_log
+
+--let SEARCH_PATTERN=Database page corruption detected.*
+--let SEARCH_FILE=$backuplog
+--source include/search_pattern_in_file.inc
+remove_file $backuplog;
+
+drop table t1;
+rmdir $targetdir;
diff --git a/mysql-test/suite/rpl/r/rpl_idempotency.result b/mysql-test/suite/rpl/r/rpl_idempotency.result
index a9485ca8933..09e084ce448 100644
--- a/mysql-test/suite/rpl/r/rpl_idempotency.result
+++ b/mysql-test/suite/rpl/r/rpl_idempotency.result
@@ -79,8 +79,25 @@ a
-3
1
include/check_slave_no_error.inc
+connection slave;
+drop table t1, t2;
connection master;
DROP TABLE t1, t2;
connection slave;
+include/check_slave_no_error.inc
+create database d;
+create database e;
+connection master;
+create database d;
+create database if not exists e;
+connection slave;
+include/check_slave_no_error.inc
+drop database d;
+drop database e;
+connection master;
+drop database d;
+drop database if exists e;
+connection slave;
+include/check_slave_no_error.inc
SET @@global.slave_exec_mode= @old_slave_exec_mode;
include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_idempotency.test b/mysql-test/suite/rpl/t/rpl_idempotency.test
index fcfe6f65e6d..12dec236d45 100644
--- a/mysql-test/suite/rpl/t/rpl_idempotency.test
+++ b/mysql-test/suite/rpl/t/rpl_idempotency.test
@@ -77,9 +77,30 @@ SELECT * FROM t1 ORDER BY a;
SELECT * FROM t2 ORDER BY a;
--source include/check_slave_no_error.inc
+connection slave;
+drop table t1, t2;
+
connection master;
DROP TABLE t1, t2;
sync_slave_with_master;
+--source include/check_slave_no_error.inc
+create database d;
+create database e;
+
+connection master;
+create database d;
+create database if not exists e;
+
+sync_slave_with_master;
+--source include/check_slave_no_error.inc
+drop database d;
+drop database e;
+
+connection master;
+drop database d;
+drop database if exists e;
+sync_slave_with_master;
+--source include/check_slave_no_error.inc
SET @@global.slave_exec_mode= @old_slave_exec_mode;
diff --git a/mysql-test/suite/storage_engine/type_bool.result b/mysql-test/suite/storage_engine/type_bool.result
index 87308ed63fc..10cfc08102f 100644
--- a/mysql-test/suite/storage_engine/type_bool.result
+++ b/mysql-test/suite/storage_engine/type_bool.result
@@ -42,8 +42,8 @@ b1 b2
0 0
INSERT INTO t1 (b1,b2) VALUES ('a','b');
Warnings:
-Warning 1366 Incorrect integer value: 'a' for column 'b1' at row 1
-Warning 1366 Incorrect integer value: 'b' for column 'b2' at row 1
+Warning 1366 Incorrect integer value: 'a' for column `test`.`t1`.`b1` at row 1
+Warning 1366 Incorrect integer value: 'b' for column `test`.`t1`.`b2` at row 1
SELECT b1,b2 FROM t1;
b1 b2
-1 -2
diff --git a/mysql-test/suite/vcol/r/upgrade.result b/mysql-test/suite/vcol/r/upgrade.result
index 75684bf0e41..527bc5f3abf 100644
--- a/mysql-test/suite/vcol/r/upgrade.result
+++ b/mysql-test/suite/vcol/r/upgrade.result
@@ -16,3 +16,19 @@ select * from vcol_autoinc;
pk v3
1 1
drop table vcol_autoinc;
+check table t1 for upgrade;
+Table Op Msg_type Msg_text
+test.t1 check status OK
+flush tables;
+show create table t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `Date` datetime(6) NOT NULL,
+ `Data` varbinary(2000) NOT NULL,
+ `a` varchar(100) GENERATED ALWAYS AS (column_get(`Data`,1 as char(100) charset latin1)) VIRTUAL,
+ PRIMARY KEY (`Date`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+ PARTITION BY RANGE (to_days(`Date`))
+(PARTITION `p20181029` VALUES LESS THAN (737361) ENGINE = MyISAM,
+ PARTITION `p20181128` VALUES LESS THAN (737391) ENGINE = MyISAM)
+drop table t1;
diff --git a/mysql-test/suite/vcol/t/upgrade.test b/mysql-test/suite/vcol/t/upgrade.test
index 3e221747dfa..146495d8ed0 100644
--- a/mysql-test/suite/vcol/t/upgrade.test
+++ b/mysql-test/suite/vcol/t/upgrade.test
@@ -11,3 +11,18 @@ select * from vcol_autoinc;
insert vcol_autoinc (pk) values (1);
select * from vcol_autoinc;
drop table vcol_autoinc;
+
+#
+# MDEV-17909 Problem by MariaDB Update 10.1.32 -> 10.2.19 (Incorrect information in file: .frm)
+#
+source include/have_partition.inc;
+copy_file std_data/mdev17909#P#p20181029.MYD $datadir/test/t1#P#p20181029.MYD;
+copy_file std_data/mdev17909#P#p20181029.MYI $datadir/test/t1#P#p20181029.MYI;
+copy_file std_data/mdev17909#P#p20181128.MYD $datadir/test/t1#P#p20181128.MYD;
+copy_file std_data/mdev17909#P#p20181128.MYI $datadir/test/t1#P#p20181128.MYI;
+copy_file std_data/mdev17909.frm $datadir/test/t1.frm;
+copy_file std_data/mdev17909.par $datadir/test/t1.par;
+check table t1 for upgrade;
+flush tables;
+show create table t1;
+drop table t1;
diff --git a/mysql-test/t/ps_error.test b/mysql-test/t/ps_error.test
new file mode 100644
index 00000000000..5efb5d36137
--- /dev/null
+++ b/mysql-test/t/ps_error.test
@@ -0,0 +1,66 @@
+#
+# Tests related to PS returning errors rather than doing successfull execution
+#
+
+--echo #
+--echo # MDEV-17741 Assertion `thd->Item_change_list::is_empty()' failed in mysql_parse after unsuccessful PS
+--echo #
+
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+--error ER_TRUNCATED_WRONG_VALUE
+EXECUTE stmt;
+SELECT a FROM t1 GROUP BY NULL WITH ROLLUP;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+--error ER_TRUNCATED_WRONG_VALUE
+EXECUTE stmt;
+SET @a = REPLACE( @@global.optimizer_switch, '=on', '=off' ) ;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+
+--echo #
+--echo # MDEV-17738 Server crashes in Item::delete_self on closing connection after unsuccessful PS
+--echo #
+
+SET SQL_MODE='STRICT_ALL_TABLES';
+PREPARE stmt FROM "CREATE TABLE ps AS SELECT 1 FROM DUAL WHERE 'foo' && 0";
+--error ER_TRUNCATED_WRONG_VALUE
+EXECUTE stmt;
+--source include/restart_mysqld.inc
+SELECT 'All done';
+SET SQL_MODE=DEFAULT;
+
+SET SQL_MODE='STRICT_ALL_TABLES';
+PREPARE stmt FROM "CREATE TABLE ps AS SELECT 1 FROM DUAL WHERE 'foo' && 0";
+--error ER_TRUNCATED_WRONG_VALUE
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+SELECT 'All done';
+SET SQL_MODE=DEFAULT;
+
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+--error ER_TRUNCATED_WRONG_VALUE
+EXECUTE stmt;
+SELECT a FROM t1 GROUP BY a;
+SELECT * FROM t1;
+DROP TABLE t1;
+SET SQL_MODE=DEFAULT;
+
+SET SQL_MODE= 'STRICT_ALL_TABLES';
+CREATE TABLE t1 (a INT);
+PREPARE stmt FROM "CREATE TABLE tmp AS SELECT * FROM t1 WHERE 'foo' && 0";
+--error ER_TRUNCATED_WRONG_VALUE
+EXECUTE stmt;
+SELECT a FROM t1 GROUP BY a;
+INSERT t1 SELECT * FROM ( SELECT * FROM t1 ) sq;
+DROP TABLE t1;
+SET SQL_MODE=DEFAULT;
diff --git a/sql/handler.h b/sql/handler.h
index 788ac4dd474..a4e81ea0365 100644
--- a/sql/handler.h
+++ b/sql/handler.h
@@ -415,6 +415,12 @@ enum enum_alter_inplace_result {
#define HA_KEY_NULL_LENGTH 1
#define HA_KEY_BLOB_LENGTH 2
+/* Maximum length of any index lookup key, in bytes */
+
+#define MAX_KEY_LENGTH (MAX_DATA_LENGTH_FOR_KEY \
+ +(MAX_REF_PARTS \
+ *(HA_KEY_NULL_LENGTH + HA_KEY_BLOB_LENGTH)))
+
#define HA_LEX_CREATE_TMP_TABLE 1U
#define HA_CREATE_TMP_ALTER 8U
#define HA_LEX_CREATE_SEQUENCE 16U
@@ -3782,14 +3788,14 @@ public:
uint max_key_parts() const
{ return MY_MIN(MAX_REF_PARTS, max_supported_key_parts()); }
uint max_key_length() const
- { return MY_MIN(MAX_KEY_LENGTH, max_supported_key_length()); }
+ { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_length()); }
uint max_key_part_length() const
- { return MY_MIN(MAX_KEY_LENGTH, max_supported_key_part_length()); }
+ { return MY_MIN(MAX_DATA_LENGTH_FOR_KEY, max_supported_key_part_length()); }
virtual uint max_supported_record_length() const { return HA_MAX_REC_LENGTH; }
virtual uint max_supported_keys() const { return 0; }
virtual uint max_supported_key_parts() const { return MAX_REF_PARTS; }
- virtual uint max_supported_key_length() const { return MAX_KEY_LENGTH; }
+ virtual uint max_supported_key_length() const { return MAX_DATA_LENGTH_FOR_KEY; }
virtual uint max_supported_key_part_length() const { return 255; }
virtual uint min_record_length(uint options) const { return 1; }
diff --git a/sql/item.cc b/sql/item.cc
index a26f1eac5ba..694b12eecc0 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -8220,7 +8220,9 @@ void Item_ref::print(String *str, enum_query_type query_type)
{
if (ref)
{
- if ((*ref)->type() != Item::CACHE_ITEM && ref_type() != VIEW_REF &&
+ if ((*ref)->type() != Item::CACHE_ITEM &&
+ (*ref)->type() != Item::WINDOW_FUNC_ITEM &&
+ ref_type() != VIEW_REF &&
!table_name && name.str && alias_name_used)
{
THD *thd= current_thd;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 3b9dfc9d97a..62c40255d51 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -3301,6 +3301,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
if (item->maybe_null)
func->maybe_null=1;
func->with_sum_func= func->with_sum_func || item->with_sum_func;
+ func->with_window_func= func->with_window_func ||
+ item->with_window_func;
func->with_field= func->with_field || item->with_field;
func->with_param= func->with_param || item->with_param;
func->With_subquery_cache::join(item);
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 0c6c585bff6..26cda75913a 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2730,10 +2730,6 @@ bool create_key_parts_for_pseudo_indexes(RANGE_OPT_PARAM *param,
{
Field **field_ptr;
TABLE *table= param->table;
- partition_info *part_info= NULL;
- #ifdef WITH_PARTITION_STORAGE_ENGINE
- part_info= table->part_info;
- #endif
uint parts= 0;
for (field_ptr= table->field; *field_ptr; field_ptr++)
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index e24038f96ab..0ac4014a669 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -1516,12 +1516,12 @@ bool partition_info::check_partition_field_length()
for (i= 0; i < num_part_fields; i++)
store_length+= get_partition_field_store_length(part_field_array[i]);
- if (store_length > MAX_KEY_LENGTH)
+ if (store_length > MAX_DATA_LENGTH_FOR_KEY)
DBUG_RETURN(TRUE);
store_length= 0;
for (i= 0; i < num_subpart_fields; i++)
store_length+= get_partition_field_store_length(subpart_field_array[i]);
- if (store_length > MAX_KEY_LENGTH)
+ if (store_length > MAX_DATA_LENGTH_FOR_KEY)
DBUG_RETURN(TRUE);
DBUG_RETURN(FALSE);
}
diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc
index 59ba324df31..748c164c6a8 100644
--- a/sql/sql_acl.cc
+++ b/sql/sql_acl.cc
@@ -6609,7 +6609,8 @@ bool mysql_routine_grant(THD *thd, TABLE_LIST *table_list,
{
List_iterator <LEX_USER> str_list (user_list);
LEX_USER *Str, *tmp_Str;
- bool create_new_users= 0, result;
+ bool create_new_users= 0;
+ int result;
const char *db_name, *table_name;
DBUG_ENTER("mysql_routine_grant");
@@ -7046,7 +7047,8 @@ bool mysql_grant(THD *thd, const char *db, List <LEX_USER> &list,
List_iterator <LEX_USER> str_list (list);
LEX_USER *Str, *tmp_Str, *proxied_user= NULL;
char tmp_db[SAFE_NAME_LEN+1];
- bool create_new_users=0, result;
+ bool create_new_users=0;
+ int result;
DBUG_ENTER("mysql_grant");
if (lower_case_table_names && db)
diff --git a/sql/sql_const.h b/sql/sql_const.h
index be26de872df..82f3b9c21f2 100644
--- a/sql/sql_const.h
+++ b/sql/sql_const.h
@@ -33,7 +33,17 @@
#define MAX_SYS_VAR_LENGTH 32
#define MAX_KEY MAX_INDEXES /* Max used keys */
#define MAX_REF_PARTS 32 /* Max parts used as ref */
-#define MAX_KEY_LENGTH 3072 /* max possible key */
+
+/*
+ Maximum length of the data part of an index lookup key.
+
+ The "data part" is defined as the value itself, not including the
+ NULL-indicator bytes or varchar length bytes ("the Extras"). We need this
+ value because there was a bug where length of the Extras were not counted.
+
+ You probably need MAX_KEY_LENGTH, not this constant.
+*/
+#define MAX_DATA_LENGTH_FOR_KEY 3072
#if SIZEOF_OFF_T > 4
#define MAX_REFLENGTH 8 /* Max length for record ref */
#else
diff --git a/sql/sql_db.cc b/sql/sql_db.cc
index 5f826e37a76..55c51dbe151 100644
--- a/sql/sql_db.cc
+++ b/sql/sql_db.cc
@@ -764,8 +764,7 @@ exit:
}
-int mysql_create_db(THD *thd, const LEX_CSTRING *db,
- const DDL_options_st &options,
+int mysql_create_db(THD *thd, const LEX_CSTRING *db, DDL_options_st options,
const Schema_specification_st *create_info)
{
/*
@@ -773,6 +772,9 @@ int mysql_create_db(THD *thd, const LEX_CSTRING *db,
to it, we need to use a copy to make execution prepared statement- safe.
*/
Schema_specification_st tmp(*create_info);
+ if (thd->slave_thread &&
+ slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
+ options.add(DDL_options::OPT_IF_NOT_EXISTS);
return mysql_create_db_internal(thd, db, options, &tmp, false);
}
@@ -1047,6 +1049,9 @@ exit:
bool mysql_rm_db(THD *thd, const LEX_CSTRING *db, bool if_exists)
{
+ if (thd->slave_thread &&
+ slave_ddl_exec_mode_options == SLAVE_EXEC_MODE_IDEMPOTENT)
+ if_exists= true;
return mysql_rm_db_internal(thd, db, if_exists, false);
}
diff --git a/sql/sql_db.h b/sql/sql_db.h
index 7de6c2a9c99..c0646bd65f0 100644
--- a/sql/sql_db.h
+++ b/sql/sql_db.h
@@ -20,8 +20,7 @@
class THD;
-int mysql_create_db(THD *thd, const LEX_CSTRING *db,
- const DDL_options_st &options,
+int mysql_create_db(THD *thd, const LEX_CSTRING *db, DDL_options_st options,
const Schema_specification_st *create);
bool mysql_alter_db(THD *thd, const LEX_CSTRING *db,
const Schema_specification_st *create);
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 233e0313121..731dd3cba71 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -565,7 +565,7 @@ void init_update_queries(void)
sql_command_flags[SQLCOM_CREATE_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_PACKAGE_BODY]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_ALTER_DB_UPGRADE]= CF_AUTO_COMMIT_TRANS;
- sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
+ sql_command_flags[SQLCOM_ALTER_DB]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_DB_CHANGE;
sql_command_flags[SQLCOM_RENAME_TABLE]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS;
sql_command_flags[SQLCOM_DROP_INDEX]= CF_CHANGES_DATA | CF_AUTO_COMMIT_TRANS | CF_REPORT_PROGRESS;
sql_command_flags[SQLCOM_CREATE_VIEW]= CF_CHANGES_DATA | CF_REEXECUTION_FRAGILE |
@@ -1486,7 +1486,7 @@ static bool deny_updates_if_read_only_option(THD *thd, TABLE_LIST *all_tables)
if (lex->sql_command == SQLCOM_DROP_TABLE && lex->tmp_table())
DBUG_RETURN(FALSE);
- /* Check if we created or dropped databases */
+ /* Check if we created, dropped, or renamed a database */
if ((sql_command_flags[lex->sql_command] & CF_DB_CHANGE))
DBUG_RETURN(TRUE);
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index ddc5a25bd07..ff51eb101d2 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -20281,6 +20281,10 @@ test_if_quick_select(JOIN_TAB *tab)
delete tab->select->quick;
tab->select->quick=0;
+
+ if (tab->table->file->inited != handler::NONE)
+ tab->table->file->ha_index_or_rnd_end();
+
int res= tab->select->test_quick_select(tab->join->thd, tab->keys,
(table_map) 0, HA_POS_ERROR, 0,
FALSE, /*remove where parts*/FALSE);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 1bf88de5f5e..490c95277f1 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -10401,14 +10401,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
error= 1;
break;
}
- if (to->next_number_field)
- {
- if (auto_increment_field_copied)
- to->auto_increment_field_not_null= TRUE;
- else
- to->next_number_field->reset();
- }
-
+
for (Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
{
copy_ptr->do_copy(copy_ptr);
@@ -10446,6 +10439,13 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
if (keep_versioned && to->versioned(VERS_TRX_ID))
to->vers_write= false;
+ if (to->next_number_field)
+ {
+ if (auto_increment_field_copied)
+ to->auto_increment_field_not_null= TRUE;
+ else
+ to->next_number_field->reset();
+ }
error= to->file->ha_write_row(to->record[0]);
to->auto_increment_field_not_null= FALSE;
if (unlikely(error))
diff --git a/sql/table.cc b/sql/table.cc
index ce7a34a8fe2..096711f851c 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -1029,7 +1029,7 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
while (pos < end)
{
uint type, expr_length;
- if (table->s->mysql_version >= 100202)
+ if (table->s->frm_version >= FRM_VER_EXPRESSSIONS)
{
uint field_nr, name_length;
/* see pack_expression() for how data is stored */
@@ -2270,7 +2270,7 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
uint pk_part_length= key_first_info->key_part[i].store_length;
if (keyinfo->ext_key_part_map & 1<<i)
{
- if (ext_key_length + pk_part_length > MAX_KEY_LENGTH)
+ if (ext_key_length + pk_part_length > MAX_DATA_LENGTH_FOR_KEY)
{
add_keyparts_for_this_key= i;
break;
@@ -2280,9 +2280,9 @@ int TABLE_SHARE::init_from_binary_frm_image(THD *thd, bool write,
}
}
- if (add_keyparts_for_this_key < (keyinfo->ext_key_parts -
- keyinfo->user_defined_key_parts))
- {
+ if (add_keyparts_for_this_key < keyinfo->ext_key_parts -
+ keyinfo->user_defined_key_parts)
+ {
share->ext_key_parts-= keyinfo->ext_key_parts;
key_part_map ext_key_part_map= keyinfo->ext_key_part_map;
keyinfo->ext_key_parts= keyinfo->user_defined_key_parts;
diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc
index 1c8af5eaf66..917a85e6c3b 100644
--- a/sql/temporary_tables.cc
+++ b/sql/temporary_tables.cc
@@ -1041,39 +1041,28 @@ TABLE *THD::find_temporary_table(const char *key, uint key_length,
/* A matching TMP_TABLE_SHARE is found. */
All_share_tables_list::Iterator tables_it(share->all_tmp_tables);
- while ((table= tables_it++))
+ bool found= false;
+ while (!found && (table= tables_it++))
{
switch (state)
{
- case TMP_TABLE_IN_USE:
- if (table->query_id > 0)
- {
- result= table;
- goto done;
- }
- break;
- case TMP_TABLE_NOT_IN_USE:
- if (table->query_id == 0)
- {
- result= table;
- goto done;
- }
- break;
- case TMP_TABLE_ANY:
- {
- result= table;
- goto done;
- }
- break;
- default: /* Invalid */
- DBUG_ASSERT(0);
- goto done;
+ case TMP_TABLE_IN_USE: found= table->query_id > 0; break;
+ case TMP_TABLE_NOT_IN_USE: found= table->query_id == 0; break;
+ case TMP_TABLE_ANY: found= true; break;
}
}
+ if (table && unlikely(table->m_needs_reopen))
+ {
+ share->all_tmp_tables.remove(table);
+ free_temporary_table(table);
+ it.rewind();
+ continue;
+ }
+ result= table;
+ break;
}
}
-done:
if (locked)
{
DBUG_ASSERT(m_tmp_tables_locked);
@@ -1154,8 +1143,7 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share,
@return Success false
Failure true
*/
-bool THD::find_and_use_tmp_table(const TABLE_LIST *tl,
- TABLE **out_table)
+bool THD::find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table)
{
DBUG_ENTER("THD::find_and_use_tmp_table");
@@ -1165,11 +1153,9 @@ bool THD::find_and_use_tmp_table(const TABLE_LIST *tl,
key_length= create_tmp_table_def_key(key, tl->get_db_name(),
tl->get_table_name());
- result=
- use_temporary_table(find_temporary_table(key, key_length,
- TMP_TABLE_NOT_IN_USE),
- out_table);
-
+ result= use_temporary_table(find_temporary_table(key, key_length,
+ TMP_TABLE_NOT_IN_USE),
+ out_table);
DBUG_RETURN(result);
}
diff --git a/storage/connect/global.h b/storage/connect/global.h
index 36e8a311124..dc1e149745f 100644
--- a/storage/connect/global.h
+++ b/storage/connect/global.h
@@ -219,11 +219,11 @@ DllExport LPCSTR PlugSetPath(LPSTR to, LPCSTR prefix, LPCSTR name, LPCSTR dir);
DllExport BOOL PlugIsAbsolutePath(LPCSTR path);
DllExport bool AllocSarea(PGLOBAL, uint);
DllExport void FreeSarea(PGLOBAL);
-DllExport BOOL PlugSubSet(PGLOBAL, void *, uint);
+DllExport BOOL PlugSubSet(void *, uint);
+DllExport void *PlugSubAlloc(PGLOBAL, void *, size_t);
DllExport char *PlugDup(PGLOBAL g, const char *str);
DllExport void *MakePtr(void *, OFFSET);
DllExport void htrc(char const *fmt, ...);
-//DllExport int GetTraceValue(void);
DllExport uint GetTraceValue(void);
#if defined(__cplusplus)
@@ -233,6 +233,6 @@ DllExport uint GetTraceValue(void);
/***********************************************************************/
/* Non exported routine declarations. */
/***********************************************************************/
-void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
+//void *PlugSubAlloc(PGLOBAL, void *, size_t); // Does throw
/*-------------------------- End of Global.H --------------------------*/
diff --git a/storage/connect/ha_connect.cc b/storage/connect/ha_connect.cc
index b781c61cdd1..e79682d331b 100644
--- a/storage/connect/ha_connect.cc
+++ b/storage/connect/ha_connect.cc
@@ -4189,7 +4189,7 @@ int ha_connect::rnd_pos(uchar *buf, uchar *pos)
rc= rnd_next(buf);
} else {
PGLOBAL g = GetPlug((table) ? table->in_use : NULL, xp);
- strcpy(g->Message, "Not supported by this table type");
+// strcpy(g->Message, "Not supported by this table type");
my_message(ER_ILLEGAL_HA, g->Message, MYF(0));
rc= HA_ERR_INTERNAL_ERROR;
} // endif SetRecpos
@@ -7307,7 +7307,7 @@ maria_declare_plugin(connect)
PLUGIN_LICENSE_GPL,
connect_init_func, /* Plugin Init */
connect_done_func, /* Plugin Deinit */
- 0x0107, /* version number (1.05) */
+ 0x0106, /* version number (1.06) */
NULL, /* status variables */
connect_system_variables, /* system variables */
"1.06.0008", /* string version */
diff --git a/storage/connect/jsonudf.cpp b/storage/connect/jsonudf.cpp
index 145c48b81d5..07a67e37379 100644
--- a/storage/connect/jsonudf.cpp
+++ b/storage/connect/jsonudf.cpp
@@ -3056,7 +3056,7 @@ my_bool json_array_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = (int)n;
return false;
@@ -3099,7 +3099,7 @@ void json_array_grp_clear(UDF_INIT *initid, char*, char*)
{
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JAR);
g->N = GetJsonGroupSize();
} // end of json_array_grp_clear
@@ -3133,7 +3133,7 @@ my_bool json_object_grp_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = (int)n;
return false;
@@ -3170,7 +3170,7 @@ void json_object_grp_clear(UDF_INIT *initid, char*, char*)
{
PGLOBAL g = (PGLOBAL)initid->ptr;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Activityp = (PACTIVITY)JsonNew(g, TYPE_JOB);
g->N = GetJsonGroupSize();
} // end of json_object_grp_clear
@@ -4419,7 +4419,7 @@ char *json_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
} else if (initid->const_item)
g->N = 1;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
fn = MakePSZ(g, args, 0);
if (args->arg_count > 1) {
@@ -5663,7 +5663,7 @@ char *jbin_file(UDF_INIT *initid, UDF_ARGS *args, char *result,
if (bsp && !bsp->Changed)
goto fin;
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
fn = MakePSZ(g, args, 0);
pretty = (args->arg_count > 2 && args->args[2]) ? (int)*(longlong*)args->args[2] : 3;
diff --git a/storage/connect/mysql-test/connect/r/jdbc_oracle.result b/storage/connect/mysql-test/connect/r/jdbc_oracle.result
index 2e36891a037..ec314c5f072 100644
--- a/storage/connect/mysql-test/connect/r/jdbc_oracle.result
+++ b/storage/connect/mysql-test/connect/r/jdbc_oracle.result
@@ -8,12 +8,19 @@ SELECT * FROM t2 WHERE command = 'drop table employee';
command number message
drop table employee 0 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
+Warnings:
+Warning 1105 Execute: java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
+
SELECT * FROM t2 WHERE command = 'create table employee (id int not null, name varchar(32), title char(16), salary number(8,2))';
command number message
create table employee (id int not null, name varchar(32), title char(16), salary number(8,2)) 0 Affected rows
+Warnings:
+Warning 1105 Affected rows
SELECT * FROM t2 WHERE command = "insert into employee values(4567,'Johnson', 'Engineer', 12560.50)";
command number message
insert into employee values(4567,'Johnson', 'Engineer', 12560.50) 1 Affected rows
+Warnings:
+Warning 1105 Affected rows
CREATE TABLE t1 ENGINE=CONNECT TABLE_TYPE=JDBC CATFUNC=tables
CONNECTION='jdbc:oracle:thin:@localhost:1521:xe'
OPTION_LIST='User=system,Password=manager';
@@ -27,8 +34,8 @@ OPTION_LIST='User=system,Password=manager';
SELECT * FROM t1;
Table_Cat Table_Schema Table_Name Column_Name Data_Type Type_Name Column_Size Buffer_Length Decimal_Digits Radix Nullable Remarks
NULL SYSTEM EMPLOYEE ID 3 NUMBER 38 0 0 10 0 NULL
-NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 0 10 1 NULL
-NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 0 10 1 NULL
+NULL SYSTEM EMPLOYEE NAME 12 VARCHAR2 32 0 NULL 10 1 NULL
+NULL SYSTEM EMPLOYEE TITLE 1 CHAR 16 0 NULL 10 1 NULL
NULL SYSTEM EMPLOYEE SALARY 3 NUMBER 8 0 2 10 1 NULL
DROP TABLE t1;
CREATE SERVER 'oracle' FOREIGN DATA WRAPPER 'oracle.jdbc.driver.OracleDriver' OPTIONS (
@@ -52,7 +59,7 @@ Note 1105 EMPLOYEE: 1 affected rows
SELECT * FROM t1;
ID NAME TITLE SALARY
4567 Trump Engineer 12560.50
-6214 Clinton Retired 0.00
+6214 Clinton Retired NULL
DELETE FROM t1 WHERE id = 6214;
Warnings:
Note 1105 EMPLOYEE: 1 affected rows
@@ -63,8 +70,7 @@ DROP TABLE t1;
SELECT * FROM t2 WHERE command = 'drop table employee';
command number message
drop table employee 0 Affected rows
+Warnings:
+Warning 1105 Affected rows
DROP TABLE t2;
DROP SERVER 'oracle';
-SET GLOBAL connect_jvm_path=NULL;
-SET GLOBAL connect_class_path=NULL;
-SET GLOBAL time_zone = SYSTEM;
diff --git a/storage/connect/plugutil.cpp b/storage/connect/plugutil.cpp
index 887527e38ab..048f00be75f 100644
--- a/storage/connect/plugutil.cpp
+++ b/storage/connect/plugutil.cpp
@@ -514,27 +514,31 @@ void FreeSarea(PGLOBAL g)
/* Here there should be some verification done such as validity of */
/* the address and size not larger than memory size. */
/***********************************************************************/
-BOOL PlugSubSet(PGLOBAL g __attribute__((unused)), void *memp, uint size)
+BOOL PlugSubSet(void *memp, uint size)
{
PPOOLHEADER pph = (PPOOLHEADER)memp;
pph->To_Free = (OFFSET)sizeof(POOLHEADER);
pph->FreeBlk = size - pph->To_Free;
-
return FALSE;
} /* end of PlugSubSet */
/***********************************************************************/
+/* Use it to export a function that do throwing. */
+/***********************************************************************/
+void *DoThrow(int n)
+{
+ throw n;
+} /* end of DoThrow */
+
+/***********************************************************************/
/* Program for sub-allocating one item in a storage area. */
-/* Note: SubAlloc routines of OS/2 are no more used to increase the */
-/* code portability and avoid problems when a grammar compiled under */
-/* one version of OS/2 is used under another version. */
-/* The simple way things are done here is also based on the fact */
-/* that no freeing of suballocated blocks is permitted in Plug. */
+/* The simple way things are done here is based on the fact */
+/* that no freeing of suballocated blocks is permitted in CONNECT. */
/***********************************************************************/
void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
- {
- PPOOLHEADER pph; /* Points on area header. */
+{
+ PPOOLHEADER pph; /* Points on area header. */
if (!memp)
/*******************************************************************/
@@ -559,8 +563,8 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
if (trace(1))
htrc("PlugSubAlloc: %s\n", g->Message);
- throw 1234;
- } /* endif size OS32 code */
+ DoThrow(1234);
+ } /* endif size OS32 code */
/*********************************************************************/
/* Do the suballocation the simplest way. */
@@ -574,7 +578,7 @@ void *PlugSubAlloc(PGLOBAL g, void *memp, size_t size)
memp, pph->To_Free, pph->FreeBlk);
return (memp);
- } /* end of PlugSubAlloc */
+} /* end of PlugSubAlloc */
/***********************************************************************/
/* Program for sub-allocating and copying a string in a storage area. */
diff --git a/storage/connect/reldef.cpp b/storage/connect/reldef.cpp
index e4f169575f8..30d8063d1a6 100644
--- a/storage/connect/reldef.cpp
+++ b/storage/connect/reldef.cpp
@@ -522,8 +522,15 @@ PTABDEF OEMDEF::GetXdef(PGLOBAL g)
// Get the function returning an instance of the external DEF class
if (!(getdef = (XGETDEF)GetProcAddress((HINSTANCE)Hdll, getname))) {
- sprintf(g->Message, MSG(PROCADD_ERROR), GetLastError(), getname);
- FreeLibrary((HMODULE)Hdll);
+ char buf[256];
+ DWORD rc = GetLastError();
+
+ sprintf(g->Message, MSG(PROCADD_ERROR), rc, getname);
+ FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS, NULL, rc, 0,
+ (LPTSTR)buf, sizeof(buf), NULL);
+ strcat(strcat(g->Message, ": "), buf);
+ FreeLibrary((HMODULE)Hdll);
return NULL;
} // endif getdef
#else // !__WIN__
diff --git a/storage/connect/tabfmt.h b/storage/connect/tabfmt.h
index 396bba568ff..10f0757c60b 100644
--- a/storage/connect/tabfmt.h
+++ b/storage/connect/tabfmt.h
@@ -13,7 +13,7 @@ typedef class TDBFMT *PTDBFMT;
/***********************************************************************/
/* Functions used externally. */
/***********************************************************************/
-PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info);
+DllExport PQRYRES CSVColumns(PGLOBAL g, PCSZ dp, PTOS topt, bool info);
/***********************************************************************/
/* CSV table. */
diff --git a/storage/connect/tabjson.cpp b/storage/connect/tabjson.cpp
index 9e4f5ab987d..d20e793ff88 100644
--- a/storage/connect/tabjson.cpp
+++ b/storage/connect/tabjson.cpp
@@ -299,7 +299,7 @@ int JSONDISC::GetColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt)
memset(G, 0, sizeof(GLOBAL));
G->Sarea_Size = tdp->Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
G->jump_level = 0;
tjnp->SetG(G);
@@ -670,7 +670,7 @@ PTDB JSONDEF::GetTable(PGLOBAL g, MODE m)
memset(G, 0, sizeof(GLOBAL));
G->Sarea_Size = Lrecl * 10;
G->Sarea = PlugSubAlloc(g, NULL, G->Sarea_Size);
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
G->jump_level = 0;
((TDBJSN*)tdbp)->G = G;
} else {
@@ -963,7 +963,7 @@ int TDBJSN::ReadDB(PGLOBAL g)
return rc;
// Recover the memory used for parsing
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
if ((Row = ParseJson(G, To_Line, strlen(To_Line), &Pretty, &Comma))) {
Row = FindRow(g);
@@ -1079,13 +1079,13 @@ int TDBJSN::MakeTopTree(PGLOBAL g, PJSON jsp)
} // end of PrepareWriting
/***********************************************************************/
-/* WriteDB: Data Base write routine for DOS access method. */
+/* WriteDB: Data Base write routine for JSON access method. */
/***********************************************************************/
int TDBJSN::WriteDB(PGLOBAL g)
{
int rc = TDBDOS::WriteDB(g);
- PlugSubSet(G, G->Sarea, G->Sarea_Size);
+ PlugSubSet(G->Sarea, G->Sarea_Size);
Row->Clear();
return rc;
} // end of WriteDB
diff --git a/storage/connect/tabjson.h b/storage/connect/tabjson.h
index 2ff72905e86..fcbfe4ed1ec 100644
--- a/storage/connect/tabjson.h
+++ b/storage/connect/tabjson.h
@@ -1,11 +1,11 @@
/*************** tabjson H Declares Source Code File (.H) **************/
/* Name: tabjson.h Version 1.3 */
/* */
-/* (C) Copyright to the author Olivier BERTRAND 2014 - 2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2014 - 2018 */
/* */
/* This file contains the JSON classes declares. */
/***********************************************************************/
-#include "osutil.h"
+//#include "osutil.h" // Unuseful and bad for OEM
#include "block.h"
#include "colblk.h"
#include "json.h"
@@ -16,7 +16,7 @@ typedef class JSONDEF *PJDEF;
typedef class TDBJSON *PJTDB;
typedef class JSONCOL *PJCOL;
class TDBJSN;
-PQRYRES JSONColumns(PGLOBAL g, PCSZ db, PCSZ dsn, PTOS topt, bool info);
+DllExport PQRYRES JSONColumns(PGLOBAL, PCSZ, PCSZ, PTOS, bool);
/***********************************************************************/
/* The JSON tree node. Can be an Object or an Array. */
diff --git a/storage/connect/tabodbc.cpp b/storage/connect/tabodbc.cpp
index fddfb0c0420..0fa117c3d2f 100644
--- a/storage/connect/tabodbc.cpp
+++ b/storage/connect/tabodbc.cpp
@@ -5,7 +5,7 @@
/* */
/* COPYRIGHT: */
/* ---------- */
-/* (C) Copyright to the author Olivier BERTRAND 2000-2017 */
+/* (C) Copyright to the author Olivier BERTRAND 2000-2018 */
/* */
/* WHAT THIS PROGRAM DOES: */
/* ----------------------- */
@@ -95,23 +95,23 @@ bool ExactInfo(void);
/* Constructor. */
/***********************************************************************/
ODBCDEF::ODBCDEF(void)
- {
+{
Connect = NULL;
Catver = 0;
UseCnc = false;
- } // end of ODBCDEF constructor
+} // end of ODBCDEF constructor
/***********************************************************************/
/* DefineAM: define specific AM block values from XDB file. */
/***********************************************************************/
bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
- {
+{
Desc = Connect = GetStringCatInfo(g, "Connect", NULL);
if (!Connect && !Catfunc) {
sprintf(g->Message, "Missing connection for ODBC table %s", Name);
return true;
- } // endif Connect
+ } // endif Connect
if (EXTDEF::DefineAM(g, am, poff))
return true;
@@ -123,13 +123,13 @@ bool ODBCDEF::DefineAM(PGLOBAL g, LPCSTR am, int poff)
Qto= GetIntCatInfo("QueryTimeout", DEFAULT_QUERY_TIMEOUT);
UseCnc = GetBoolCatInfo("UseDSN", false);
return false;
- } // end of DefineAM
+} // end of DefineAM
/***********************************************************************/
/* GetTable: makes a new Table Description Block. */
/***********************************************************************/
PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
- {
+{
PTDB tdbp = NULL;
/*********************************************************************/
@@ -158,10 +158,10 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
tdbp = new(g) TDBMUL(tdbp);
else if (Multiple == 2)
strcpy(g->Message, MSG(NO_ODBC_MUL));
- } // endswitch Catfunc
+ } // endswitch Catfunc
return tdbp;
- } // end of GetTable
+} // end of GetTable
/* -------------------------- Class TDBODBC -------------------------- */
@@ -169,7 +169,7 @@ PTDB ODBCDEF::GetTable(PGLOBAL g, MODE m)
/* Implementation of the TDBODBC class. */
/***********************************************************************/
TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp)
- {
+{
Ocp = NULL;
Cnp = NULL;
@@ -191,19 +191,19 @@ TDBODBC::TDBODBC(PODEF tdp) : TDBEXT(tdp)
Ops.UseCnc = false;
} // endif tdp
- } // end of TDBODBC standard constructor
+} // end of TDBODBC standard constructor
TDBODBC::TDBODBC(PTDBODBC tdbp) : TDBEXT(tdbp)
- {
+{
Ocp = tdbp->Ocp; // is that right ?
Cnp = tdbp->Cnp;
Connect = tdbp->Connect;
Ops = tdbp->Ops;
- } // end of TDBODBC copy constructor
+} // end of TDBODBC copy constructor
// Method
PTDB TDBODBC::Clone(PTABS t)
- {
+{
PTDB tp;
PODBCCOL cp1, cp2;
PGLOBAL g = t->G; // Is this really useful ???
@@ -213,18 +213,18 @@ PTDB TDBODBC::Clone(PTABS t)
for (cp1 = (PODBCCOL)Columns; cp1; cp1 = (PODBCCOL)cp1->GetNext()) {
cp2 = new(g) ODBCCOL(cp1, tp); // Make a copy
NewPointer(t, cp1, cp2);
- } // endfor cp1
+ } // endfor cp1
return tp;
- } // end of CopyOne
+} // end of CopyOne
/***********************************************************************/
/* Allocate ODBC column description block. */
/***********************************************************************/
PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
+{
return new(g) ODBCCOL(cdp, this, cprec, n);
- } // end of MakeCol
+} // end of MakeCol
/***********************************************************************/
/* Extract the filename from connect string and return it. */
@@ -232,7 +232,7 @@ PCOL TDBODBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
/* with a place holder to be used by SetFile. */
/***********************************************************************/
PCSZ TDBODBC::GetFile(PGLOBAL g)
- {
+{
if (Connect) {
char *p1, *p2;
int i;
@@ -263,18 +263,18 @@ PCSZ TDBODBC::GetFile(PGLOBAL g)
memcpy(MulConn, Connect, p1 - Connect);
MulConn[p1 - Connect] = '\0';
strcat(strcat(MulConn, "%s"), (p2) ? p2 : ";");
- } // endif p1
+ } // endif p1
- } // endif Connect
+ } // endif Connect
return (DBQ) ? DBQ : (PSZ)"???";
- } // end of GetFile
+} // end of GetFile
/***********************************************************************/
/* Set DBQ and get the new file name into the connect string. */
/***********************************************************************/
void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
- {
+{
if (MulConn) {
int n = strlen(MulConn) + strlen(fn) - 1;
@@ -283,20 +283,20 @@ void TDBODBC::SetFile(PGLOBAL g, PCSZ fn)
// of having to reallocate it is reduced.
BufSize = n + 6;
Connect = (char*)PlugSubAlloc(g, NULL, BufSize);
- } // endif n
+ } // endif n
// Make the complete connect string
sprintf(Connect, MulConn, fn);
- } // endif MultConn
+ } // endif MultConn
DBQ = PlugDup(g, fn);
- } // end of SetFile
+} // end of SetFile
/***********************************************************************/
/* MakeInsert: make the Insert statement used with ODBC connection. */
/***********************************************************************/
bool TDBODBC::MakeInsert(PGLOBAL g)
- {
+{
PCSZ schmp = NULL;
char *catp = NULL, buf[NAM_LEN * 3];
int len = 0;
@@ -377,7 +377,7 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
} else
Query->Append(buf);
- } // endfor colp
+ } // endfor colp
Query->Append(") VALUES (");
@@ -390,32 +390,32 @@ bool TDBODBC::MakeInsert(PGLOBAL g)
Query->RepLast(')');
return oom;
- } // end of MakeInsert
+} // end of MakeInsert
/***********************************************************************/
/* ODBC Bind Parameter function. */
/***********************************************************************/
bool TDBODBC::BindParameters(PGLOBAL g)
- {
- PODBCCOL colp;
+{
+ PODBCCOL colp;
- for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
- colp->AllocateBuffers(g, 0);
+ for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
+ colp->AllocateBuffers(g, 0);
- if (Ocp->BindParam(colp))
- return true;
+ if (Ocp->BindParam(colp))
+ return true;
- } // endfor colp
+ } // endfor colp
- return false;
- } // end of BindParameters
+ return false;
+} // end of BindParameters
#if 0
/***********************************************************************/
/* MakeUpdate: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeUpdate(PGLOBAL g)
- {
+{
char *qc, *stmt = NULL, cmd[8], tab[96], end[1024];
stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
@@ -440,60 +440,60 @@ char *TDBODBC::MakeUpdate(PGLOBAL g)
strcat(stmt, end);
return stmt;
- } // end of MakeUpdate
+} // end of MakeUpdate
/***********************************************************************/
/* MakeDelete: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
char *TDBODBC::MakeDelete(PGLOBAL g)
- {
- char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
-
- stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
- memset(end, 0, sizeof(end));
-
- if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
- sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
- qc = Ocp->GetQuoteChar();
- else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
- qc = (Quoted) ? Quote : "";
- else {
- strcpy(g->Message, "Cannot use this DELETE command");
- return NULL;
- } // endif sscanf
-
- assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
- strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
-
- if (*end) {
- for (int i = 0; end[i]; i++)
- if (end[i] == '`')
- end[i] = *qc;
-
- strcat(stmt, end);
- } // endif end
-
- return stmt;
- } // end of MakeDelete
+{
+ char *qc, *stmt = NULL, cmd[8], from[8], tab[96], end[512];
+
+ stmt = (char*)PlugSubAlloc(g, NULL, strlen(Qrystr) + 64);
+ memset(end, 0, sizeof(end));
+
+ if (sscanf(Qrystr, "%s %s `%[^`]`%511c", cmd, from, tab, end) > 2 ||
+ sscanf(Qrystr, "%s %s \"%[^\"]\"%511c", cmd, from, tab, end) > 2)
+ qc = Ocp->GetQuoteChar();
+ else if (sscanf(Qrystr, "%s %s %s%511c", cmd, from, tab, end) > 2)
+ qc = (Quoted) ? Quote : "";
+ else {
+ strcpy(g->Message, "Cannot use this DELETE command");
+ return NULL;
+ } // endif sscanf
+
+ assert(!stricmp(cmd, "delete") && !stricmp(from, "from"));
+ strcat(strcat(strcat(strcpy(stmt, "DELETE FROM "), qc), TableName), qc);
+
+ if (*end) {
+ for (int i = 0; end[i]; i++)
+ if (end[i] == '`')
+ end[i] = *qc;
+
+ strcat(stmt, end);
+ } // endif end
+
+ return stmt;
+} // end of MakeDelete
#endif // 0
/***********************************************************************/
/* ResetSize: call by TDBMUL when calculating size estimate. */
/***********************************************************************/
void TDBODBC::ResetSize(void)
- {
+{
MaxSize = -1;
if (Ocp && Ocp->IsOpen())
Ocp->Close();
- } // end of ResetSize
+} // end of ResetSize
/***********************************************************************/
/* ODBC Cardinality: returns table size in number of rows. */
/***********************************************************************/
int TDBODBC::Cardinality(PGLOBAL g)
- {
+{
if (!g)
return (Mode == MODE_ANY && !Srcdef) ? 1 : 0;
@@ -526,7 +526,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
Cardinal = 10; // To make MySQL happy
return Cardinal;
- } // end of Cardinality
+} // end of Cardinality
/***********************************************************************/
/* ODBC Access Method opening routine. */
@@ -535,7 +535,7 @@ int TDBODBC::Cardinality(PGLOBAL g)
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool TDBODBC::OpenDB(PGLOBAL g)
- {
+{
bool rc = true;
if (trace(1))
@@ -571,7 +571,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
Fpos = 0;
Curpos = 1;
return false;
- } // endif use
+ } // endif use
/*********************************************************************/
/* Open an ODBC connection for this table. */
@@ -593,7 +593,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
Use = USE_OPEN; // Do it now in case we are recursively called
/*********************************************************************/
- /* Make the command and allocate whatever is used for getting results. */
+ /* Make the command and allocate whatever is used for getting results*/
/*********************************************************************/
if (Mode == MODE_READ || Mode == MODE_READX) {
if (Memory > 1 && !Srcdef) {
@@ -624,7 +624,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} else
return true;
- } // endif Memory
+ } // endif Memory
if (!(rc = MakeSQL(g, false))) {
for (PODBCCOL colp = (PODBCCOL)Columns; colp;
@@ -635,7 +635,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
rc = (Mode == MODE_READ)
? ((Rows = Ocp->ExecDirectSQL(Query->GetStr(), (PODBCCOL)Columns)) < 0)
: false;
- } // endif rc
+ } // endif rc
} else if (Mode == MODE_INSERT) {
if (!(rc = MakeInsert(g))) {
@@ -645,7 +645,7 @@ bool TDBODBC::OpenDB(PGLOBAL g)
} else
rc = BindParameters(g);
- } // endif rc
+ } // endif rc
} else if (Mode == MODE_UPDATE || Mode == MODE_DELETE) {
rc = false; // wait for CheckCond before calling MakeCommand(g);
@@ -655,30 +655,30 @@ bool TDBODBC::OpenDB(PGLOBAL g)
if (rc) {
Ocp->Close();
return true;
- } // endif rc
+ } // endif rc
/*********************************************************************/
/* Reset statistics values. */
/*********************************************************************/
num_read = num_there = num_eq[0] = num_eq[1] = 0;
return false;
- } // end of OpenDB
+} // end of OpenDB
#if 0
/***********************************************************************/
/* GetRecpos: return the position of last read record. */
/***********************************************************************/
int TDBODBC::GetRecpos(void)
- {
+{
return Fpos;
- } // end of GetRecpos
+} // end of GetRecpos
#endif // 0
/***********************************************************************/
/* SetRecpos: set the position of next read record. */
/***********************************************************************/
bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
- {
+{
if (Ocp->m_Full) {
Fpos = 0;
CurNum = recpos - 1;
@@ -696,14 +696,15 @@ bool TDBODBC::SetRecpos(PGLOBAL g, int recpos)
} // endif recpos
} else {
- strcpy(g->Message, "This action requires a scrollable cursor");
+ strcpy(g->Message,
+ "This action requires Memory setting or a scrollable cursor");
return true;
} // endif's
// Indicate the table position was externally set
Placed = true;
return false;
- } // end of SetRecpos
+} // end of SetRecpos
/***********************************************************************/
/* Data Base indexed read routine for ODBC access method. */
@@ -721,7 +722,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
Rows = Ocp->ExecDirectSQL((char*)Query->GetStr(), (PODBCCOL)Columns);
Mode = MODE_READ;
return (Rows < 0);
- } // endif key
+ } // endif key
return false;
} else {
@@ -737,7 +738,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
if ((To_CondFil = hc->CheckCond(g, To_CondFil, Cond)))
PlugSubAlloc(g, NULL, strlen(To_CondFil->Body) + 1);
- } // endif active_index
+ } // endif active_index
if (To_CondFil)
if (Query->Append(" AND ") || Query->Append(To_CondFil->Body)) {
@@ -762,7 +763,7 @@ bool TDBODBC::ReadKey(PGLOBAL g, OPVAL op, const key_range *kr)
/* VRDNDOS: Data Base read routine for odbc access method. */
/***********************************************************************/
int TDBODBC::ReadDB(PGLOBAL g)
- {
+{
int rc;
if (trace(2))
@@ -784,7 +785,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
} else
return RC_FX; // Error
- } // endif Mode
+ } // endif Mode
/*********************************************************************/
/* Now start the reading process. */
@@ -813,7 +814,7 @@ int TDBODBC::ReadDB(PGLOBAL g)
Qrp->Nblin++;
Fpos++; // Used for memory and pos
- } // endif rc
+ } // endif rc
} // endif Placed
@@ -821,13 +822,13 @@ int TDBODBC::ReadDB(PGLOBAL g)
htrc(" Read: Rbuf=%d rc=%d\n", Rbuf, rc);
return rc;
- } // end of ReadDB
+} // end of ReadDB
/***********************************************************************/
/* Data Base Insert write routine for ODBC access method. */
/***********************************************************************/
int TDBODBC::WriteDB(PGLOBAL g)
- {
+{
int n = Ocp->ExecuteSQL();
if (n < 0) {
@@ -837,13 +838,13 @@ int TDBODBC::WriteDB(PGLOBAL g)
AftRows += n;
return RC_OK;
- } // end of WriteDB
+} // end of WriteDB
/***********************************************************************/
/* Data Base delete line routine for ODBC access method. */
/***********************************************************************/
int TDBODBC::DeleteDB(PGLOBAL g, int irc)
- {
+{
if (irc == RC_FX) {
if (!Query && MakeCommand(g))
return RC_FX;
@@ -863,13 +864,13 @@ int TDBODBC::DeleteDB(PGLOBAL g, int irc)
} else
return RC_OK; // Ignore
- } // end of DeleteDB
+} // end of DeleteDB
/***********************************************************************/
/* Data Base close routine for ODBC access method. */
/***********************************************************************/
void TDBODBC::CloseDB(PGLOBAL g)
- {
+{
if (Ocp)
Ocp->Close();
@@ -877,7 +878,7 @@ void TDBODBC::CloseDB(PGLOBAL g)
if (trace(1))
htrc("ODBC CloseDB: closing %s\n", Name);
- } // end of CloseDB
+} // end of CloseDB
/* --------------------------- ODBCCOL ------------------------------- */
@@ -886,33 +887,33 @@ void TDBODBC::CloseDB(PGLOBAL g)
/***********************************************************************/
ODBCCOL::ODBCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: EXTCOL(cdp, tdbp, cprec, i, am)
- {
+{
// Set additional ODBC access method information for column.
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
- } // end of ODBCCOL constructor
+} // end of ODBCCOL constructor
/***********************************************************************/
/* ODBCCOL private constructor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(void) : EXTCOL()
- {
+{
Slen = 0;
StrLen = &Slen;
Sqlbuf = NULL;
- } // end of ODBCCOL constructor
+} // end of ODBCCOL constructor
/***********************************************************************/
/* ODBCCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
- {
+{
Slen = col1->Slen;
StrLen = col1->StrLen;
Sqlbuf = col1->Sqlbuf;
- } // end of ODBCCOL copy constructor
+} // end of ODBCCOL copy constructor
/***********************************************************************/
/* ReadColumn: when SQLFetch is used there is nothing to do as the */
@@ -920,7 +921,7 @@ ODBCCOL::ODBCCOL(ODBCCOL *col1, PTDB tdbp) : EXTCOL(col1, tdbp)
/* when calculating MaxSize (Bufp is NULL even when Rows is not). */
/***********************************************************************/
void ODBCCOL::ReadColumn(PGLOBAL g)
- {
+{
PTDBODBC tdbp = (PTDBODBC)To_Tdb;
int i = tdbp->Fpos - 1, n = tdbp->CurNum;
@@ -953,7 +954,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
else
Value->SetValue_pvblk(Blkp, n);
- } // endif Bufp
+ } // endif Bufp
if (Buf_Type == TYPE_DATE) {
struct tm dbtime;
@@ -980,7 +981,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
htrc("ODBC Column %s: rows=%d buf=%p type=%d value=%s\n",
Name, tdbp->Rows, Bufp, Buf_Type, Value->GetCharString(buf));
- } // endif trace
+ } // endif trace
put:
if (tdbp->Memory != 2)
@@ -997,7 +998,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
} else
Crp->Kdata->SetValue(Value, i);
- } // end of ReadColumn
+} // end of ReadColumn
/***********************************************************************/
/* AllocateBuffers: allocate the extended buffer for SQLExtendedFetch */
@@ -1005,7 +1006,7 @@ void ODBCCOL::ReadColumn(PGLOBAL g)
/* for the ending null character. */
/***********************************************************************/
void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows)
- {
+{
if (Buf_Type == TYPE_DATE)
Sqlbuf = (TIMESTAMP_STRUCT*)PlugSubAlloc(g, NULL,
sizeof(TIMESTAMP_STRUCT));
@@ -1019,31 +1020,31 @@ void ODBCCOL::AllocateBuffers(PGLOBAL g, int rows)
Blkp = AllocValBlock(g, NULL, Buf_Type, rows, GetBuflen(),
GetScale(), true, false, false);
Bufp = Blkp->GetValPointer();
- } // endelse
+ } // endelse
if (rows > 1)
StrLen = (SQLLEN *)PlugSubAlloc(g, NULL, rows * sizeof(SQLLEN));
- } // end of AllocateBuffers
+} // end of AllocateBuffers
/***********************************************************************/
/* Returns the buffer to use for Fetch or Extended Fetch. */
/***********************************************************************/
void *ODBCCOL::GetBuffer(DWORD rows)
- {
+{
if (rows && To_Tdb) {
assert(rows == (DWORD)((TDBODBC*)To_Tdb)->Rows);
return Bufp;
} else
return (Buf_Type == TYPE_DATE) ? Sqlbuf : Value->GetTo_Val();
- } // end of GetBuffer
+} // end of GetBuffer
/***********************************************************************/
/* Returns the buffer length to use for Fetch or Extended Fetch. */
/***********************************************************************/
SWORD ODBCCOL::GetBuflen(void)
- {
+{
SWORD flen;
switch (Buf_Type) {
@@ -1059,13 +1060,13 @@ SWORD ODBCCOL::GetBuflen(void)
} // endswitch Buf_Type
return flen;
- } // end of GetBuflen
+} // end of GetBuflen
/***********************************************************************/
/* WriteColumn: make sure the bind buffer is updated. */
/***********************************************************************/
void ODBCCOL::WriteColumn(PGLOBAL g)
- {
+{
/*********************************************************************/
/* Do convert the column value if necessary. */
/*********************************************************************/
@@ -1095,7 +1096,7 @@ void ODBCCOL::WriteColumn(PGLOBAL g)
*StrLen = (Value->IsNull()) ? SQL_NULL_DATA :
(IsTypeChar(Buf_Type)) ? SQL_NTS : 0;
- } // end of WriteColumn
+} // end of WriteColumn
/* -------------------------- Class TDBXDBC -------------------------- */
@@ -1119,7 +1120,7 @@ TDBXDBC::TDBXDBC(PTDBXDBC tdbp) : TDBODBC(tdbp)
} // end of TDBXDBC copy constructor
PTDB TDBXDBC::Clone(PTABS t)
- {
+{
PTDB tp;
PXSRCCOL cp1, cp2;
PGLOBAL g = t->G; // Is this really useful ???
@@ -1129,29 +1130,29 @@ PTDB TDBXDBC::Clone(PTABS t)
for (cp1 = (PXSRCCOL)Columns; cp1; cp1 = (PXSRCCOL)cp1->GetNext()) {
cp2 = new(g) XSRCCOL(cp1, tp); // Make a copy
NewPointer(t, cp1, cp2);
- } // endfor cp1
+ } // endfor cp1
return tp;
- } // end of CopyOne
+} // end of CopyOne
/***********************************************************************/
/* Allocate XSRC column description block. */
/***********************************************************************/
PCOL TDBXDBC::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
- {
+{
PXSRCCOL colp = new(g) XSRCCOL(cdp, this, cprec, n);
if (!colp->Flag)
Cmdcol = colp->GetName();
return colp;
- } // end of MakeCol
+} // end of MakeCol
/***********************************************************************/
/* MakeCMD: make the SQL statement to send to ODBC connection. */
/***********************************************************************/
PCMD TDBXDBC::MakeCMD(PGLOBAL g)
- {
+{
PCMD xcmd = NULL;
if (To_CondFil) {
@@ -1171,14 +1172,14 @@ PCMD TDBXDBC::MakeCMD(PGLOBAL g)
xcmd = new(g) CMD(g, Srcdef);
return xcmd;
- } // end of MakeCMD
+} // end of MakeCMD
#if 0
/***********************************************************************/
/* ODBC Bind Parameter function. */
/***********************************************************************/
bool TDBXDBC::BindParameters(PGLOBAL g)
- {
+{
PODBCCOL colp;
for (colp = (PODBCCOL)Columns; colp; colp = (PODBCCOL)colp->Next) {
@@ -1190,19 +1191,19 @@ bool TDBXDBC::BindParameters(PGLOBAL g)
} // endfor colp
return false;
- } // end of BindParameters
+} // end of BindParameters
#endif // 0
/***********************************************************************/
/* XDBC GetMaxSize: returns table size (not always one row). */
/***********************************************************************/
int TDBXDBC::GetMaxSize(PGLOBAL g)
- {
+{
if (MaxSize < 0)
MaxSize = 10; // Just a guess
return MaxSize;
- } // end of GetMaxSize
+} // end of GetMaxSize
/***********************************************************************/
/* ODBC Access Method opening routine. */
@@ -1211,7 +1212,7 @@ int TDBXDBC::GetMaxSize(PGLOBAL g)
/* join block of next table if it exists or else are discarted. */
/***********************************************************************/
bool TDBXDBC::OpenDB(PGLOBAL g)
- {
+{
bool rc = false;
if (trace(1))
@@ -1221,7 +1222,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
if (Use == USE_OPEN) {
strcpy(g->Message, "Multiple execution is not allowed");
return true;
- } // endif use
+ } // endif use
/*********************************************************************/
/* Open an ODBC connection for this table. */
@@ -1243,7 +1244,7 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
if (Mode != MODE_READ && Mode != MODE_READX) {
strcpy(g->Message, "No INSERT/DELETE/UPDATE of XDBC tables");
return true;
- } // endif Mode
+ } // endif Mode
/*********************************************************************/
/* Get the command to execute. */
@@ -1256,13 +1257,13 @@ bool TDBXDBC::OpenDB(PGLOBAL g)
Rows = 1;
return false;
- } // end of OpenDB
+} // end of OpenDB
/***********************************************************************/
/* ReadDB: Data Base read routine for xdbc access method. */
/***********************************************************************/
int TDBXDBC::ReadDB(PGLOBAL g)
- {
+{
if (Cmdlist) {
if (!Query)
Query = new(g)STRING(g, 0, Cmdlist->Cmd);
@@ -1280,25 +1281,25 @@ int TDBXDBC::ReadDB(PGLOBAL g)
return RC_EF;
} // endif Cmdlist
- } // end of ReadDB
+} // end of ReadDB
/***********************************************************************/
-/* Data Base delete line routine for ODBC access method. */
+/* Data Base write line routine for XDBC access method. */
/***********************************************************************/
int TDBXDBC::WriteDB(PGLOBAL g)
- {
+{
strcpy(g->Message, "Execsrc tables are read only");
return RC_FX;
- } // end of DeleteDB
+} // end of DeleteDB
/***********************************************************************/
-/* Data Base delete line routine for ODBC access method. */
+/* Data Base delete line routine for XDBC access method. */
/***********************************************************************/
int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
- {
+{
strcpy(g->Message, MSG(NO_ODBC_DELETE));
return RC_FX;
- } // end of DeleteDB
+} // end of DeleteDB
/* --------------------------- XSRCCOL ------------------------------- */
@@ -1307,25 +1308,25 @@ int TDBXDBC::DeleteDB(PGLOBAL g, int irc)
/***********************************************************************/
XSRCCOL::XSRCCOL(PCOLDEF cdp, PTDB tdbp, PCOL cprec, int i, PCSZ am)
: ODBCCOL(cdp, tdbp, cprec, i, am)
- {
+{
// Set additional ODBC access method information for column.
Flag = cdp->GetOffset();
- } // end of XSRCCOL constructor
+} // end of XSRCCOL constructor
/***********************************************************************/
/* XSRCCOL constructor used for copying columns. */
/* tdbp is the pointer to the new table descriptor. */
/***********************************************************************/
XSRCCOL::XSRCCOL(XSRCCOL *col1, PTDB tdbp) : ODBCCOL(col1, tdbp)
- {
+{
Flag = col1->Flag;
- } // end of XSRCCOL copy constructor
+} // end of XSRCCOL copy constructor
/***********************************************************************/
/* ReadColumn: set column value according to Flag. */
/***********************************************************************/
void XSRCCOL::ReadColumn(PGLOBAL g)
- {
+{
PTDBXDBC tdbp = (PTDBXDBC)To_Tdb;
switch (Flag) {
@@ -1335,15 +1336,15 @@ void XSRCCOL::ReadColumn(PGLOBAL g)
default: Value->SetValue_psz("Invalid Flag"); break;
} // endswitch Flag
- } // end of ReadColumn
+} // end of ReadColumn
/***********************************************************************/
/* WriteColumn: Should never be called. */
/***********************************************************************/
void XSRCCOL::WriteColumn(PGLOBAL g)
- {
+{
// Should never be called
- } // end of WriteColumn
+} // end of WriteColumn
/* ---------------------------TDBDRV class --------------------------- */
@@ -1351,9 +1352,9 @@ void XSRCCOL::WriteColumn(PGLOBAL g)
/* GetResult: Get the list of ODBC drivers. */
/***********************************************************************/
PQRYRES TDBDRV::GetResult(PGLOBAL g)
- {
+{
return ODBCDrivers(g, Maxres, false);
- } // end of GetResult
+} // end of GetResult
/* ---------------------------TDBSRC class --------------------------- */
@@ -1361,9 +1362,9 @@ PQRYRES TDBDRV::GetResult(PGLOBAL g)
/* GetResult: Get the list of ODBC data sources. */
/***********************************************************************/
PQRYRES TDBSRC::GetResult(PGLOBAL g)
- {
+{
return ODBCDataSources(g, Maxres, false);
- } // end of GetResult
+} // end of GetResult
/* ---------------------------TDBOTB class --------------------------- */
@@ -1371,7 +1372,7 @@ PQRYRES TDBSRC::GetResult(PGLOBAL g)
/* TDBOTB class constructor. */
/***********************************************************************/
TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
- {
+{
Dsn = tdp->GetConnect();
Schema = tdp->GetTabschema();
Tab = tdp->GetTabname();
@@ -1381,15 +1382,15 @@ TDBOTB::TDBOTB(PODEF tdp) : TDBDRV(tdp)
Ops.Cto = tdp->Cto;
Ops.Qto = tdp->Qto;
Ops.UseCnc = tdp->UseCnc;
- } // end of TDBOTB constructor
+} // end of TDBOTB constructor
/***********************************************************************/
/* GetResult: Get the list of ODBC tables. */
/***********************************************************************/
PQRYRES TDBOTB::GetResult(PGLOBAL g)
- {
+{
return ODBCTables(g, Dsn, Schema, Tab, Tabtyp, Maxres, false, &Ops);
- } // end of GetResult
+} // end of GetResult
/* ---------------------------TDBOCL class --------------------------- */
@@ -1405,8 +1406,8 @@ TDBOCL::TDBOCL(PODEF tdp) : TDBOTB(tdp)
/* GetResult: Get the list of ODBC table columns. */
/***********************************************************************/
PQRYRES TDBOCL::GetResult(PGLOBAL g)
- {
+{
return ODBCColumns(g, Dsn, Schema, Tab, Colpat, Maxres, false, &Ops);
- } // end of GetResult
+} // end of GetResult
/* ------------------------ End of Tabodbc --------------------------- */
diff --git a/storage/connect/tabxml.cpp b/storage/connect/tabxml.cpp
index 16bc9f91017..573339bce35 100644
--- a/storage/connect/tabxml.cpp
+++ b/storage/connect/tabxml.cpp
@@ -682,6 +682,14 @@ PTDB TDBXML::Clone(PTABS t)
} // end of Clone
/***********************************************************************/
+/* Must not be in tabxml.h because of OEM tables */
+/***********************************************************************/
+const CHARSET_INFO *TDBXML::data_charset()
+{
+ return &my_charset_utf8_general_ci;
+} // end of data_charset
+
+/***********************************************************************/
/* Allocate XML column description block. */
/***********************************************************************/
PCOL TDBXML::MakeCol(PGLOBAL g, PCOLDEF cdp, PCOL cprec, int n)
@@ -2209,8 +2217,9 @@ void XPOSCOL::WriteColumn(PGLOBAL g)
TDBXCT::TDBXCT(PXMLDEF tdp) : TDBCAT(tdp)
{
Topt = tdp->GetTopt();
- Db = (char*)tdp->GetDB();
- Tabn = tdp->Tabname;
+ //Db = (char*)tdp->GetDB();
+ Db = (char*)tdp->Schema;
+ Tabn = tdp->Tabname;
} // end of TDBXCT constructor
/***********************************************************************/
diff --git a/storage/connect/tabxml.h b/storage/connect/tabxml.h
index f55b7d98de7..102767e965a 100644
--- a/storage/connect/tabxml.h
+++ b/storage/connect/tabxml.h
@@ -9,6 +9,8 @@ typedef class XMLDEF *PXMLDEF;
typedef class TDBXML *PTDBXML;
typedef class XMLCOL *PXMLCOL;
+DllExport PQRYRES XMLColumns(PGLOBAL, char *, char *, PTOS, bool);
+
/* --------------------------- XML classes --------------------------- */
/***********************************************************************/
@@ -100,8 +102,7 @@ class DllExport TDBXML : public TDBASE {
virtual int DeleteDB(PGLOBAL g, int irc);
virtual void CloseDB(PGLOBAL g);
virtual int CheckWrite(PGLOBAL g) {Checked = true; return 0;}
- virtual const CHARSET_INFO *data_charset()
- {return &my_charset_utf8_general_ci;}
+ virtual const CHARSET_INFO *data_charset();
protected:
// Members
diff --git a/storage/connect/user_connect.cc b/storage/connect/user_connect.cc
index e2d3b664aeb..a2a8faf9b38 100644
--- a/storage/connect/user_connect.cc
+++ b/storage/connect/user_connect.cc
@@ -107,7 +107,7 @@ bool user_connect::user_init()
g= PlugInit(NULL, worksize);
// Check whether the initialization is complete
- if (!g || !g->Sarea || PlugSubSet(g, g->Sarea, g->Sarea_Size)
+ if (!g || !g->Sarea || PlugSubSet(g->Sarea, g->Sarea_Size)
|| !(dup= PlgMakeUser(g))) {
if (g)
printf("%s\n", g->Message);
@@ -172,7 +172,7 @@ bool user_connect::CheckCleanup(bool force)
} // endif worksize
- PlugSubSet(g, g->Sarea, g->Sarea_Size);
+ PlugSubSet(g->Sarea, g->Sarea_Size);
g->Xchk = NULL;
g->Createas = 0;
g->Alchecked = 0;
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index b8f9a55b148..e2b8d771e83 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -968,9 +968,20 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index)
field_max_size = dict_col_get_max_size(col);
if (UNIV_UNLIKELY(!field_max_size)) {
switch (col->mtype) {
+ case DATA_VARCHAR:
+ if (!comp
+ && (!strcmp(index->table->name.m_name,
+ "SYS_FOREIGN")
+ || !strcmp(index->table->name.m_name,
+ "SYS_FOREIGN_COLS"))) {
+ break;
+ }
+ /* fall through */
+ case DATA_VARMYSQL:
case DATA_CHAR:
case DATA_MYSQL:
- /* CHAR(0) is a possible data type.
+ /* CHAR(0) and VARCHAR(0) are possible
+ data type definitions in MariaDB.
The InnoDB internal SQL parser maps
CHAR to DATA_VARCHAR, so DATA_CHAR (or
DATA_MYSQL) is only coming from the
@@ -986,6 +997,7 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index)
}
continue;
}
+
/* SYS_FOREIGN.ID is defined as CHAR in the
InnoDB internal SQL parser, which translates
into the incorrect VARCHAR(0). InnoDB does
@@ -1002,6 +1014,7 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index)
|| !strcmp(index->table->name.m_name,
"SYS_FOREIGN_COLS"));
ut_ad(!comp);
+ ut_ad(col->mtype == DATA_VARCHAR);
rec_max_size += (srv_page_size == UNIV_PAGE_SIZE_MAX)
? REDUNDANT_REC_MAX_DATA_SIZE
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index d1e008d8be4..3d5a6a161c4 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -526,13 +526,13 @@ decompress_with_slot:
/* Verify encryption checksum before we even try to
decrypt. */
if (!fil_space_verify_crypt_checksum(dst_frame, bpage->size)) {
+decrypt_failed:
ib::error() << "Encrypted page " << bpage->id
<< " in file " << space->chain.start->name
<< " looks corrupted; key_version="
<< mach_read_from_4(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ dst_frame);
-decrypt_failed:
/* Mark page encrypted in case it should be. */
if (space->crypt_data->type
!= CRYPT_SCHEME_UNENCRYPTED) {
@@ -4448,7 +4448,7 @@ loop:
<< ". The most probable cause"
" of this error may be that the"
" table has been corrupted."
- " See https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/";
+ " See https://mariadb.com/kb/en/library/innodb-recovery-modes/";
}
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index 9d90c287ffc..57bb736d230 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -328,14 +328,14 @@ ulint fil_page_decompress(byte* tmp_buf, byte* buf)
case PAGE_ZLIB_ALGORITHM:
{
uLong len = srv_page_size;
- if (Z_OK != uncompress(tmp_buf, &len,
+ if (Z_OK == uncompress(tmp_buf, &len,
buf + header_len,
uLong(actual_size))
- && len != srv_page_size) {
- return 0;
+ && len == srv_page_size) {
+ break;
}
}
- break;
+ return 0;
#ifdef HAVE_LZ4
case PAGE_LZ4_ALGORITHM:
if (LZ4_decompress_safe(reinterpret_cast<const char*>(buf)
diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc
index 66a6d57d986..ca9eb16e506 100644
--- a/storage/innobase/gis/gis0sea.cc
+++ b/storage/innobase/gis/gis0sea.cc
@@ -772,7 +772,7 @@ rtr_page_get_father_node_ptr(
error << ". You should dump + drop + reimport the table to"
" fix the corruption. If the crash happens at"
" database startup, see "
- "https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/"
+ "https://mariadb.com/kb/en/library/innodb-recovery-modes/"
" about forcing"
" recovery. Then dump + drop + reimport.";
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index d90088f2c5e..84ae2580e4f 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -249,10 +249,10 @@ void set_my_errno(int err)
errno = err;
}
-static uint mysql_fields(const TABLE *table)
+static uint omits_virtual_cols(const TABLE_SHARE &share)
{
- return table->s->frm_version < FRM_VER_EXPRESSSIONS
- ? table->s->stored_fields : table->s->fields;
+ return share.frm_version < FRM_VER_EXPRESSSIONS &&
+ share.virtual_fields;
}
/** Checks whether the file name belongs to a partition of a table.
@@ -6114,12 +6114,13 @@ no_such_table:
DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
}
- size_t n_fields = mysql_fields(table);
+ size_t n_fields = omits_virtual_cols(*table_share)
+ ? table_share->stored_fields : table_share->fields;
size_t n_cols = dict_table_get_n_user_cols(ib_table)
+ dict_table_get_n_v_cols(ib_table)
- !!DICT_TF2_FLAG_IS_SET(ib_table, DICT_TF2_FTS_HAS_DOC_ID);
- if (n_cols != n_fields) {
+ if (UNIV_UNLIKELY(n_cols != n_fields)) {
ib::warn() << "Table " << norm_name << " contains "
<< n_cols << " user"
" defined columns in InnoDB, but " << n_fields
@@ -7279,6 +7280,10 @@ build_template_needs_field(
{
const Field* field = table->field[i];
+ if (innobase_is_v_fld(field) && omits_virtual_cols(*table->s)) {
+ return NULL;
+ }
+
if (!index_contains) {
if (read_just_key) {
/* If this is a 'key read', we do not need
@@ -7303,7 +7308,6 @@ build_template_needs_field(
if (fetch_primary_key_cols
&& dict_table_col_in_clustered_key(index->table, i - num_v)) {
/* This field is needed in the query */
-
return(field);
}
@@ -7356,17 +7360,11 @@ build_template_field(
templ = prebuilt->mysql_template + prebuilt->n_template++;
UNIV_MEM_INVALID(templ, sizeof *templ);
-
- if (innobase_is_v_fld(field)) {
- templ->is_virtual = true;
- col = &dict_table_get_nth_v_col(index->table, v_no)->m_col;
- } else {
- templ->is_virtual = false;
- col = dict_table_get_nth_col(index->table, i);
- }
+ templ->is_virtual = innobase_is_v_fld(field);
if (!templ->is_virtual) {
templ->col_no = i;
+ col = dict_table_get_nth_col(index->table, i);
templ->clust_rec_field_no = dict_col_get_clust_pos(
col, clust_index);
/* If clustered index record field is not found, lets print out
@@ -7405,7 +7403,7 @@ build_template_field(
<< table->field[j]->field_name.str;
}
- ib::error() << "Clustered record field for column " << i
+ ib::fatal() << "Clustered record field for column " << i
<< " not found table n_user_defined "
<< clust_index->n_user_defined_cols
<< " index n_user_defined "
@@ -7422,8 +7420,6 @@ build_template_field(
<< table->s->stored_fields
<< " query "
<< innobase_get_stmt_unsafe(current_thd, &size);
-
- ut_a(templ->clust_rec_field_no != ULINT_UNDEFINED);
}
templ->rec_field_is_prefix = FALSE;
templ->rec_prefix_field_no = ULINT_UNDEFINED;
@@ -7441,6 +7437,8 @@ build_template_field(
&templ->rec_prefix_field_no);
}
} else {
+ ut_ad(!omits_virtual_cols(*table->s));
+ col = &dict_table_get_nth_v_col(index->table, v_no)->m_col;
templ->clust_rec_field_no = v_no;
templ->rec_prefix_field_no = ULINT_UNDEFINED;
@@ -7524,10 +7522,8 @@ ha_innobase::build_template(
{
dict_index_t* index;
dict_index_t* clust_index;
- ulint n_fields;
ibool fetch_all_in_key = FALSE;
ibool fetch_primary_key_cols = FALSE;
- ulint i;
if (m_prebuilt->select_lock_type == LOCK_X || m_prebuilt->table->no_rollback()) {
/* We always retrieve the whole clustered index record if we
@@ -7582,7 +7578,8 @@ ha_innobase::build_template(
/* Below we check column by column if we need to access
the clustered index. */
- n_fields = (ulint) mysql_fields(table);
+ const bool skip_virtual = omits_virtual_cols(*table_share);
+ const ulint n_fields = table_share->fields;
if (!m_prebuilt->mysql_template) {
m_prebuilt->mysql_template = (mysql_row_templ_t*)
@@ -7602,25 +7599,25 @@ ha_innobase::build_template(
/* Note that in InnoDB, i is the column number in the table.
MySQL calls columns 'fields'. */
+ ulint num_v = 0;
+
if (active_index != MAX_KEY
&& active_index == pushed_idx_cond_keyno) {
- ulint num_v = 0;
-
/* Push down an index condition or an end_range check. */
- for (i = 0; i < n_fields; i++) {
- ibool index_contains;
-
- if (innobase_is_v_fld(table->field[i])) {
- index_contains = dict_index_contains_col_or_prefix(
- index, num_v, true);
- if (index_contains)
- {
- m_prebuilt->n_template = 0;
- goto no_icp;
- }
- } else {
- index_contains = dict_index_contains_col_or_prefix(
- index, i - num_v, false);
+ for (ulint i = 0; i < n_fields; i++) {
+ const Field* field = table->field[i];
+ const bool is_v = innobase_is_v_fld(field);
+ if (is_v && skip_virtual) {
+ num_v++;
+ continue;
+ }
+ ibool index_contains
+ = dict_index_contains_col_or_prefix(
+ index, is_v ? num_v : i - num_v, is_v);
+ if (is_v && index_contains) {
+ m_prebuilt->n_template = 0;
+ num_v = 0;
+ goto no_icp;
}
/* Test if an end_range or an index condition
@@ -7638,17 +7635,10 @@ ha_innobase::build_template(
the subset
field->part_of_key.is_set(active_index)
which would be acceptable if end_range==NULL. */
- bool is_v = innobase_is_v_fld(table->field[i]);
if (build_template_needs_field_in_icp(
index, m_prebuilt, index_contains,
is_v ? num_v : i - num_v, is_v)) {
- /* Needed in ICP */
- const Field* field;
- mysql_row_templ_t* templ;
-
- if (whole_row) {
- field = table->field[i];
- } else {
+ if (!whole_row) {
field = build_template_needs_field(
index_contains,
m_prebuilt->read_just_key,
@@ -7656,15 +7646,16 @@ ha_innobase::build_template(
fetch_primary_key_cols,
index, table, i, num_v);
if (!field) {
- if (innobase_is_v_fld(
- table->field[i])) {
+ if (is_v) {
num_v++;
}
continue;
}
}
- templ = build_template_field(
+ ut_ad(!is_v);
+
+ mysql_row_templ_t* templ= build_template_field(
m_prebuilt, clust_index, index,
table, field, i - num_v, 0);
@@ -7739,7 +7730,8 @@ ha_innobase::build_template(
< m_prebuilt->index->n_uniq);
*/
}
- if (innobase_is_v_fld(table->field[i])) {
+
+ if (is_v) {
num_v++;
}
}
@@ -7751,29 +7743,24 @@ ha_innobase::build_template(
/* Include the fields that are not needed in index condition
pushdown. */
- for (i = 0; i < n_fields; i++) {
+ for (ulint i = 0; i < n_fields; i++) {
mysql_row_templ_t* templ;
- ibool index_contains;
-
- if (innobase_is_v_fld(table->field[i])) {
- index_contains = dict_index_contains_col_or_prefix(
- index, num_v, true);
- } else {
- index_contains = dict_index_contains_col_or_prefix(
- index, i - num_v, false);
+ const Field* field = table->field[i];
+ const bool is_v = innobase_is_v_fld(field);
+ if (is_v && skip_virtual) {
+ num_v++;
+ continue;
}
- bool is_v = innobase_is_v_fld(table->field[i]);
+ ibool index_contains
+ = dict_index_contains_col_or_prefix(
+ index, is_v ? num_v : i - num_v, is_v);
if (!build_template_needs_field_in_icp(
index, m_prebuilt, index_contains,
is_v ? num_v : i - num_v, is_v)) {
/* Not needed in ICP */
- const Field* field;
-
- if (whole_row) {
- field = table->field[i];
- } else {
+ if (!whole_row) {
field = build_template_needs_field(
index_contains,
m_prebuilt->read_just_key,
@@ -7781,7 +7768,7 @@ ha_innobase::build_template(
fetch_primary_key_cols,
index, table, i, num_v);
if (!field) {
- if (innobase_is_v_fld(table->field[i])) {
+ if (is_v) {
num_v++;
}
continue;
@@ -7791,8 +7778,9 @@ ha_innobase::build_template(
templ = build_template_field(
m_prebuilt, clust_index, index,
table, field, i - num_v, num_v);
+ ut_ad(templ->is_virtual == (ulint)is_v);
- if (templ->is_virtual) {
+ if (is_v) {
num_v++;
}
}
@@ -7802,21 +7790,26 @@ ha_innobase::build_template(
} else {
no_icp:
mysql_row_templ_t* templ;
- ulint num_v = 0;
/* No index condition pushdown */
m_prebuilt->idx_cond = NULL;
+ ut_ad(num_v == 0);
- for (i = 0; i < n_fields; i++) {
- const Field* field;
+ for (ulint i = 0; i < n_fields; i++) {
+ const Field* field = table->field[i];
+ const bool is_v = innobase_is_v_fld(field);
if (whole_row) {
+ if (is_v && skip_virtual) {
+ num_v++;
+ continue;
+ }
/* Even this is whole_row, if the seach is
on a virtual column, and read_just_key is
set, and field is not in this index, we
will not try to fill the value since they
are not stored in such index nor in the
cluster index. */
- if (innobase_is_v_fld(table->field[i])
+ if (is_v
&& m_prebuilt->read_just_key
&& !dict_index_contains_col_or_prefix(
m_prebuilt->index, num_v, true))
@@ -7827,12 +7820,10 @@ no_icp:
num_v++;
continue;
}
-
- field = table->field[i];
} else {
ibool contain;
- if (!innobase_is_v_fld(table->field[i])) {
+ if (!is_v) {
contain = dict_index_contains_col_or_prefix(
index, i - num_v,
false);
@@ -7851,7 +7842,7 @@ no_icp:
fetch_primary_key_cols,
index, table, i, num_v);
if (!field) {
- if (innobase_is_v_fld(table->field[i])) {
+ if (is_v) {
num_v++;
}
continue;
@@ -7861,7 +7852,8 @@ no_icp:
templ = build_template_field(
m_prebuilt, clust_index, index,
table, field, i - num_v, num_v);
- if (templ->is_virtual) {
+ ut_ad(templ->is_virtual == (ulint)is_v);
+ if (is_v) {
num_v++;
}
}
@@ -7870,8 +7862,7 @@ no_icp:
if (index != clust_index && m_prebuilt->need_to_access_clustered) {
/* Change rec_field_no's to correspond to the clustered index
record */
- for (i = 0; i < m_prebuilt->n_template; i++) {
-
+ for (ulint i = 0; i < m_prebuilt->n_template; i++) {
mysql_row_templ_t* templ
= &m_prebuilt->mysql_template[i];
@@ -8299,13 +8290,12 @@ calc_row_difference(
ulint n_changed = 0;
dfield_t dfield;
dict_index_t* clust_index;
- uint i;
ibool changes_fts_column = FALSE;
ibool changes_fts_doc_col = FALSE;
trx_t* const trx = prebuilt->trx;
doc_id_t doc_id = FTS_NULL_DOC_ID;
ulint num_v = 0;
- uint n_fields = mysql_fields(table);
+ const bool skip_virtual = omits_virtual_cols(*table->s);
ut_ad(!srv_read_only_mode);
@@ -8315,16 +8305,15 @@ calc_row_difference(
/* We use upd_buff to convert changed fields */
buf = (byte*) upd_buff;
- for (i = 0; i < n_fields; i++) {
+ for (uint i = 0; i < table->s->fields; i++) {
field = table->field[i];
- bool is_virtual = innobase_is_v_fld(field);
- dict_col_t* col;
-
- if (is_virtual) {
- col = &prebuilt->table->v_cols[num_v].m_col;
- } else {
- col = &prebuilt->table->cols[i - num_v];
+ const bool is_virtual = innobase_is_v_fld(field);
+ if (is_virtual && skip_virtual) {
+ continue;
}
+ dict_col_t* col = is_virtual
+ ? &prebuilt->table->v_cols[num_v].m_col
+ : &prebuilt->table->cols[i - num_v];
o_ptr = (const byte*) old_row + get_field_offset(table, field);
n_ptr = (const byte*) new_row + get_field_offset(table, field);
@@ -8680,33 +8669,25 @@ wsrep_calc_row_hash(
dictionary */
row_prebuilt_t* prebuilt) /*!< in: InnoDB prebuilt struct */
{
- Field* field;
- enum_field_types field_mysql_type;
- uint n_fields;
ulint len;
const byte* ptr;
- ulint col_type;
- uint i;
void *ctx = alloca(my_md5_context_size());
my_md5_init(ctx);
- n_fields = mysql_fields(table);
-
- for (i = 0; i < n_fields; i++) {
+ for (uint i = 0; i < table->s->fields; i++) {
byte null_byte=0;
byte true_byte=1;
- field = table->field[i];
+ const Field* field = table->field[i];
+ if (innobase_is_v_fld(field)) {
+ continue;
+ }
ptr = (const byte*) row + get_field_offset(table, field);
len = field->pack_length();
- field_mysql_type = field->type();
-
- col_type = prebuilt->table->cols[i].mtype;
-
- switch (col_type) {
+ switch (prebuilt->table->cols[i].mtype) {
case DATA_BLOB:
ptr = row_mysql_read_blob_ref(&len, ptr, len);
@@ -8716,7 +8697,7 @@ wsrep_calc_row_hash(
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_VARMYSQL:
- if (field_mysql_type == MYSQL_TYPE_VARCHAR) {
+ if (field->type() == MYSQL_TYPE_VARCHAR) {
/* This is a >= 5.0.3 type true VARCHAR where
the real payload data length is stored in
1 or 2 bytes */
@@ -10616,9 +10597,9 @@ create_table_check_doc_id_col(
ULINT_UNDEFINED if column is of the
wrong type/name/size */
{
- uint n_fields = mysql_fields(form);
+ ut_ad(!omits_virtual_cols(*form->s));
- for (ulint i = 0; i < n_fields; i++) {
+ for (ulint i = 0; i < form->s->fields; i++) {
const Field* field;
ulint col_type;
ulint col_len;
@@ -21079,7 +21060,7 @@ const char* BUG_REPORT_MSG =
const char* FORCE_RECOVERY_MSG =
"Please refer to "
- "https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/"
+ "https://mariadb.com/kb/en/library/innodb-recovery-modes/"
" for information about forcing recovery.";
const char* ERROR_CREATING_MSG =
@@ -21097,7 +21078,7 @@ const char* SET_TRANSACTION_MSG =
"Please refer to https://mariadb.com/kb/en/library/set-transaction/";
const char* INNODB_PARAMETERS_MSG =
- "Please refer to https://mariadb.com/kb/en/library/xtradbinnodb-server-system-variables/";
+ "Please refer to https://mariadb.com/kb/en/library/innodb-system-variables/";
/**********************************************************************
Converts an identifier from my_charset_filename to UTF-8 charset.
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc
index 1e9e6dbda12..a1ec47d17dc 100644
--- a/storage/innobase/handler/handler0alter.cc
+++ b/storage/innobase/handler/handler0alter.cc
@@ -7712,36 +7712,40 @@ err_exit:
index != NULL;
index = dict_table_get_next_index(index)) {
+ bool has_prefixes = false;
+ for (size_t i = 0; i < dict_index_get_n_fields(index); i++) {
+ if (dict_index_get_nth_field(index, i)->prefix_len) {
+ has_prefixes = true;
+ break;
+ }
+ }
+
for (ulint i = 0; i < dict_index_get_n_fields(index); i++) {
- if (my_strcasecmp(
- system_charset_info,
- dict_index_get_nth_field(index, i)->name,
- from)) {
+ const dict_field_t* field
+ = dict_index_get_nth_field(index, i);
+ if (my_strcasecmp(system_charset_info, field->name,
+ from)) {
continue;
}
info = pars_info_create();
+ ulint pos = i;
+ if (has_prefixes) {
+ pos = (pos << 16) + field->prefix_len;
+ }
+
pars_info_add_ull_literal(info, "indexid", index->id);
- pars_info_add_int4_literal(info, "nth", i);
+ pars_info_add_int4_literal(info, "nth", pos);
pars_info_add_str_literal(info, "new", to);
error = que_eval_sql(
info,
"PROCEDURE RENAME_SYS_FIELDS_PROC () IS\n"
"BEGIN\n"
-
"UPDATE SYS_FIELDS SET COL_NAME=:new\n"
"WHERE INDEX_ID=:indexid\n"
"AND POS=:nth;\n"
-
- /* Try again, in case there is a prefix_len
- encoded in SYS_FIELDS.POS */
-
- "UPDATE SYS_FIELDS SET COL_NAME=:new\n"
- "WHERE INDEX_ID=:indexid\n"
- "AND POS>=65536*:nth AND POS<65536*(:nth+1);\n"
-
"END;\n",
FALSE, trx);
diff --git a/storage/innobase/os/os0event.cc b/storage/innobase/os/os0event.cc
index 4453faedb71..7588020c8db 100644
--- a/storage/innobase/os/os0event.cc
+++ b/storage/innobase/os/os0event.cc
@@ -31,8 +31,6 @@ Created 2012-09-23 Sunny Bains
#include <synchapi.h>
#endif /* _WIN32 */
-#include <list>
-
#ifdef _WIN32
/** Native condition variable. */
typedef CONDITION_VARIABLE os_cond_t;
@@ -41,9 +39,6 @@ typedef CONDITION_VARIABLE os_cond_t;
typedef pthread_cond_t os_cond_t;
#endif /* _WIN32 */
-typedef std::list<os_event_t, ut_allocator<os_event_t> > os_event_list_t;
-typedef os_event_list_t::iterator event_iter_t;
-
/** InnoDB condition variable. */
struct os_event {
os_event() UNIV_NOTHROW;
@@ -123,7 +118,10 @@ struct os_event {
/** @return true if the event is in the signalled state. */
bool is_set() const UNIV_NOTHROW
{
- return(m_set);
+ mutex.enter();
+ bool is_set = m_set;
+ mutex.exit();
+ return is_set;
}
private:
@@ -221,16 +219,13 @@ private:
int64_t signal_count; /*!< this is incremented
each time the event becomes
signaled */
- EventMutex mutex; /*!< this mutex protects
+ mutable EventMutex mutex; /*!< this mutex protects
the next fields */
os_cond_t cond_var; /*!< condition variable is
used in waiting for the event */
-public:
- event_iter_t event_iter; /*!< For O(1) removal from
- list */
protected:
// Disable copying
os_event(const os_event&);
@@ -528,8 +523,6 @@ os_event_destroy(
os_event_t& event) /*!< in/own: event to free */
{
- if (event != NULL) {
- UT_DELETE(event);
- event = NULL;
- }
+ UT_DELETE(event);
+ event = NULL;
}
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 5b69663b0db..8bc9fdc7cae 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -3304,6 +3304,7 @@ row_drop_table_for_mysql(
pars_info_t* info = NULL;
mem_heap_t* heap = NULL;
+
DBUG_ENTER("row_drop_table_for_mysql");
DBUG_PRINT("row_drop_table_for_mysql", ("table: '%s'", name));
@@ -3334,10 +3335,16 @@ row_drop_table_for_mysql(
| DICT_ERR_IGNORE_CORRUPT));
if (!table) {
- err = DB_TABLE_NOT_FOUND;
- goto funct_exit_all_freed;
+ if (locked_dictionary) {
+ row_mysql_unlock_data_dictionary(trx);
+ }
+ trx->op_info = "";
+ DBUG_RETURN(DB_TABLE_NOT_FOUND);
}
+ const bool is_temp_name = strstr(table->name.m_name,
+ "/" TEMP_FILE_PREFIX);
+
if (table->is_temporary()) {
ut_ad(table->space == fil_system.temp_space);
for (dict_index_t* index = dict_table_get_first_index(table);
@@ -3393,7 +3400,6 @@ row_drop_table_for_mysql(
/* make sure background stats thread is not running on the table */
ut_ad(!(table->stats_bg_flag & BG_STAT_IN_PROGRESS));
-
if (!table->no_rollback()) {
if (table->space != fil_system.sys_space) {
#ifdef BTR_CUR_HASH_ADAPT
@@ -3409,7 +3415,7 @@ row_drop_table_for_mysql(
hold the InnoDB dictionary lock, we will drop any
adaptive hash index entries upfront. */
while (buf_LRU_drop_page_hash_for_tablespace(table)) {
- if (trx_is_interrupted(trx)
+ if ((!is_temp_name && trx_is_interrupted(trx))
|| srv_shutdown_state
!= SRV_SHUTDOWN_NONE) {
err = DB_INTERRUPTED;
@@ -3500,7 +3506,6 @@ row_drop_table_for_mysql(
}
}
-
DBUG_EXECUTE_IF("row_drop_table_add_to_background", goto defer;);
/* TODO: could we replace the counter n_foreign_key_checks_running
@@ -3511,7 +3516,7 @@ row_drop_table_for_mysql(
if (table->n_foreign_key_checks_running > 0) {
defer:
- if (!strstr(table->name.m_name, "/" TEMP_FILE_PREFIX)) {
+ if (!is_temp_name) {
heap = mem_heap_create(FN_REFLEN);
const char* tmp_name
= dict_mem_create_temporary_tablename(
diff --git a/storage/innobase/ut/ut0dbg.cc b/storage/innobase/ut/ut0dbg.cc
index 56a2eb80337..05b27060a9b 100644
--- a/storage/innobase/ut/ut0dbg.cc
+++ b/storage/innobase/ut/ut0dbg.cc
@@ -52,7 +52,7 @@ ut_dbg_assertion_failed(
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
- "InnoDB: https://mariadb.com/kb/en/library/xtradbinnodb-recovery-modes/\n"
+ "InnoDB: https://mariadb.com/kb/en/library/innodb-recovery-modes/\n"
"InnoDB: about forcing recovery.\n", stderr);
fflush(stderr);
diff --git a/storage/rocksdb/CMakeLists.txt b/storage/rocksdb/CMakeLists.txt
index 090763a2ece..6bb8c9f6d67 100644
--- a/storage/rocksdb/CMakeLists.txt
+++ b/storage/rocksdb/CMakeLists.txt
@@ -221,7 +221,9 @@ TARGET_LINK_LIBRARIES(sst_dump rocksdblib)
MYSQL_ADD_EXECUTABLE(mysql_ldb tools/mysql_ldb.cc COMPONENT rocksdb-engine)
TARGET_LINK_LIBRARIES(mysql_ldb rocksdb_tools rocksdb_aux_lib dbug)
-INSTALL_SCRIPT(myrocks_hotbackup COMPONENT rocksdb-engine)
+CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/myrocks_hotbackup.py
+ ${CMAKE_CURRENT_BINARY_DIR}/myrocks_hotbackup @ONLY)
+INSTALL_SCRIPT(${CMAKE_CURRENT_BINARY_DIR}/myrocks_hotbackup COMPONENT rocksdb-engine)
IF(CMAKE_CXX_COMPILER_ID MATCHES "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
SET_TARGET_PROPERTIES(rocksdb_tools sst_dump mysql_ldb PROPERTIES COMPILE_FLAGS -frtti)
diff --git a/storage/rocksdb/ha_rocksdb.cc b/storage/rocksdb/ha_rocksdb.cc
index 98ce1180d48..f09e263fe75 100644
--- a/storage/rocksdb/ha_rocksdb.cc
+++ b/storage/rocksdb/ha_rocksdb.cc
@@ -3770,7 +3770,6 @@ static int rocksdb_commit(handlerton* hton, THD* thd, bool commit_tx)
We get here when committing a statement within a transaction.
*/
tx->make_stmt_savepoint_permanent();
- tx->make_stmt_savepoint_permanent();
}
if (my_core::thd_tx_isolation(thd) <= ISO_READ_COMMITTED) {
diff --git a/storage/rocksdb/myrocks_hotbackup b/storage/rocksdb/myrocks_hotbackup.py
index ef1e934f3fd..69c75b7cbfd 100755
--- a/storage/rocksdb/myrocks_hotbackup
+++ b/storage/rocksdb/myrocks_hotbackup.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!@PYTHON_SHEBANG@
from __future__ import division
from optparse import OptionParser
diff --git a/storage/tokudb/CMakeLists.txt b/storage/tokudb/CMakeLists.txt
index 86463c2997e..3b4e4fb967e 100644
--- a/storage/tokudb/CMakeLists.txt
+++ b/storage/tokudb/CMakeLists.txt
@@ -49,34 +49,43 @@ CHECK_JEMALLOC()
IF(NOT LIBJEMALLOC)
MESSAGE(WARNING "TokuDB is enabled, but jemalloc is not. This configuration is not supported")
+ELSEIF(LIBJEMALLOC STREQUAL jemalloc_pic)
+ CHECK_CXX_SOURCE_COMPILES(
+"
+#include <jemalloc/jemalloc.h>
+#if JEMALLOC_VERSION_MAJOR < 5
+int main() { return 0; }
+#else
+#error
+#endif
+" JEMALLOC_OK)
+ IF (NOT JEMALLOC_OK)
+ MESSAGE(FATAL_ERROR "static jemalloc_pic.a can only be used up to jemalloc 4")
+ ENDIF()
ELSEIF(LIBJEMALLOC STREQUAL jemalloc)
FIND_LIBRARY(LIBJEMALLOC_SO jemalloc)
IF(NOT LIBJEMALLOC_SO)
MESSAGE(FATAL_ERROR "jemalloc is present, but cannot be found?")
ENDIF()
GET_FILENAME_COMPONENT(LIBJEMALLOC_PATH ${LIBJEMALLOC_SO} REALPATH CACHE)
-ENDIF()
-IF(LIBJEMALLOC_PATH AND (RPM OR DEB))
- UNSET(LIBJEMALLOC)
- GET_DIRECTORY_PROPERTY(V DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITION CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES)
- SET(CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES "${V} jemalloc" PARENT_SCOPE)
- SET(systemd_env "Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
- SET(cnf_malloc_lib "malloc-lib=${LIBJEMALLOC_PATH}")
-ELSEIF(LIBJEMALLOC_PATH)
- SET(systemd_env "#Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"") #"
- SET(cnf_malloc_lib "#malloc-lib=${LIBJEMALLOC_PATH}")
-ELSE()
- SET(systemd_env "#Environment=\"LD_PRELOAD=/path/to/libjemalloc.so\"") #"
- SET(cnf_malloc_lib "#malloc-lib=/path/to/libjemalloc.so")
+ IF(RPM OR DEB)
+ UNSET(LIBJEMALLOC)
+ GET_DIRECTORY_PROPERTY(V DIRECTORY ${CMAKE_SOURCE_DIR} DEFINITION CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES)
+ SET(CPACK_RPM_tokudb-engine_PACKAGE_REQUIRES "${V} jemalloc" PARENT_SCOPE)
+ ENDIF()
+
+ IF(INSTALL_SYSCONFDIR)
+ SET(systemd_env "Environment=\"LD_PRELOAD=${LIBJEMALLOC_PATH}\"")
+ SET(cnf_malloc_lib "malloc-lib=${LIBJEMALLOC_PATH}")
+ CONFIGURE_FILE(tokudb.conf.in tokudb.conf @ONLY)
+ INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tokudb.conf
+ DESTINATION ${INSTALL_SYSCONFDIR}/systemd/system/mariadb.service.d/
+ COMPONENT tokudb-engine)
+ ENDIF()
ENDIF()
+
CONFIGURE_FILE(tokudb.cnf.in tokudb.cnf @ONLY)
-CONFIGURE_FILE(tokudb.conf.in tokudb.conf @ONLY)
-IF(INSTALL_SYSCONFDIR)
- INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/tokudb.conf
- DESTINATION ${INSTALL_SYSCONFDIR}/systemd/system/mariadb.service.d/
- COMPONENT tokudb-engine)
-ENDIF()
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-shadow")
MY_CHECK_AND_SET_COMPILER_FLAG("-Wno-vla" DEBUG)
diff --git a/storage/tokudb/mysql-test/tokudb/disabled.def b/storage/tokudb/mysql-test/tokudb/disabled.def
index 89f6992d26d..4f759001151 100644
--- a/storage/tokudb/mysql-test/tokudb/disabled.def
+++ b/storage/tokudb/mysql-test/tokudb/disabled.def
@@ -30,5 +30,5 @@ i_s_tokudb_lock_waits_released: unstable, race conditions
i_s_tokudb_locks_released: unstable, race conditions
row_format: n/a
nonflushing_analyze_debug: Freezes in MariaDB 10.0
-tokudb.change_column_all_1000_1: We are too lazy to fix this properly
-tokudb.change_column_all_1000_10: We are too lazy to fix this properly
+change_column_all_1000_1: We are too lazy to fix this properly
+change_column_all_1000_10: We are too lazy to fix this properly
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py
index 2c7d8dd9a54..2c7d8dd9a54 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_bin.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py
index 6bd5de38fe8..6bd5de38fe8 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_bin_rename.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_char.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char.py
index c53442ade50..c53442ade50 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_char.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_char.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py
index e92797918d5..e92797918d5 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_char_binary.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py
index 065e37b186d..065e37b186d 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_char_charbinary.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py b/storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py
index fe73fce0d53..fe73fce0d53 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_char_rename.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_int.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int.py
index 6f69156e260..6f69156e260 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_int.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_int.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py
index fd7e5868c40..fd7e5868c40 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_int_key.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py
index 1708c65efde..1708c65efde 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_int_not_supported.py
diff --git a/storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py b/storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py
index 5222564a9a2..5222564a9a2 100755..100644
--- a/storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py
+++ b/storage/tokudb/mysql-test/tokudb/t/change_column_int_rename.py
diff --git a/unittest/mysys/lf-t.c b/unittest/mysys/lf-t.c
index abfa74877f8..7070da648a8 100644
--- a/unittest/mysys/lf-t.c
+++ b/unittest/mysys/lf-t.c
@@ -48,9 +48,6 @@ pthread_handler_t test_lf_pinbox(void *arg)
pins= lf_pinbox_get_pins(&lf_allocator.pinbox);
}
lf_pinbox_put_pins(pins);
- pthread_mutex_lock(&mutex);
- if (!--running_threads) pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
if (with_my_thread_init)
my_thread_end();
@@ -105,7 +102,6 @@ pthread_handler_t test_lf_alloc(void *arg)
bad|= lf_allocator.mallocs - lf_alloc_pool_count(&lf_allocator);
#endif
}
- if (!--running_threads) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
if (with_my_thread_init)
@@ -172,7 +168,6 @@ pthread_handler_t test_lf_hash(void *arg)
lf_hash.size, inserts, scans);
bad|= lf_hash.count;
}
- if (!--running_threads) pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
if (with_my_thread_init)
my_thread_end();
diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c
index 79e93b36ad9..7a7fbaeecd1 100644
--- a/unittest/mysys/my_atomic-t.c
+++ b/unittest/mysys/my_atomic-t.c
@@ -29,9 +29,6 @@ pthread_handler_t test_atomic_add(void *arg)
my_atomic_add32(&bad, x);
my_atomic_add32(&bad, -x);
}
- pthread_mutex_lock(&mutex);
- if (!--running_threads) pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
return 0;
}
@@ -47,13 +44,6 @@ pthread_handler_t test_atomic_add64(void *arg)
my_atomic_add64(&a64, x);
my_atomic_add64(&a64, -x);
}
- pthread_mutex_lock(&mutex);
- if (!--running_threads)
- {
- bad= (a64 != 0);
- pthread_cond_signal(&cond);
- }
- pthread_mutex_unlock(&mutex);
return 0;
}
@@ -83,9 +73,6 @@ pthread_handler_t test_atomic_fas(void *arg)
my_atomic_add32(&bad, -x);
- pthread_mutex_lock(&mutex);
- if (!--running_threads) pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
return 0;
}
@@ -109,9 +96,6 @@ pthread_handler_t test_atomic_cas(void *arg)
ok= my_atomic_cas32(&bad, &y, y-x);
} while (!ok) ;
}
- pthread_mutex_lock(&mutex);
- if (!--running_threads) pthread_cond_signal(&cond);
- pthread_mutex_unlock(&mutex);
return 0;
}
@@ -142,4 +126,5 @@ void do_tests()
}
a64=0;
test_concurrently("my_atomic_add64", test_atomic_add64, THREADS, CYCLES);
+ bad= (a64 != 0);
}
diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c
index 83c7432c823..3a57ed091e9 100644
--- a/unittest/mysys/thr_template.c
+++ b/unittest/mysys/thr_template.c
@@ -20,35 +20,34 @@
#include <tap.h>
volatile uint32 bad;
-pthread_attr_t thr_attr;
pthread_mutex_t mutex;
-pthread_cond_t cond;
-uint running_threads;
void do_tests();
void test_concurrently(const char *test, pthread_handler handler, int n, int m)
{
- pthread_t t;
+ pthread_t *threads= malloc(n * sizeof(pthread_t));
+ int i;
ulonglong now= my_interval_timer();
+ assert(threads);
bad= 0;
diag("Testing %s with %d threads, %d iterations... ", test, n, m);
- for (running_threads= n ; n ; n--)
+ for (i= n; i; i--)
{
- if (pthread_create(&t, &thr_attr, handler, &m) != 0)
+ if (pthread_create(&threads[i], 0, handler, &m) != 0)
{
diag("Could not create thread");
abort();
}
}
- pthread_mutex_lock(&mutex);
- while (running_threads)
- pthread_cond_wait(&cond, &mutex);
- pthread_mutex_unlock(&mutex);
+
+ for (i= n; i; i--)
+ pthread_join(threads[i], 0);
now= my_interval_timer() - now;
+ free(threads);
ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e9, bad);
}
@@ -60,9 +59,6 @@ int main(int argc __attribute__((unused)), char **argv)
DBUG_SET_INITIAL(argv[1]);
pthread_mutex_init(&mutex, 0);
- pthread_cond_init(&cond, 0);
- pthread_attr_init(&thr_attr);
- pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
#define CYCLES 3000
#define THREADS 30
@@ -71,16 +67,7 @@ int main(int argc __attribute__((unused)), char **argv)
do_tests();
- /*
- workaround until we know why it crashes randomly on some machine
- (BUG#22320).
- */
-#ifdef NOT_USED
- sleep(2);
-#endif
pthread_mutex_destroy(&mutex);
- pthread_cond_destroy(&cond);
- pthread_attr_destroy(&thr_attr);
my_end(0);
return exit_status();
}
diff --git a/unittest/mysys/waiting_threads-t.c b/unittest/mysys/waiting_threads-t.c
index 01fc850cb96..a2cb7a51c85 100644
--- a/unittest/mysys/waiting_threads-t.c
+++ b/unittest/mysys/waiting_threads-t.c
@@ -136,10 +136,8 @@ retry:
pthread_mutex_unlock(&lock);
pthread_mutex_unlock(& thds[id].lock);
wt_thd_destroy(& thds[id].thd);
-
- if (!--running_threads) /* now, signal when everybody is done with deinit */
- pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
+
DBUG_PRINT("wt", ("exiting"));
my_thread_end();
return 0;