summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicențiu Ciorbaru <vicentiu@mariadb.org>2021-07-18 19:39:45 +0300
committerVicențiu Ciorbaru <cvicentiu@gmail.com>2021-07-18 19:58:43 +0300
commitb32b1f2b19ee0974464a0f8a75209d119452e740 (patch)
tree92c4d0e8995b71c018a4c5ab4816d1ececa2cece
parent2c4d1fb544039d86c516c8a37ce60ca07a02ca33 (diff)
parent74f5aa164eee447fe37d9bbdb8465dffc03164af (diff)
downloadmariadb-git-b32b1f2b19ee0974464a0f8a75209d119452e740.tar.gz
Merge remote-tracking branch '10.6' into 10.7
Update debian changes to 10.7 to enable debian packaging to work again.
-rw-r--r--.gitlab-ci.yml270
-rw-r--r--client/mysqltest.cc2
-rw-r--r--mysql-test/include/have_pool_of_threads.inc3
-rw-r--r--mysql-test/include/maybe_pool_of_threads.inc1
-rw-r--r--mysql-test/include/protocol.combinations3
-rw-r--r--mysql-test/include/protocol.inc2
-rw-r--r--mysql-test/main/features,ps.rdiff21
-rw-r--r--mysql-test/main/features.test5
-rw-r--r--mysql-test/main/join_outer_innodb.result19
-rw-r--r--mysql-test/main/join_outer_innodb.test17
-rw-r--r--mysql-test/main/limit_rows_examined.test5
-rw-r--r--mysql-test/main/mysqld--defaults-file.test1
-rw-r--r--mysql-test/main/mysqld--help,aix.rdiff76
-rw-r--r--mysql-test/main/opt_trace.test7
-rwxr-xr-xmysql-test/mariadb-test-run.pl2
-rw-r--r--mysql-test/suite.pm6
-rw-r--r--mysql-test/suite/innodb/t/innodb_bug53756-master.opt2
-rw-r--r--mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff18
-rw-r--r--mysql-test/suite/sys_vars/t/stored_program_cache_func.test6
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test1
-rw-r--r--mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test1
-rw-r--r--sql/myskel.m49
-rw-r--r--sql/net_serv.cc20
-rw-r--r--sql/protocol.cc4
-rw-r--r--sql/sql_delete.cc7
-rw-r--r--sql/sql_error.cc22
-rw-r--r--sql/sql_error.h11
-rw-r--r--sql/sql_insert.cc24
-rw-r--r--sql/sql_prepare.cc46
-rw-r--r--sql/sql_select.cc31
-rw-r--r--storage/innobase/buf/buf0dblwr.cc3
-rw-r--r--storage/innobase/handler/ha_innodb.cc2
-rw-r--r--storage/innobase/include/log0log.h9
-rw-r--r--storage/innobase/log/log0log.cc1
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc2
-rw-r--r--storage/innobase/row/row0mysql.cc2
-rw-r--r--storage/innobase/srv/srv0srv.cc2
-rw-r--r--storage/innobase/srv/srv0start.cc2
-rw-r--r--storage/innobase/trx/trx0purge.cc2
-rw-r--r--storage/perfschema/pfs.cc2
-rw-r--r--tests/mysql_client_test.c174
48 files changed, 774 insertions, 76 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 00000000000..0a1bf5bff71
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,270 @@
+---
+# This Gitlab-CI pipeline offers basic validation that a commit did not
+# introduce easily detectable regressions. Builds run primairly on a new Fedora,
+# which has all the latest upstream build dependencies and thus is the primary
+# testing target, as eventually everything in Fedora becomes the next CentOS and
+# Red Hat releases.
+#
+# In addition test building on CentOS 7 and 8 to ensure that the code base
+# remains reasonably backwards compatible.
+#
+# This is now intentionally simple, to keep it fast and accurate with minimal
+# false positive failures. If one wants to extend it, see debian/salsa-ci.yml
+# for inspiration on more integration tests to run.
+#
+# Also make sure the pipeline stays within the bounds of what CI workers on
+# Gitlab-CI are capable of executing, thus ensuring that any potential
+# contributor can at any point in time fork to their own Gitlab account and
+# start working towards meaningful contributions!
+#
+# NOTE TO MERGERS: Most of the contents in the Gitlab-CI configuration has been
+# tailored for a specific release or MariaDB. As a general rule, do not merge
+# changes in this file across MariaDB branches to avoid breaking the CI. Updates
+# the Gitlab-CI pipeline are most of the time better done manually per major
+# release branch.
+
+stages:
+ - build
+ - test
+ - Salsa-CI
+
+# Base image for builds and tests unless otherwise defined
+# @TODO: Fedora 34 is latest, but fails to start on Gitlab.com with error "shell not found"
+image: fedora:33
+
+# Define common CMAKE_FLAGS for all builds. Skim down build by omitting all
+# submodules (a commit in this repo does not affect their builds anyway) and
+# many components that are otherwise slow to build.
+variables:
+ CMAKE_FLAGS: "-DWITH_SSL=system -DPLUGIN_COLUMNSTORE=NO -DPLUGIN_ROCKSDB=NO -DPLUGIN_S3=NO -DPLUGIN_MROONGA=NO -DPLUGIN_CONNECT=NO -DPLUGIN_MROONGA=NO -DPLUGIN_TOKUDB=NO -DPLUGIN_PERFSCHEMA=NO -DWITH_WSREP=OFF"
+ # Major version dictates which branches share the same ccache
+ MARIADB_MAJOR_VERSION: "10.6"
+ # Most steps don't need the source code, only artifacts
+ GIT_STRATEGY: none
+ # Hack to satisfy directory name length requirement by CPackRPM in CMake 3.x
+ # https://cmake.org/cmake/help/v3.7/module/CPackRPM.html#variable:CPACK_RPM_BUILD_SOURCE_DIRS_PREFIX
+ GIT_CLONE_PATH: $CI_BUILDS_DIR/CPACK_BUILD_SOURCE_DIRS_LONG_NAME_REQUIREMENT
+
+# Define once, use many times
+.rpm_listfiles: &rpm_listfiles
+ - |
+ echo "Generating rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log ..."
+ for package in *.rpm
+ do
+ echo "$package"
+ rpm -qlpv "$package" | awk '{print $1 " " $3 "/" $4 " ." $9 " " $10 " " $11}' | sort -k 3
+ echo "------------------------------------------------"
+ done >> ../rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ # CPackRPM lists contents in build log, so no need to show the output of this,
+ # just store it as a build artifact that can be downloaded and diffed against
+ # other builds to detect which files where added/removed/moved
+
+fedora:
+ stage: build
+ variables:
+ GIT_STRATEGY: fetch
+ GIT_SUBMODULE_STRATEGY: normal
+ script:
+ - yum install -y yum-utils rpm-build ccache openssl-devel
+ - source /etc/profile.d/ccache.sh
+ - export CCACHE_DIR="$(pwd)/.ccache"; ccache -s
+ # Accelerate builds with unsafe disk access, as we can afford to loose the entire build anyway
+ - yum install -y https://github.com/stewartsmith/libeatmydata/releases/download/v129/libeatmydata-129-1.fc33.x86_64.rpm
+ # This repository does not have any .spec files, so install dependencies based on Fedora spec file
+ - yum-builddep -y mariadb-server
+ - mkdir builddir; cd builddir
+ - cmake -DRPM=$CI_JOB_NAME $CMAKE_FLAGS .. 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - eatmydata make package 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ # @TODO: Don't use -j on Gitlab.com as builds just get stuck when running
+ # multi-proc, needs more debugging
+ - make test || true # Unit tests constantly fail, see https://jira.mariadb.org/browse/MDEV-25820
+ # - make test-force || true # mysql-test-runner takes too long, run it in a separate job instead
+ - *rpm_listfiles
+ - mkdir ../rpm; mv *.rpm ../rpm
+ - ccache -s
+ artifacts:
+ when: always # Must be able to see logs
+ paths:
+ - build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - rpm
+ - builddir/_CPack_Packages/Linux/RPM/SPECS/
+ cache:
+ key: $MARIADB_MAJOR_VERSION-$CI_JOB_NAME
+ paths:
+ - .ccache
+ # policy: pull
+ # @TODO: It would be enough to only download the cache. There is no need for
+ # every job to upload a new cache every time. A monthly or weekly scheduled
+ # run could update the cache for all other builds to us.
+
+centos8:
+ stage: build
+ image: centos:8
+ variables:
+ GIT_STRATEGY: fetch
+ GIT_SUBMODULE_STRATEGY: normal
+ script:
+ - yum install -y yum-utils rpm-build openssl-devel
+ - yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm
+ # dnf --enablerepo=powertools install Judy-devel #--> not found
+ - dnf config-manager --set-enabled powertools
+ # Error:
+ # Problem: conflicting requests
+ # - package Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.i686 is filtered out by modular filtering
+ # - package Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64 is filtered out by modular filtering
+ # Solution: install Judy-devel directly from downloaded rpm file:
+ - yum install -y http://mirror.centos.org/centos/8/PowerTools/x86_64/os/Packages/Judy-devel-1.0.5-18.module_el8.3.0+757+d382997d.x86_64.rpm
+ # Use eatmydata to speed up build
+ - yum install -y https://github.com/stewartsmith/libeatmydata/releases/download/v129/libeatmydata-129-1.fc33.x86_64.rpm
+ - yum install -y ccache # From EPEL
+ - source /etc/profile.d/ccache.sh
+ - export CCACHE_DIR="$(pwd)/.ccache"; ccache -s
+ # This repository does not have any .spec files, so install dependencies based on CentOS spec file
+ - yum-builddep -y mariadb-server
+ - mkdir builddir; cd builddir
+ - cmake -DRPM=$CI_JOB_NAME $CMAKE_FLAGS .. 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - eatmydata make package 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ # @TODO: Don't use -j on Gitlab.com as builds just get stuck when running
+ # multi-proc and out of memory, see https://jira.mariadb.org/browse/MDEV-25968
+ - make test || true # Unit tests constantly fail, see https://jira.mariadb.org/browse/MDEV-25820
+ # - make test-force || true # mysql-test-runner takes too long, run it in a separate job instead
+ - *rpm_listfiles
+ - mkdir ../rpm; mv *.rpm ../rpm
+ - ccache -s
+ artifacts:
+ when: always # Must be able to see logs
+ paths:
+ - build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - rpm
+ - builddir/_CPack_Packages/Linux/RPM/SPECS/
+ cache:
+ key: $MARIADB_MAJOR_VERSION-$CI_JOB_NAME
+ paths:
+ - .ccache
+
+centos7:
+ stage: build
+ image: centos:7
+ variables:
+ GIT_STRATEGY: fetch
+ GIT_SUBMODULE_STRATEGY: normal
+ script:
+ # This repository does not have any .spec files, so install dependencies based on Fedora spec file
+ - yum-builddep -y mariadb-server
+ # ..with a few extra ones, as CentOS 7 is very old and these are added in newer MariaDB releases
+ - yum install -y yum-utils rpm-build gcc gcc-c++ bison libxml2-devel libevent-devel openssl-devel
+ - mkdir builddir; cd builddir
+ - cmake -DRPM=$CI_JOB_NAME $CMAKE_FLAGS .. 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - make package 2>&1 | tee -a ../build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ # @TODO: Don't use -j on Gitlab.com as builds just get stuck when running
+ # multi-proc and out of memory, see https://jira.mariadb.org/browse/MDEV-25968
+ - make test || true # Unit tests constantly fail, see https://jira.mariadb.org/browse/MDEV-25820
+ # - make test-force || true # mysql-test-runner takes too long, run it in a separate job instead
+ - *rpm_listfiles
+ - mkdir ../rpm; mv *.rpm ../rpm
+ artifacts:
+ when: always # Must be able to see logs
+ paths:
+ - build-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - rpmlist-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ - rpm
+ - builddir/_CPack_Packages/Linux/RPM/SPECS/
+
+mysql-test-run:
+ stage: test
+ dependencies:
+ - fedora
+ script:
+ # Install packages so tests and the dependencies install
+ # @TODO: RPM missing 'patch' as dependency, so installing it manually for now
+ - yum install -y rpm/*.rpm patch
+ # @TODO: Fix on packaging level for /usr/share/mariadb to work and errormsg.sys be found
+ - rm -rf /usr/share/mariadb; ln -s /usr/share/mysql /usr/share/mariadb
+ # mtr expects to be launched in-place and with write access to it's own directories
+ - cd /usr/share/mysql-test
+ - |
+ echo "
+ main.mysqldump : flaky on Gitlab-CI
+ main.flush_logs_not_windows : flaky in containers in general
+ main.mysql_upgrade_noengine : requires diff but diffutils is not a dependency
+ " > skiplist
+ # @TODO: Flaky tests are skipped for now, but should be fixed
+ - ./mtr --suite=main --force --xml-report=$CI_PROJECT_DIR/junit.xml --skip-test-list=skiplist
+ artifacts:
+ when: always # Also show results when tests fail
+ reports:
+ junit:
+ - junit.xml
+
+rpmlint:
+ stage: test
+ dependencies:
+ - fedora
+ script:
+ - yum install -y rpmlint
+ - rm -f rpm/*debuginfo* # Not relevant in this test
+ # Limit output to 1000 lines as Gitlab-CI max output is 4194304 bytes
+ # Save everything in a log file so it can be viewed in full via artifacts
+ - rpmlint --info rpm/*.rpm | tee -a rpmlint-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ artifacts:
+ when: always # Also show results when tests fail
+ paths:
+ - rpmlint-$CI_JOB_NAME-$CI_COMMIT_REF_SLUG.log
+ allow_failure: true
+ # @TODO: The package is not rpmlint clean, must allow failure for now
+
+fedora install:
+ stage: test
+ dependencies:
+ - fedora
+ script:
+ - rm -f rpm/*debuginfo* # Not relevant in this test
+ # Nothing provides galera-4 on Fedora, so this step fails if built with wsrep
+ - yum install -y rpm/*.rpm
+ # Fedora does not support running services in Docker (like Debian packages do) so start it manually
+ - /usr/bin/mariadb-install-db -u mysql
+ - sudo -u mysql /usr/sbin/mariadbd & sleep 10
+ # @TODO: Since we did a manual start, we also need to run upgrade manually
+ - /usr/bin/mariadb-upgrade -u root --socket /var/lib/mysql/mysql.sock
+ - |
+ mysql --skip-column-names -e "SELECT @@version, @@version_comment" | tee /tmp/version
+ grep $MARIADB_MAJOR_VERSION /tmp/version || echo "MariaDB didn't upgrade properly"
+
+fedora upgrade:
+ stage: test
+ dependencies:
+ - fedora
+ script:
+ - yum install -y mariadb-server
+ # Fedora does not support running services in Docker (like Debian packages do) so start it manually
+ - /usr/libexec/mysql-check-socket
+ - /usr/libexec/mysql-prepare-db-dir
+ - sudo -u mysql /usr/libexec/mysqld --basedir=/usr & sleep 10
+ - /usr/libexec/mysql-check-upgrade
+ - mysql --skip-column-names -e "SELECT @@version, @@version_comment" # Show version
+ # @TODO: Upgrade from Fedora 33 MariaDB 10.4 to MariaDB.org latest does not work
+ # so do this manual step to remove conflicts until packaging is fixed
+ - >
+ yum remove -y mariadb-server-utils mariadb-gssapi-server mariadb-cracklib-password-check
+ mariadb-backup mariadb-connector-c-config
+ - rm -f rpm/*debuginfo* # Not relevant in this test
+ - yum install -y rpm/*.rpm procps # procps provides pkill
+ # nothing provides galera-4 on Fedora, so this step fails if built with wsrep
+ - pkill mysqld || true; sleep 5; pkill mysqld || true; sleep 5
+ - /usr/bin/mariadb-install-db -u mysql
+ - sudo -u mysql /usr/sbin/mariadbd & sleep 10
+ # @TODO: Since we did a manual start, we also need to run upgrade manually
+ - /usr/bin/mariadb-upgrade -u root --socket /var/lib/mysql/mysql.sock
+ - |
+ mysql --skip-column-names -e "SELECT @@version, @@version_comment" | tee /tmp/version
+ grep $MARIADB_MAJOR_VERSION /tmp/version || echo "MariaDB didn't upgrade properly"
+
+# Once all RPM builds and tests have passed, also run the DEB builds and tests
+# @NOTE: This is likely to work well only on salsa.debian.org as the Gitlab.com
+# runners are too small for everything this stage does.
+# build_deb:
+# stage: Salsa-CI
+# trigger:
+# include: debian/salsa-ci.yml
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index c4b6aad6346..5008a048148 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -8416,7 +8416,7 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command,
append_session_track_info(ds, mysql);
- if (!disable_warnings)
+ if (!disable_warnings && !mysql_more_results(stmt->mysql))
{
/* Get the warnings from execute */
diff --git a/mysql-test/include/have_pool_of_threads.inc b/mysql-test/include/have_pool_of_threads.inc
index 432c6216804..62460127d88 100644
--- a/mysql-test/include/have_pool_of_threads.inc
+++ b/mysql-test/include/have_pool_of_threads.inc
@@ -1,4 +1,5 @@
--- require include/have_pool_of_threads.require
+--source include/not_aix.inc
+--require include/have_pool_of_threads.require
disable_query_log;
show variables like 'thread_handling';
enable_query_log;
diff --git a/mysql-test/include/maybe_pool_of_threads.inc b/mysql-test/include/maybe_pool_of_threads.inc
index 51a179b4426..d25e3864333 100644
--- a/mysql-test/include/maybe_pool_of_threads.inc
+++ b/mysql-test/include/maybe_pool_of_threads.inc
@@ -1 +1,2 @@
# run with and without threadpool
+--source include/not_aix.inc
diff --git a/mysql-test/include/protocol.combinations b/mysql-test/include/protocol.combinations
new file mode 100644
index 00000000000..fa5b08c0e51
--- /dev/null
+++ b/mysql-test/include/protocol.combinations
@@ -0,0 +1,3 @@
+[nm]
+
+[ps]
diff --git a/mysql-test/include/protocol.inc b/mysql-test/include/protocol.inc
new file mode 100644
index 00000000000..02f8c3f3dec
--- /dev/null
+++ b/mysql-test/include/protocol.inc
@@ -0,0 +1,2 @@
+# The goal of including this file is to enable protocol
+# combinations (see include/protocol.combinations)
diff --git a/mysql-test/main/features,ps.rdiff b/mysql-test/main/features,ps.rdiff
new file mode 100644
index 00000000000..9065c132714
--- /dev/null
+++ b/mysql-test/main/features,ps.rdiff
@@ -0,0 +1,21 @@
+--- features.result
++++ features,ps.result
+@@ -46,7 +46,7 @@
+ 1212
+ show status like "feature_dynamic_columns";
+ Variable_name Value
+-Feature_dynamic_columns 2
++Feature_dynamic_columns 4
+ #
+ # Feature fulltext
+ #
+@@ -93,7 +93,7 @@
+ drop table t1;
+ show status like "feature_subquery";
+ Variable_name Value
+-Feature_subquery 4
++Feature_subquery 5
+ #
+ # Feature timezone
+ #
+
diff --git a/mysql-test/main/features.test b/mysql-test/main/features.test
index 0dd0be20c9e..14c86255c37 100644
--- a/mysql-test/main/features.test
+++ b/mysql-test/main/features.test
@@ -1,10 +1,7 @@
# Testing of feature statistics
-if (`SELECT $PS_PROTOCOL != 0`)
-{
- --skip Test temporarily disabled for ps-protocol
-}
-- source include/have_geometry.inc
+-- source include/protocol.inc
--disable_warnings
drop table if exists t1;
diff --git a/mysql-test/main/join_outer_innodb.result b/mysql-test/main/join_outer_innodb.result
index 0b34a399d77..09a37a29702 100644
--- a/mysql-test/main/join_outer_innodb.result
+++ b/mysql-test/main/join_outer_innodb.result
@@ -496,3 +496,22 @@ natural right outer join t3;
drop table t1,t2,t3;
set optimizer_prune_level=@mdev4270_opl;
set optimizer_search_depth=@mdev4270_osd;
+#
+# Bug #20939184:INNODB: UNLOCK ROW COULD NOT FIND A 2 MODE LOCK ON THE
+# RECORD
+#
+CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1,c2) ) engine=innodb;
+CREATE TABLE t2 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1), KEY (c2)) engine=innodb;
+INSERT INTO t1 VALUES (1,2,3),(2,3,4),(3,4,5);
+INSERT INTO t2 SELECT * FROM t1;
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+START TRANSACTION;
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c2=t2.c2 AND t2.c1=1 FOR UPDATE;
+c1 c2 c3 c1 c2 c3
+1 2 3 1 2 3
+2 3 4 NULL NULL NULL
+3 4 5 NULL NULL NULL
+UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t2.c1 = 3 SET t1.c3 = RAND()*10;
+COMMIT;
+SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+DROP TABLE t1,t2;
diff --git a/mysql-test/main/join_outer_innodb.test b/mysql-test/main/join_outer_innodb.test
index c26cd62fbc7..6b332f3d155 100644
--- a/mysql-test/main/join_outer_innodb.test
+++ b/mysql-test/main/join_outer_innodb.test
@@ -374,3 +374,20 @@ drop table t1,t2,t3;
set optimizer_prune_level=@mdev4270_opl;
set optimizer_search_depth=@mdev4270_osd;
+--echo #
+--echo # Bug #20939184:INNODB: UNLOCK ROW COULD NOT FIND A 2 MODE LOCK ON THE
+--echo # RECORD
+--echo #
+CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1,c2) ) engine=innodb;
+CREATE TABLE t2 (c1 INT, c2 INT, c3 INT, PRIMARY KEY (c1), KEY (c2)) engine=innodb;
+INSERT INTO t1 VALUES (1,2,3),(2,3,4),(3,4,5);
+INSERT INTO t2 SELECT * FROM t1;
+SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
+START TRANSACTION;
+#unlocks rows in table t2 where c1 = 1
+SELECT * FROM t1 LEFT JOIN t2 ON t1.c2=t2.c2 AND t2.c1=1 FOR UPDATE;
+UPDATE t1 LEFT JOIN t2 ON t1.c1 = t2.c2 AND t2.c1 = 3 SET t1.c3 = RAND()*10;
+COMMIT;
+SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
+DROP TABLE t1,t2;
+
diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test
index 8dc595ab594..2315580410f 100644
--- a/mysql-test/main/limit_rows_examined.test
+++ b/mysql-test/main/limit_rows_examined.test
@@ -2,11 +2,6 @@
# Tests for LIMIT ROWS EXAMINED, MDEV-28
#
-if (`SELECT $PS_PROTOCOL != 0`)
-{
- --skip Test temporarily disabled for ps-protocol
-}
-
--source include/default_optimizer_switch.inc
call mtr.add_suppression("Sort aborted.*");
diff --git a/mysql-test/main/mysqld--defaults-file.test b/mysql-test/main/mysqld--defaults-file.test
index 4859cc17b42..9ca427568ef 100644
--- a/mysql-test/main/mysqld--defaults-file.test
+++ b/mysql-test/main/mysqld--defaults-file.test
@@ -4,6 +4,7 @@
source include/not_embedded.inc;
source include/not_windows.inc;
+source include/not_aix.inc;
# All these tests refer to configuration files that do not exist
diff --git a/mysql-test/main/mysqld--help,aix.rdiff b/mysql-test/main/mysqld--help,aix.rdiff
index e69de29bb2d..972f8b1844b 100644
--- a/mysql-test/main/mysqld--help,aix.rdiff
+++ b/mysql-test/main/mysqld--help,aix.rdiff
@@ -0,0 +1,76 @@
+diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result
+index 7b0ce27ead3..38176dcaa86 100644
+--- a/mysql-test/main/mysqld--help.result
++++ b/mysql-test/main/mysqld--help.result
+@@ -1301,8 +1301,6 @@ The following specify which files/extra groups are read (specified before remain
+ WHERE clause, or a LIMIT clause, or else they will
+ aborted. Prevents the common mistake of accidentally
+ deleting or updating every row in a table.
+- --stack-trace Print a symbolic stack trace on failure
+- (Defaults to on; use --skip-stack-trace to disable.)
+ --standard-compliant-cte
+ Allow only CTEs compliant to SQL standard
+ (Defaults to on; use --skip-standard-compliant-cte to disable.)
+@@ -1367,39 +1365,6 @@ The following specify which files/extra groups are read (specified before remain
+ --thread-cache-size=#
+ How many threads we should keep in a cache for reuse.
+ These are freed after 5 minutes of idle time
+- --thread-pool-dedicated-listener
+- If set to 1,listener thread will not pick up queries
+- --thread-pool-exact-stats
+- If set to 1, provides better statistics in
+- information_schema threadpool tables
+- --thread-pool-idle-timeout=#
+- Timeout in seconds for an idle thread in the thread
+- pool.Worker thread will be shut down after timeout
+- --thread-pool-max-threads=#
+- Maximum allowed number of worker threads in the thread
+- pool
+- --thread-pool-oversubscribe=#
+- How many additional active worker threads in a group are
+- allowed.
+- --thread-pool-prio-kickup-timer=#
+- The number of milliseconds before a dequeued low-priority
+- statement is moved to the high-priority queue
+- --thread-pool-priority=name
+- Threadpool priority. High priority connections usually
+- start executing earlier than low priority.If priority set
+- to 'auto', the the actual priority(low or high) is
+- determined based on whether or not connection is inside
+- transaction.
+- --thread-pool-size=#
+- Number of thread groups in the pool. This parameter is
+- roughly equivalent to maximum number of concurrently
+- executing threads (threads in a waiting state do not
+- count as executing).
+- --thread-pool-stall-limit=#
+- Maximum query execution time in milliseconds,before an
+- executing non-yielding thread is considered stalled.If a
+- worker thread is stalled, additional worker thread may be
+- created to handle remaining clients.
+ --thread-stack=# The stack size for each thread
+ --time-format=name The TIME format (ignored)
+ --tls-version=name TLS protocol version for secure connections.. Any
+@@ -1788,7 +1753,6 @@ slow-query-log FALSE
+ sort-buffer-size 2097152
+ sql-mode STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
+ sql-safe-updates FALSE
+-stack-trace TRUE
+ standard-compliant-cte TRUE
+ stored-program-cache 256
+ strict-password-validation TRUE
+@@ -1807,14 +1771,6 @@ tcp-keepalive-probes 0
+ tcp-keepalive-time 0
+ tcp-nodelay TRUE
+ thread-cache-size 151
+-thread-pool-dedicated-listener FALSE
+-thread-pool-exact-stats FALSE
+-thread-pool-idle-timeout 60
+-thread-pool-max-threads 65536
+-thread-pool-oversubscribe 3
+-thread-pool-prio-kickup-timer 1000
+-thread-pool-priority auto
+-thread-pool-stall-limit 500
+ thread-stack 299008
+ time-format %H:%i:%s
+ tmp-disk-table-size 18446744073709551615
diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test
index 35a1f99236f..e0c65723012 100644
--- a/mysql-test/main/opt_trace.test
+++ b/mysql-test/main/opt_trace.test
@@ -1,9 +1,6 @@
-if (`SELECT $PS_PROTOCOL != 0`)
-{
- --skip Test temporarily disabled for ps-protocol
-}
--source include/not_embedded.inc
--source include/have_sequence.inc
+--source include/protocol.inc
SELECT table_name, column_name FROM information_schema.columns where table_name="OPTIMIZER_TRACE";
show variables like 'optimizer_trace';
set optimizer_trace="enabled=on";
@@ -267,12 +264,14 @@ begin
return a;
end|
+--enable_prepare_warnings
create function f2(a int) returns int
begin
declare a int default 0;
select count(*) from t2 into a;
return a;
end|
+--disable_prepare_warnings
delimiter ;|
set optimizer_trace='enabled=on';
diff --git a/mysql-test/mariadb-test-run.pl b/mysql-test/mariadb-test-run.pl
index becf799c825..7b9422565ab 100755
--- a/mysql-test/mariadb-test-run.pl
+++ b/mysql-test/mariadb-test-run.pl
@@ -244,7 +244,7 @@ my $opt_ssl;
my $opt_skip_ssl;
my @opt_skip_test_list;
our $opt_ssl_supported;
-my $opt_ps_protocol;
+our $opt_ps_protocol;
my $opt_sp_protocol;
my $opt_cursor_protocol;
my $opt_view_protocol;
diff --git a/mysql-test/suite.pm b/mysql-test/suite.pm
index 5100b4137a2..4cc6b410fa1 100644
--- a/mysql-test/suite.pm
+++ b/mysql-test/suite.pm
@@ -25,6 +25,12 @@ sub skip_combinations {
$skip{'include/platform.combinations'} = [ 'aix', 'win' ];
}
+ if ( $::opt_ps_protocol ) {
+ $skip{'include/protocol.combinations'} = [ 'nm' ];
+ } else {
+ $skip{'include/protocol.combinations'} = [ 'ps' ];
+ }
+
$skip{'include/maybe_debug.combinations'} =
[ defined $::mysqld_variables{'debug-dbug'} ? 'release' : 'debug' ];
diff --git a/mysql-test/suite/innodb/t/innodb_bug53756-master.opt b/mysql-test/suite/innodb/t/innodb_bug53756-master.opt
index 425fda95086..590d44a6d12 100644
--- a/mysql-test/suite/innodb/t/innodb_bug53756-master.opt
+++ b/mysql-test/suite/innodb/t/innodb_bug53756-master.opt
@@ -1 +1 @@
---skip-stack-trace --skip-core-file
+--loose-skip-stack-trace --skip-core-file
diff --git a/mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff b/mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff
new file mode 100644
index 00000000000..f07e82c3472
--- /dev/null
+++ b/mysql-test/suite/sys_vars/r/stored_program_cache_func,ps.rdiff
@@ -0,0 +1,18 @@
+--- stored_program_cache_func.result
++++ stored_program_cache_func,ps.result
+@@ -21,13 +21,13 @@
+ 1
+ show status like 'handler_read_key';
+ Variable_name Value
+-Handler_read_key 2
++Handler_read_key 3
+ call p1;
+ 1
+ 1
+ show status like 'handler_read_key';
+ Variable_name Value
+-Handler_read_key 3
++Handler_read_key 5
+ drop procedure p1;
+ set global stored_program_cache=default;
+ create procedure pr(i int) begin
diff --git a/mysql-test/suite/sys_vars/t/stored_program_cache_func.test b/mysql-test/suite/sys_vars/t/stored_program_cache_func.test
index 86cdd56a6de..611c33b530e 100644
--- a/mysql-test/suite/sys_vars/t/stored_program_cache_func.test
+++ b/mysql-test/suite/sys_vars/t/stored_program_cache_func.test
@@ -1,7 +1,5 @@
-if (`SELECT $PS_PROTOCOL != 0`)
-{
- --skip Test temporarily disabled for ps-protocol
-}
+--source include/protocol.inc
+
create procedure p1() select 1;
flush status;
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test
index 4afcc0379f0..b06a5069514 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_basic.test
@@ -1,6 +1,7 @@
# uint global
--source include/not_windows.inc
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @start_global_value = @@global.thread_pool_idle_timeout;
#
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test
index 71b007bde23..8f5f2491e12 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_idle_timeout_grant.test
@@ -1,5 +1,6 @@
--source include/not_windows.inc
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @global=@@global.thread_pool_idle_timeout;
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test
index 3d5cd5f5198..392dbd3a145 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_basic.test
@@ -1,5 +1,6 @@
# uint global
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @start_global_value = @@global.thread_pool_max_threads;
#
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test
index 29a9ac42ea0..299d5ff4f44 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_max_threads_grant.test
@@ -1,5 +1,6 @@
# uint global
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @global=@@global.thread_pool_max_threads;
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test
index 131fbe98502..1447c83d39c 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_min_threads_basic.test
@@ -1,6 +1,7 @@
# uint global
--source include/not_embedded.inc
--source include/windows.inc
+--source include/not_aix.inc
SET @start_global_value = @@global.thread_pool_min_threads;
#
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test
index 74f0f5e6ea7..43817febafd 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_basic.test
@@ -1,6 +1,7 @@
# uint global
--source include/not_windows.inc
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @start_global_value = @@global.thread_pool_oversubscribe;
#
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test
index cbffb94c297..f3a96c69e8a 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_oversubscribe_grant.test
@@ -1,5 +1,6 @@
--source include/not_windows.inc
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @global=@@global.thread_pool_oversubscribe;
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test
index 1ab27907535..2d1dc59476c 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_basic.test
@@ -1,5 +1,6 @@
# uint global
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @start_global_value = @@global.thread_pool_stall_limit;
#
diff --git a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test
index 8c0908fe2c0..ae0ed8a785b 100644
--- a/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test
+++ b/mysql-test/suite/sys_vars/t/thread_pool_stall_limit_grant.test
@@ -1,5 +1,6 @@
# uint global
--source include/not_embedded.inc
+--source include/not_aix.inc
SET @global=@@global.thread_pool_stall_limit;
diff --git a/sql/myskel.m4 b/sql/myskel.m4
index b26fe46d342..8239b983f04 100644
--- a/sql/myskel.m4
+++ b/sql/myskel.m4
@@ -2,15 +2,10 @@
# fix the #line directives in the generated .cc files
# to refer to the original sql_yacc.yy
#
-m4_define([yyfile],m4_bpatsubst(__file__,[[a-z.0-9]+$],sql_yacc.yy))
-
m4_define([b4_syncline],
-[m4_if(m4_index([$2],[.yy]),[-1],
-[b4_sync_start([$1], [$2])[]dnl
-
-],[b4_sync_start([$1], ["yyfile"])[]dnl
+[b4_sync_start([$1], m4_bpatsubst([$2],[yy_[a-z]+\.yy],sql_yacc.yy))[]dnl
-])])
+])
# try both paths for different bison versions
m4_sinclude(skeletons/c-skel.m4)
diff --git a/sql/net_serv.cc b/sql/net_serv.cc
index 8b0f1eed46d..39b4290a161 100644
--- a/sql/net_serv.cc
+++ b/sql/net_serv.cc
@@ -179,14 +179,26 @@ my_bool my_net_init(NET *net, Vio *vio, void *thd, uint my_flags)
DBUG_RETURN(0);
}
+
+/**
+ Allocate and assign new net buffer
+
+ @note In case of error the old buffer left
+
+ @retval TRUE error
+ @retval FALSE success
+*/
+
my_bool net_allocate_new_packet(NET *net, void *thd, uint my_flags)
{
+ uchar *tmp;
DBUG_ENTER("net_allocate_new_packet");
- if (!(net->buff=(uchar*) my_malloc(key_memory_NET_buff,
- (size_t) net->max_packet +
- NET_HEADER_SIZE + COMP_HEADER_SIZE + 1,
- MYF(MY_WME | my_flags))))
+ if (!(tmp= (uchar*) my_malloc(key_memory_NET_buff,
+ (size_t) net->max_packet +
+ NET_HEADER_SIZE + COMP_HEADER_SIZE + 1,
+ MYF(MY_WME | my_flags))))
DBUG_RETURN(1);
+ net->buff= tmp;
net->buff_end=net->buff+net->max_packet;
net->write_pos=net->read_pos = net->buff;
DBUG_RETURN(0);
diff --git a/sql/protocol.cc b/sql/protocol.cc
index c0a5f2327a0..7886ecd3043 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -597,6 +597,7 @@ void Protocol::end_statement()
thd->get_stmt_da()->get_sqlstate());
break;
case Diagnostics_area::DA_EOF:
+ case Diagnostics_area::DA_EOF_BULK:
error= send_eof(thd->server_status,
thd->get_stmt_da()->statement_warn_count());
break;
@@ -1135,7 +1136,8 @@ static bool should_send_column_info(THD* thd, List<Item>* list, uint flags)
auto cmd= thd->get_command();
#endif
- DBUG_ASSERT(cmd == COM_STMT_EXECUTE || cmd == COM_STMT_PREPARE);
+ DBUG_ASSERT(cmd == COM_STMT_EXECUTE || cmd == COM_STMT_PREPARE
+ || cmd == COM_STMT_BULK_EXECUTE);
DBUG_ASSERT(cmd != COM_STMT_PREPARE || !column_info_state.initialized);
bool ret= metadata_columns_changed(column_info_state, thd, *list);
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index 34fa14d4324..0a2db2ea93a 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -709,7 +709,12 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
!table->prepare_triggers_for_delete_stmt_or_event())
will_batch= !table->file->start_bulk_delete();
- if (returning)
+ /*
+ thd->get_stmt_da()->is_set() means first iteration of prepared statement
+ with array binding operation execution (non optimized so it is not
+ INSERT)
+ */
+ if (returning && !thd->get_stmt_da()->is_set())
{
if (result->send_result_set_metadata(returning->item_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index bb47502b3ce..cef9e6cec00 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -371,7 +371,7 @@ Diagnostics_area::set_eof_status(THD *thd)
{
DBUG_ENTER("set_eof_status");
/* Only allowed to report eof if has not yet reported an error */
- DBUG_ASSERT(! is_set());
+ DBUG_ASSERT(!is_set() || (m_status == DA_EOF_BULK && is_bulk_op()));
/*
In production, refuse to overwrite an error or a custom response
with an EOF packet.
@@ -384,11 +384,23 @@ Diagnostics_area::set_eof_status(THD *thd)
number of warnings, since they are not available to the client
anyway.
*/
- m_statement_warn_count= (thd->spcont ?
- 0 :
- current_statement_warn_count());
+ if (m_status == DA_EOF_BULK)
+ {
+ if (!thd->spcont)
+ m_statement_warn_count+= current_statement_warn_count();
+ }
+ else
+ {
+ if (thd->spcont)
+ {
+ m_statement_warn_count= 0;
+ m_affected_rows= 0;
+ }
+ else
+ m_statement_warn_count= current_statement_warn_count();
+ m_status= (is_bulk_op() ? DA_EOF_BULK : DA_EOF);
+ }
- m_status= DA_EOF;
DBUG_VOID_RETURN;
}
diff --git a/sql/sql_error.h b/sql/sql_error.h
index a3782048c79..6b0d4d7749c 100644
--- a/sql/sql_error.h
+++ b/sql/sql_error.h
@@ -970,6 +970,8 @@ public:
DA_EOF,
/** Set whenever one calls my_ok() in PS bulk mode. */
DA_OK_BULK,
+ /** Set whenever one calls my_eof() in PS bulk mode. */
+ DA_EOF_BULK,
/** Set whenever one calls my_error() or my_message(). */
DA_ERROR,
/** Set in case of a custom response, such as one from COM_STMT_PREPARE. */
@@ -1029,8 +1031,11 @@ public:
enum_diagnostics_status status() const { return m_status; }
const char *message() const
- { DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK ||
- m_status == DA_OK_BULK); return m_message; }
+ {
+ DBUG_ASSERT(m_status == DA_ERROR || m_status == DA_OK ||
+ m_status == DA_OK_BULK || m_status == DA_EOF_BULK);
+ return m_message;
+ }
uint sql_errno() const
@@ -1057,7 +1062,7 @@ public:
uint statement_warn_count() const
{
DBUG_ASSERT(m_status == DA_OK || m_status == DA_OK_BULK ||
- m_status == DA_EOF);
+ m_status == DA_EOF ||m_status == DA_EOF_BULK );
return m_statement_warn_count;
}
diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc
index 24ffad7368a..e258d46f78a 100644
--- a/sql/sql_insert.cc
+++ b/sql/sql_insert.cc
@@ -710,6 +710,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
Name_resolution_context *context;
Name_resolution_context_state ctx_state;
SELECT_LEX *returning= thd->lex->has_returning() ? thd->lex->returning() : 0;
+ unsigned char *readbuff= NULL;
#ifndef EMBEDDED_LIBRARY
char *query= thd->query();
@@ -786,7 +787,25 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
/* Prepares LEX::returing_list if it is not empty */
if (returning)
+ {
result->prepare(returning->item_list, NULL);
+ if (thd->is_bulk_op())
+ {
+ /*
+ It is RETURNING which needs network buffer to write result set and
+ it is array binfing which need network buffer to read parameters.
+ So we allocate yet another network buffer.
+ The old buffer will be freed at the end of operation.
+ */
+ DBUG_ASSERT(thd->protocol == &thd->protocol_binary);
+ readbuff= thd->net.buff; // old buffer
+ if (net_allocate_new_packet(&thd->net, thd, MYF(MY_THREAD_SPECIFIC)))
+ {
+ readbuff= NULL; // failure, net_allocate_new_packet keeps old buffer
+ goto abort;
+ }
+ }
+ }
context= &thd->lex->first_select_lex()->context;
/*
@@ -1322,7 +1341,8 @@ values_loop_end:
thd->lex->current_select->save_leaf_tables(thd);
thd->lex->current_select->first_cond_optimization= 0;
}
-
+ if (readbuff)
+ my_free(readbuff);
DBUG_RETURN(FALSE);
abort:
@@ -1336,6 +1356,8 @@ abort:
if (!joins_freed)
free_underlaid_joins(thd, thd->lex->first_select_lex());
thd->abort_on_warning= 0;
+ if (readbuff)
+ my_free(readbuff);
DBUG_RETURN(retval);
}
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index 2f5470db123..e7d02aaeb0d 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -903,6 +903,9 @@ static bool insert_bulk_params(Prepared_statement *stmt,
case STMT_INDICATOR_IGNORE:
param->set_ignore();
break;
+ default:
+ DBUG_ASSERT(0);
+ DBUG_RETURN(1);
}
}
else
@@ -4680,6 +4683,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
uchar *packet_end_arg)
{
Reprepare_observer reprepare_observer;
+ unsigned char *readbuff= NULL;
bool error= 0;
packet= packet_arg;
packet_end= packet_end_arg;
@@ -4693,24 +4697,37 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
if (state == Query_arena::STMT_ERROR)
{
my_message(last_errno, last_error, MYF(0));
- thd->set_bulk_execution(0);
- return TRUE;
+ goto err;
}
/* Check for non zero parameter count*/
if (param_count == 0)
{
DBUG_PRINT("error", ("Statement with no parameters for bulk execution."));
my_error(ER_UNSUPPORTED_PS, MYF(0));
- thd->set_bulk_execution(0);
- return TRUE;
+ goto err;
}
if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_SAFE))
{
DBUG_PRINT("error", ("Command is not supported in bulk execution."));
my_error(ER_UNSUPPORTED_PS, MYF(0));
- thd->set_bulk_execution(0);
- return TRUE;
+ goto err;
+ }
+ /*
+ Here second buffer for not optimized commands,
+ optimized commands do it inside thier internal loop.
+ */
+ if (!(sql_command_flags[lex->sql_command] & CF_PS_ARRAY_BINDING_OPTIMIZED) &&
+ this->lex->has_returning())
+ {
+ // Above check can be true for SELECT in future
+ DBUG_ASSERT(lex->sql_command != SQLCOM_SELECT);
+ readbuff= thd->net.buff; // old buffer
+ if (net_allocate_new_packet(&thd->net, thd, MYF(MY_THREAD_SPECIFIC)))
+ {
+ readbuff= NULL; // failure, net_allocate_new_packet keeps old buffer
+ goto err;
+ }
}
#ifndef EMBEDDED_LIBRARY
@@ -4722,9 +4739,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
{
my_error(ER_WRONG_ARGUMENTS, MYF(0),
"mysqld_stmt_bulk_execute");
- reset_stmt_params(this);
- thd->set_bulk_execution(0);
- return true;
+ goto err;
}
read_types= FALSE;
@@ -4741,8 +4756,7 @@ Prepared_statement::execute_bulk_loop(String *expanded_query,
{
if (set_bulk_parameters(TRUE))
{
- thd->set_bulk_execution(0);
- return true;
+ goto err;
}
}
@@ -4806,8 +4820,16 @@ reexecute:
}
reset_stmt_params(this);
thd->set_bulk_execution(0);
-
+ if (readbuff)
+ my_free(readbuff);
return error;
+
+err:
+ reset_stmt_params(this);
+ thd->set_bulk_execution(0);
+ if (readbuff)
+ my_free(readbuff);
+ return true;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 5a02218bb4a..08de2565caf 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -190,6 +190,7 @@ static int join_read_system(JOIN_TAB *tab);
static int join_read_const(JOIN_TAB *tab);
static int join_read_key(JOIN_TAB *tab);
static void join_read_key_unlock_row(st_join_table *tab);
+static void join_const_unlock_row(JOIN_TAB *tab);
static int join_read_always_key(JOIN_TAB *tab);
static int join_read_last_key(JOIN_TAB *tab);
static int join_no_more_records(READ_RECORD *info);
@@ -11189,8 +11190,12 @@ static bool create_ref_for_key(JOIN *join, JOIN_TAB *j,
else
j->type=JT_EQ_REF;
- j->read_record.unlock_row= (j->type == JT_EQ_REF)?
- join_read_key_unlock_row : rr_unlock_row;
+ if (j->type == JT_EQ_REF)
+ j->read_record.unlock_row= join_read_key_unlock_row;
+ else if (j->type == JT_CONST)
+ j->read_record.unlock_row= join_const_unlock_row;
+ else
+ j->read_record.unlock_row= rr_unlock_row;
DBUG_RETURN(0);
}
@@ -13455,6 +13460,7 @@ make_join_readinfo(JOIN *join, ulonglong options, uint no_jbuf_after)
/* Only happens with outer joins */
tab->read_first_record= tab->type == JT_SYSTEM ? join_read_system
: join_read_const;
+ tab->read_record.unlock_row= join_const_unlock_row;
if (!(table->covering_keys.is_set(tab->ref.key) && !table->no_keyread) &&
(!jcl || jcl > 4) && !tab->ref.is_access_triggered())
push_index_cond(tab, tab->ref.key);
@@ -21726,6 +21732,19 @@ join_read_key_unlock_row(st_join_table *tab)
tab->ref.use_count--;
}
+/**
+ Rows from const tables are read once but potentially used
+ multiple times during execution of a query.
+ Ensure such rows are never unlocked during query execution.
+*/
+
+void
+join_const_unlock_row(JOIN_TAB *tab)
+{
+ DBUG_ASSERT(tab->type == JT_CONST);
+}
+
+
/*
ref access method implementation: "read_first" function
@@ -24178,8 +24197,12 @@ check_reverse_order:
else if (select && select->quick)
select->quick->need_sorted_output();
- tab->read_record.unlock_row= (tab->type == JT_EQ_REF) ?
- join_read_key_unlock_row : rr_unlock_row;
+ if (tab->type == JT_EQ_REF)
+ tab->read_record.unlock_row= join_read_key_unlock_row;
+ else if (tab->type == JT_CONST)
+ tab->read_record.unlock_row= join_const_unlock_row;
+ else
+ tab->read_record.unlock_row= rr_unlock_row;
} // QEP has been modified
diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc
index 44db9986df6..447fba38323 100644
--- a/storage/innobase/buf/buf0dblwr.cc
+++ b/storage/innobase/buf/buf0dblwr.cc
@@ -674,8 +674,7 @@ void buf_dblwr_t::flush_buffered_writes_completed(const IORequest &request)
static_cast<const byte*>(frame)));
ut_ad(lsn);
ut_ad(lsn >= bpage->oldest_modification());
- if (lsn > log_sys.get_flushed_lsn())
- log_write_up_to(lsn, true);
+ log_write_up_to(lsn, true);
e.request.node->space->io(e.request, bpage->physical_offset(), e_size,
frame, bpage);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 2a91106ba22..65dc7fcae1a 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -15432,7 +15432,7 @@ ha_innobase::extra(
case HA_EXTRA_END_ALTER_COPY:
m_prebuilt->table->skip_alter_undo = 0;
if (!m_prebuilt->table->is_temporary()) {
- log_write_up_to(LSN_MAX, true);
+ log_buffer_flush_to_disk();
}
break;
default:/* Do nothing */
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 89cef8d69ed..0fe7b22fb04 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -705,15 +705,6 @@ public:
/** Shut down the redo log subsystem. */
void close();
-
- /** Initiate a write of the log buffer to the file if needed.
- @param flush whether to initiate a durable write */
- inline void initiate_write(bool flush)
- {
- const lsn_t lsn= get_lsn();
- if (!flush || get_flushed_lsn() < lsn)
- log_write_up_to(lsn, flush);
- }
};
/** Redo log system */
diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc
index 5e64007ef84..1c0a617191e 100644
--- a/storage/innobase/log/log0log.cc
+++ b/storage/innobase/log/log0log.cc
@@ -791,6 +791,7 @@ void log_write_up_to(lsn_t lsn, bool flush_to_disk, bool rotate_key,
{
ut_ad(!srv_read_only_mode);
ut_ad(!rotate_key || flush_to_disk);
+ ut_ad(lsn != LSN_MAX);
if (recv_no_ibuf_operations)
{
diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc
index d7bb3ce886b..76a703b7496 100644
--- a/storage/innobase/mtr/mtr0mtr.cc
+++ b/storage/innobase/mtr/mtr0mtr.cc
@@ -702,7 +702,7 @@ static lsn_t log_reserve_and_open(size_t len)
DEBUG_SYNC_C("log_buf_size_exceeded");
/* Not enough free space, do a write of the log buffer */
- log_sys.initiate_write(false);
+ log_write_up_to(log_sys.get_lsn(), false);
srv_stats.log_waits.inc();
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index bb85e82cbb8..b8f78775624 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2672,7 +2672,7 @@ rollback:
ALTER TABLE...DISCARD TABLESPACE operation altogether. */
err= row_discard_tablespace(trx, table);
DBUG_EXECUTE_IF("ib_discard_before_commit_crash",
- log_write_up_to(LSN_MAX, true); DBUG_SUICIDE(););
+ log_buffer_flush_to_disk(); DBUG_SUICIDE(););
/* FTS_ tables may be deleted */
std::vector<pfs_os_file_t> deleted;
trx->commit(deleted);
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index ce020a6b88d..8692eaa0e89 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -1477,7 +1477,7 @@ static void srv_sync_log_buffer_in_background()
srv_main_thread_op_info = "flushing log";
if (difftime(current_time, srv_last_log_flush_time)
>= srv_flush_log_at_timeout) {
- log_sys.initiate_write(true);
+ log_buffer_flush_to_disk();
srv_last_log_flush_time = current_time;
srv_log_writes_and_flush++;
}
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index d0596cded6b..bac9a3b25b5 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -328,7 +328,7 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn,
mysql_mutex_unlock(&log_sys.mutex);
log_make_checkpoint();
- log_write_up_to(LSN_MAX, true);
+ log_buffer_flush_to_disk();
return DB_SUCCESS;
}
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 40fa8172e6f..609e058ca52 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -777,7 +777,7 @@ not_free:
DBUG_EXECUTE_IF("ib_undo_trunc",
ib::info() << "ib_undo_trunc";
- log_write_up_to(LSN_MAX, true);
+ log_buffer_flush_to_disk();
DBUG_SUICIDE(););
for (auto& rseg : trx_sys.rseg_array) {
diff --git a/storage/perfschema/pfs.cc b/storage/perfschema/pfs.cc
index 1bb712f64cc..3e9198a6b6c 100644
--- a/storage/perfschema/pfs.cc
+++ b/storage/perfschema/pfs.cc
@@ -5466,6 +5466,7 @@ void pfs_end_statement_v1(PSI_statement_locker *locker, void *stmt_da)
switch(da->status())
{
case Diagnostics_area::DA_OK_BULK:
+ case Diagnostics_area::DA_EOF_BULK:
case Diagnostics_area::DA_EMPTY:
break;
case Diagnostics_area::DA_OK:
@@ -5706,6 +5707,7 @@ void pfs_end_statement_v1(PSI_statement_locker *locker, void *stmt_da)
switch (da->status())
{
case Diagnostics_area::DA_OK_BULK:
+ case Diagnostics_area::DA_EOF_BULK:
case Diagnostics_area::DA_EMPTY:
break;
case Diagnostics_area::DA_OK:
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index 77ebf0ae3b8..e6c5f4ab654 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -20547,6 +20547,178 @@ static void test_bulk_replace()
rc= mysql_query(mysql, "DROP TABLE t1");
myquery(rc);
}
+
+
+static void test_bulk_insert_returning()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[2], res_bind[2];
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+ int i,
+ id[]= {1, 2, 3, 4},
+ val[]= {1, 1, 1, 1},
+ count= sizeof(id)/sizeof(id[0]);
+ unsigned long length[2];
+ my_bool is_null[2];
+ my_bool error[2];
+ int32 res[2];
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql,
+ "CREATE TABLE t1 (id int not null primary key, active int)");
+ myquery(rc);
+
+ stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_prepare(stmt,
+ "insert into t1 values (?, ?) returning id, active",
+ -1);
+ check_execute(stmt, rc);
+
+ memset(bind, 0, sizeof(bind));
+ bind[0].buffer_type = MYSQL_TYPE_LONG;
+ bind[0].buffer = (void *)id;
+ bind[0].buffer_length = 0;
+ bind[1].buffer_type = MYSQL_TYPE_LONG;
+ bind[1].buffer = (void *)val;
+ bind[1].buffer_length = 0;
+
+ mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ myquery(rc);
+
+ memset(res_bind, 0, sizeof(res_bind));
+ for (i= 0; i < 2; i++)
+ {
+ res_bind[i].buffer_type= MYSQL_TYPE_LONG;
+ res_bind[i].buffer= (char *)&res[i];
+ res_bind[i].is_null= &is_null[i];
+ res_bind[i].length= &length[i];
+ res_bind[i].error= &error[i];
+ }
+ rc= mysql_stmt_bind_result(stmt, res_bind);
+ myquery(rc);
+ rc= mysql_stmt_store_result(stmt);
+ myquery(rc);
+
+ i= 0;
+ while (!mysql_stmt_fetch(stmt))
+ {
+ i++;
+ DIE_IF(is_null[0] || is_null[1]);
+ DIE_IF(res[0] != i);
+ DIE_IF(res[1] != 1);
+ }
+ DIE_IF(i != 4);
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "SELECT id,active FROM t1");
+ myquery(rc);
+
+ result= mysql_store_result(mysql);
+ mytest(result);
+
+ i= 0;
+ while ((row= mysql_fetch_row(result)))
+ {
+ i++;
+ DIE_IF(atoi(row[0]) != i);
+ DIE_IF(atoi(row[1]) != 1);
+ }
+ DIE_IF(i != 4);
+ mysql_free_result(result);
+
+
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+}
+
+static void test_bulk_delete_returning()
+{
+ int rc;
+ MYSQL_STMT *stmt;
+ MYSQL_BIND bind[2], res_bind[2];
+ MYSQL_ROW row;
+ MYSQL_RES *result;
+ int i,
+ id[]= {1, 2, 3, 4},
+ count= sizeof(id)/sizeof(id[0]);
+ unsigned long length[1];
+ my_bool is_null[1];
+ my_bool error[1];
+ int32 res[1];
+
+ rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+ myquery(rc);
+ rc= mysql_query(mysql, "CREATE TABLE t1 (id int not null primary key)");
+ myquery(rc);
+ rc= mysql_query(mysql, "insert into t1 values (1), (2), (3), (4)");
+ myquery(rc);
+ verify_affected_rows(4);
+
+ stmt= mysql_stmt_init(mysql);
+ rc= mysql_stmt_prepare(stmt, "DELETE FROM t1 WHERE id=? RETURNING id", -1);
+ check_execute(stmt, rc);
+
+ memset(bind, 0, sizeof(bind));
+ bind[0].buffer_type = MYSQL_TYPE_LONG;
+ bind[0].buffer = (void *)id;
+ bind[0].buffer_length = 0;
+
+ mysql_stmt_attr_set(stmt, STMT_ATTR_ARRAY_SIZE, (void*)&count);
+ rc= mysql_stmt_bind_param(stmt, bind);
+ check_execute(stmt, rc);
+
+ rc= mysql_stmt_execute(stmt);
+ myquery(rc);
+
+ memset(res_bind, 0, sizeof(res_bind));
+ res_bind[0].buffer_type= MYSQL_TYPE_LONG;
+ res_bind[0].buffer= (char *)&res[0];
+ res_bind[0].is_null= &is_null[0];
+ res_bind[0].length= &length[0];
+ res_bind[0].error= &error[0];
+ rc= mysql_stmt_bind_result(stmt, res_bind);
+ myquery(rc);
+ rc= mysql_stmt_store_result(stmt);
+ myquery(rc);
+
+ i= 0;
+ while (!mysql_stmt_fetch(stmt))
+ {
+ i++;
+ DIE_IF(is_null[0]);
+ DIE_IF(res[0] != i);
+ }
+ DIE_IF(i != 4);
+
+ mysql_stmt_close(stmt);
+
+ rc= mysql_query(mysql, "SELECT id FROM t1");
+ myquery(rc);
+
+ result= mysql_store_result(mysql);
+ mytest(result);
+
+ i= 0;
+ while ((row= mysql_fetch_row(result)))
+ {
+ i++;
+ printf("\nResult (SHOULD NOT BE HERE!!!) %d %s \n", i, row[0]);
+ }
+ DIE_IF(i != 0 );
+ mysql_free_result(result);
+
+
+ rc= mysql_query(mysql, "DROP TABLE t1");
+ myquery(rc);
+}
#endif
@@ -21556,6 +21728,8 @@ static struct my_tests_st my_tests[]= {
{ "test_bulk_autoinc", test_bulk_autoinc},
{ "test_bulk_delete", test_bulk_delete },
{ "test_bulk_replace", test_bulk_replace },
+ { "test_bulk_insert_returning", test_bulk_insert_returning },
+ { "test_bulk_delete_returning", test_bulk_delete_returning },
#endif
{ "test_ps_params_in_ctes", test_ps_params_in_ctes },
{ "test_explain_meta", test_explain_meta },