diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 71704d95c38..170c790d4c6 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -299,6 +299,7 @@ ENDIF() # MDEV-24629, we need it outside of ELSIFs IF(RPM MATCHES "fedora") ALTERNATIVE_NAME("common" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1) + ALTERNATIVE_NAME("shared" "mariadb-connector-c" ${MARIADB_CONNECTOR_C_VERSION}-1) ENDIF() SET(PYTHON_SHEBANG "/usr/bin/python3" CACHE STRING "python shebang") diff --git a/debian/mariadb-plugin-provider-bzip2.lintian-overrides b/debian/mariadb-plugin-provider-bzip2.lintian-overrides index 47298832bcf..50e280b56da 100644 --- a/debian/mariadb-plugin-provider-bzip2.lintian-overrides +++ b/debian/mariadb-plugin-provider-bzip2.lintian-overrides @@ -1,3 +1,4 @@ # It's intentional that bzip2 compression plugin doesn't have symbols from libc # More info https://jira.mariadb.org/browse/MDEV-28120 +library-not-linked-against-libc usr/lib/mysql/plugin/provider_bzip2.so library-not-linked-against-libc [usr/lib/mysql/plugin/provider_bzip2.so] diff --git a/debian/mariadb-plugin-provider-lz4.lintian-overrides b/debian/mariadb-plugin-provider-lz4.lintian-overrides index dbfde133135..4df09a0af4e 100644 --- a/debian/mariadb-plugin-provider-lz4.lintian-overrides +++ b/debian/mariadb-plugin-provider-lz4.lintian-overrides @@ -1,3 +1,4 @@ # It's intentional that LZ4 compression plugin doesn't have symbols from libc # More info https://jira.mariadb.org/browse/MDEV-28120 +library-not-linked-against-libc usr/lib/mysql/plugin/provider_lz4.so library-not-linked-against-libc [usr/lib/mysql/plugin/provider_lz4.so] diff --git a/debian/mariadb-plugin-provider-lzma.lintian-overrides b/debian/mariadb-plugin-provider-lzma.lintian-overrides index 79f6cb793c2..2d9f4b8adc2 100644 --- a/debian/mariadb-plugin-provider-lzma.lintian-overrides +++ b/debian/mariadb-plugin-provider-lzma.lintian-overrides @@ -1,3 +1,4 @@ # It's intentional that LZMA compression plugin doesn't have symbols from libc # More info https://jira.mariadb.org/browse/MDEV-28120 +library-not-linked-against-libc usr/lib/mysql/plugin/provider_lzma.so library-not-linked-against-libc [usr/lib/mysql/plugin/provider_lzma.so] diff --git a/debian/mariadb-plugin-provider-lzo.lintian-overrides b/debian/mariadb-plugin-provider-lzo.lintian-overrides index ccca4e2d355..13015fde854 100644 --- a/debian/mariadb-plugin-provider-lzo.lintian-overrides +++ b/debian/mariadb-plugin-provider-lzo.lintian-overrides @@ -1,3 +1,4 @@ # It's intentional that LZO compression plugin doesn't have symbols from libc # More info https://jira.mariadb.org/browse/MDEV-28120 +library-not-linked-against-libc usr/lib/mysql/plugin/provider_lzo.so library-not-linked-against-libc [usr/lib/mysql/plugin/provider_lzo.so] diff --git a/debian/mariadb-plugin-provider-snappy.lintian-overrides b/debian/mariadb-plugin-provider-snappy.lintian-overrides index b62907c3469..2ddf25d0dd0 100644 --- a/debian/mariadb-plugin-provider-snappy.lintian-overrides +++ b/debian/mariadb-plugin-provider-snappy.lintian-overrides @@ -1,3 +1,4 @@ # It's intentional that Snappy compression plugin doesn't have symbols from libc # More info https://jira.mariadb.org/browse/MDEV-28120 +library-not-linked-against-libc usr/lib/mysql/plugin/provider_snappy.so library-not-linked-against-libc [usr/lib/mysql/plugin/provider_snappy.so] diff --git a/debian/salsa-ci.yml b/debian/salsa-ci.yml index a5c0ec3ee9c..0c0d3e62301 100644 --- a/debian/salsa-ci.yml +++ b/debian/salsa-ci.yml @@ -56,6 +56,14 @@ build i386: script: - *autobake-deb-steps +build bullseye-backports: + extends: .build-package + variables: + RELEASE: bullseye-backports + +# Buster only has libfmt 6.1 but 7.0 is required, so backport build for Buster +# is not possible unless somebody packages libfmt7-dev for Buster. + build sid: extends: .build-package script: @@ -112,6 +120,12 @@ blhc: mysql --table -e "SELECT * FROM plugin;" mysql mysql --table -e "SHOW PLUGINS;" mysql +# Readline was removed from Debian Sid (and Bullseye) in Feb 2021. To be able to install older +# versions of MariaDB that depend on it, fetch and install it from Buster. +.test-install-readline-in-sid-for-backwards-compat: &test-install-readline-in-sid-for-backwards-compat | + curl -sS -O http://ftp.de.debian.org/debian/pool/main/r/readline5/libreadline5_5.2+dfsg-3+b13_amd64.deb + apt-get -qq install --no-install-recommends --yes ./libreadline5_5.2+dfsg-3+b13_amd64.deb + .test-enable-bullseye-repos: &test-enable-bullseye-repos # Replace any old repos with just Sid - echo 'deb http://deb.debian.org/debian bullseye main' > /etc/apt/sources.list @@ -119,6 +133,17 @@ blhc: - apt-get update -qq - apt-get install -y apt +.test-enable-buster-backports-repos: &test-enable-buster-backports-repos | + # Enable buster-backports (assumes environment already Debian Buster) + echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/buster-backports.list + # Increase default backports priority policy from '100' to '500' so it can actually be used + cat << EOF > /etc/apt/preferences.d/enable-backports-to-satisfy-dependencies + Package: * + Pin: release n=buster-* + Pin-Priority: 500 + EOF + apt-get update -qq + .test-enable-bullseye-backports-repos: &test-enable-bullseye-backports-repos | # Enable bullseye-backports (assumes environment already Debian Bullseye) echo 'deb http://deb.debian.org/debian bullseye-backports main' > /etc/apt/sources.list.d/bullseye-backports.list @@ -130,16 +155,28 @@ blhc: EOF apt-get update -qq -.test-enable-buster-backports-repos: &test-enable-buster-backports-repos | - # Enable buster-backports (assumes environment already Debian Buster) - echo 'deb http://deb.debian.org/debian buster-backports main' > /etc/apt/sources.list.d/buster-backports.list - # Increase default backports priority policy from '100' to '500' so it can actually be used - cat << EOF > /etc/apt/preferences.d/enable-backports-to-satisfy-dependencies - Package: * - Pin: release n=buster-* - Pin-Priority: 500 - EOF - apt-get update -qq +.test-enable-sid-repos: &test-enable-sid-repos + # Apply usrmerge workaround for Stretch/Buster/Bullseye to Bookworm/Sid upgrades + - echo 'this system will not be supported in the future' > /etc/unsupported-skip-usrmerge-conversion + # Replace any old repos with just Sid + - echo 'deb http://deb.debian.org/debian sid main' > /etc/apt/sources.list + # Upgrade minimal stack first + - apt-get update -qq + # Next step will fail on https://bugs.debian.org/993755 + # /usr/bin/perl: error while loading shared libraries: libcrypt.so.1: cannot + # open shared object file: No such file or directory + # dpkg: error processing package libc6:amd64 (--configure): + - apt-get install -y apt || true + # Apply workaround + - cd $(mktemp -d) # Use temp dir where apt can download and unpack files + - apt-get -y download libcrypt1 + - dpkg-deb -x libcrypt1_*.deb . + - cp -ra lib/* /lib/ + - cd - # Back to /builds/$USER/mariadb-server/debian/output + - find /lib/*/libcrypt.* -ls # Show that new libcrypt is there + - apt-get -y --fix-broken install + # Complete upgrade of minimal stack + - apt-get install -y apt .test-install: &test-install # Install MariaDB built in this commit @@ -252,35 +289,6 @@ mariadb-10.5 Bullseye upgrade: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ -mariadb-10.3 with Buster backports upgrade: - stage: upgrade extras - needs: - - job: build buster-backports - image: debian:buster - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug - script: - - *test-prepare-container - # Install everything MariaDB 10.3 currently in Debian Buster - - apt-get install -y 'default-mysql*' 'mariadb-*' 'libmariadb*' - # Verify installation of MariaDB from Buster - - *test-verify-initial - # Buster backports is needed for liburing1 (>= 0.7) and galera-4 (>= 26.4) - - *test-enable-buster-backports-repos - - *test-install - # mariadb-10.3 in Buster ships a /etc/init.d/mysql so it should continue to work - - service mysql status - - service mariadb status - - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ - mariadb-10.3 Buster upgrade: stage: upgrade from Buster needs: @@ -490,6 +498,43 @@ mysql-8.0 from Ubuntu 22.04 upgrade: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ +# Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. +# The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. +mysql-community-cluster-8.0 from MySQL.com upgrade: + stage: upgrade extras + needs: + - job: build + image: debian:${RELEASE} + artifacts: + when: always + name: "$CI_BUILD_NAME" + paths: + - ${WORKING_DIR}/debug + script: + - *test-prepare-container + - apt-get install --no-install-recommends --yes ca-certificates curl systemctl + - curl -sS "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x859be8d7c586f538430b19c2467b942d3a79bd29" -o /etc/apt/trusted.gpg.d/mysql.asc + - echo "deb https://repo.mysql.com/apt/debian/ bullseye mysql-cluster-8.0" > /etc/apt/sources.list.d/mysql.list + - apt-get update -qq + - apt-get install -y mysql-cluster-community-server + - sed 's/ExecStartPre=+/ExecStartPre=/' -i /lib/systemd/system/mysql.service # Hack to make file compatible with systemctl shim + - systemctl start mysql + - dpkg -l | grep -iE 'maria|mysql|galera' + - systemctl status mysql; mysql -e 'SELECT VERSION()' + - systemctl stop mysql # Stop manually as maintainer scripts don't handle this with systemctl shim + - *test-install + # Ignore systemctl shim result as MariaDB systemd file is incompatible with it and yields: + # ERROR:systemctl:the ExecStartPre control process exited with error code + - systemctl status mysql || true + - mysql -e 'SELECT VERSION()' || true + - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server + - *test-verify-final + variables: + GIT_STRATEGY: none + except: + variables: + - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ + mariadb.org 10.11 to mariadb upgrade: stage: upgrade extras needs: @@ -570,7 +615,7 @@ mariadb.org 10.9 to mariadb upgrade: - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - echo "deb https://deb.mariadb.org/10.9/debian ${RELEASE} main" > /etc/apt/sources.list.d/mariadb.list - apt-get update - - apt-get install -y mariadb-server + - apt-get install -y mariadb-server-10.9 mariadb-client-10.9 - *test-verify-initial # Install MariaDB built in this commit # Force downgrades so our version installs on top of upstream revision, e.g. 1:10.9.1-1 vs 1:10.9.1+mariadb~sid @@ -618,43 +663,6 @@ mariadb.org-10.8 to mariadb upgrade: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ -# Upgrading from MySQL 8.0 with datadir in place is not possible. Users need to do a data dump. -# The Debian maintainer scripts detect this situation and simply moves old datadir aside and start fresh. -mysql-community-cluster-8.0 from MySQL.com upgrade: - stage: upgrade extras - needs: - - job: build - image: debian:${RELEASE} - artifacts: - when: always - name: "$CI_BUILD_NAME" - paths: - - ${WORKING_DIR}/debug - script: - - *test-prepare-container - - apt-get install --no-install-recommends --yes ca-certificates curl systemctl - - curl -sS "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x859be8d7c586f538430b19c2467b942d3a79bd29" -o /etc/apt/trusted.gpg.d/mysql.asc - - echo "deb https://repo.mysql.com/apt/debian/ bullseye mysql-cluster-8.0" > /etc/apt/sources.list.d/mysql.list - - apt-get update -qq - - apt-get install -y mysql-cluster-community-server - - sed 's/ExecStartPre=+/ExecStartPre=/' -i /lib/systemd/system/mysql.service # Hack to make file compatible with systemctl shim - - systemctl start mysql - - dpkg -l | grep -iE 'maria|mysql|galera' - - systemctl status mysql; mysql -e 'SELECT VERSION()' - - systemctl stop mysql # Stop manually as maintainer scripts don't handle this with systemctl shim - - *test-install - # Ignore systemctl shim result as MariaDB systemd file is incompatible with it and yields: - # ERROR:systemctl:the ExecStartPre control process exited with error code - - systemctl status mysql || true - - mysql -e 'SELECT VERSION()' || true - - sleep 5 # Give the mysql_upgrade a bit of time to complete before querying the server - - *test-verify-final - variables: - GIT_STRATEGY: none - except: - variables: - - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ - mariadb.org-10.7 to mariadb upgrade: stage: upgrade extras needs: @@ -746,11 +754,11 @@ mariadb.org-10.5 to mariadb upgrade: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ -mariadb.org-10.4 to mariadb with Buster backports upgrade: +mariadb.org-10.4 to mariadb upgrade: stage: upgrade extras needs: - - job: build buster-backports - image: debian:buster + - job: build + image: debian:${RELEASE} artifacts: when: always name: "$CI_BUILD_NAME" @@ -762,6 +770,7 @@ mariadb.org-10.4 to mariadb with Buster backports upgrade: - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - echo "deb https://archive.mariadb.org/mariadb-10.4/repo/debian buster main" > /etc/apt/sources.list.d/mariadb.list - apt-get update -qq + - *test-install-readline-in-sid-for-backwards-compat - apt-get install -y mariadb-server-10.4 # MariaDB.org version of 10.4 and early 10.5 do not install an init file, so # it must be installed here manually @@ -780,11 +789,11 @@ mariadb.org-10.4 to mariadb with Buster backports upgrade: variables: - $CI_COMMIT_TAG != null && $SALSA_CI_ENABLE_PIPELINE_ON_TAGS !~ /^(1|yes|true)$/ -mariadb.org-10.3 to mariadb with Buster backports upgrade: +mariadb.org-10.3 to mariadb upgrade: stage: upgrade extras needs: - - job: build bullseye-backports - image: debian:bullseye + - job: build + image: debian:${RELEASE} artifacts: when: always name: "$CI_BUILD_NAME" @@ -796,6 +805,7 @@ mariadb.org-10.3 to mariadb with Buster backports upgrade: - curl -sS https://mariadb.org/mariadb_release_signing_key.asc -o /etc/apt/trusted.gpg.d/mariadb.asc - echo "deb https://archive.mariadb.org/mariadb-10.3/repo/debian buster main" > /etc/apt/sources.list.d/mariadb.list - apt-get update -qq + - *test-install-readline-in-sid-for-backwards-compat - apt-get install -y mariadb-server-10.3 - *test-verify-initial # Buster backports is needed for liburing1 (>= 0.7) and galera-4 (>= 26.4) diff --git a/debian/source/lintian-overrides b/debian/source/lintian-overrides index 306ab27271d..1ee677bb083 100644 --- a/debian/source/lintian-overrides +++ b/debian/source/lintian-overrides @@ -1,3 +1,6 @@ +# MariaDB use high enough debhelper so this is should +# be considered as bug in lintia +missing-build-dependency-for-dh-addon systemd * # Necessary for drop-in-place-replacement upgrades on mysql-server/-client # since package breaks/replaces these but at the same time also provides them version-substvar-for-external-package mariadb-client-core -> mysql-client-5.5 @@ -7,22 +10,11 @@ version-substvar-for-external-package libmariadb-dev -> libmysqld-dev version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev -> libmysqlclient-dev [debian/control:74] version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev -> libmysqld-dev [debian/control:74] version-substvar-for-external-package libmariadbd-dev -> libmariadbclient-dev -version-substvar-for-external-package Replaces ${source:Version} libmariadbd-dev -> libmariadbclient-dev [debian/control:232] -version-substvar-for-external-package Conflicts (line 408) ${source:Version} mariadb-client -> mariadb-client-10.11 -version-substvar-for-external-package Conflicts (line 575) ${source:Version} mariadb-server-core -> mariadb-server-core-10.11 -version-substvar-for-external-package Conflicts (line 711) ${source:Version} mariadb-server -> mariadb-server-10.11 +# These are left for reason version-substvar-for-external-package version-substvar-for-external-package Conflicts (line 95) ${source:Version} libmariadb-dev-compat -> libmariadbclient-dev version-substvar-for-external-package Replaces (line 109) ${source:Version} libmariadb-dev-compat -> libmariadbclient-dev -version-substvar-for-external-package Replaces (line 330) ${source:Version} mariadb-client-core -> mariadb-client-10.11 -version-substvar-for-external-package Replaces (line 330) ${source:Version} mariadb-client-core -> mariadb-server-core-10.11 -version-substvar-for-external-package Replaces (line 481) ${source:Version} mariadb-client -> mariadb-client-10.11 -version-substvar-for-external-package Replaces (line 481) ${source:Version} mariadb-client -> mariadb-client-core-10.11 -version-substvar-for-external-package Replaces (line 481) ${source:Version} mariadb-client -> mariadb-server-10.11 -version-substvar-for-external-package Replaces (line 481) ${source:Version} mariadb-client -> mariadb-server-core-10.11 -version-substvar-for-external-package Replaces (line 626) ${source:Version} mariadb-server-core -> mariadb-client-10.11 -version-substvar-for-external-package Replaces (line 626) ${source:Version} mariadb-server-core -> mariadb-server-10.11 -version-substvar-for-external-package Replaces (line 748) ${source:Version} mariadb-server -> mariadb-client-10.11 -version-substvar-for-external-package Replaces (line 748) ${source:Version} mariadb-server -> mariadb-server-10.11 +version-substvar-for-external-package Conflicts ${source:Version} libmariadb-dev-compat -> libmariadbclient-dev [*] +version-substvar-for-external-package Replaces ${source:Version} libmariadb-dev-compat -> libmariadbclient-dev [*] # ColumnStore not used in Debian, safe to ignore. Reported upstream in https://jira.mariadb.org/browse/MDEV-24124 source-is-missing storage/columnstore/columnstore/utils/jemalloc/libjemalloc.so.2 source-is-missing [storage/columnstore/columnstore/utils/jemalloc/libjemalloc.so.2] diff --git a/include/m_string.h b/include/m_string.h index 6a645b20a7f..28ad9ee7c88 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -201,7 +201,7 @@ extern ulonglong strtoull(const char *str, char **ptr, int base); #ifdef __cplusplus #include -template inline const char *_swl_check(T s) +template inline constexpr const char *_swl_check(T s) { static_assert(std::is_same::value || std::is_same::value, diff --git a/include/my_compiler.h b/include/my_compiler.h index ff049f3d8a6..b979b5a5b73 100644 --- a/include/my_compiler.h +++ b/include/my_compiler.h @@ -40,7 +40,15 @@ /* GNU C/C++ */ #if defined __GNUC__ # define MY_ALIGN_EXT -# define MY_ASSERT_UNREACHABLE() __builtin_unreachable() + +/* + __builtin_unreachable() removes the "statement may fall through" warning-as- + error when MY_ASSERT_UNREACHABLE() is used in "case xxx:" in switch (...) + statements. + abort() is there to prevent the execution from reaching the + __builtin_unreachable() as this may cause misleading stack traces. +*/ +# define MY_ASSERT_UNREACHABLE() { abort(); __builtin_unreachable(); } /* Microsoft Visual C++ */ #elif defined _MSC_VER @@ -88,7 +96,7 @@ #endif #ifndef MY_ASSERT_UNREACHABLE -# define MY_ASSERT_UNREACHABLE() do { assert(0); } while (0) +# define MY_ASSERT_UNREACHABLE() do { abort(); } while (0) #endif /** diff --git a/mysql-test/include/analyze-format.inc b/mysql-test/include/analyze-format.inc index 4b24f3cc6f4..49edd0097d1 100644 --- a/mysql-test/include/analyze-format.inc +++ b/mysql-test/include/analyze-format.inc @@ -1,3 +1,7 @@ -# The time on ANALYSE FORMAT=JSON is rather variable +# Remove non-deterministic parts of ANALYZE FORMAT=JSON output: +# - any timings +# - Buffer sizes (depend on pointer size) +# - r_engine_stats depends on buffer pool state and whether old record versions +# were purged. ---replace_regex /("(r_[a-z_]*_time(_in_progress)?_ms|r_buffer_size)": )[^, \n]*/\1"REPLACED"/ +--replace_regex /("(r_[a-z_]*_time(_in_progress)?_ms|r_buffer_size)": )[^, \n]*/\1"REPLACED"/ /("r_engine_stats":) {[^}]*}/\1 REPLACED/ diff --git a/mysql-test/include/log_grep.inc b/mysql-test/include/log_grep.inc new file mode 100644 index 00000000000..a2b0c383ae0 --- /dev/null +++ b/mysql-test/include/log_grep.inc @@ -0,0 +1,85 @@ +if ($log_expected_matches) { + --echo [log_grep.inc] file: $log_file pattern: $grep_pattern expected_matches: $log_expected_matches +} +if (!$log_expected_matches) { + --echo [log_grep.inc] file: $log_file pattern: $grep_pattern +} +--let LOG_GREP_PERL_RESULT=$MYSQL_TMP_DIR/log_grep_perl_result.test +perl; + + open my $command_file, ">", "$ENV{'LOG_GREP_PERL_RESULT'}" or die "Cannot create file"; + + $log_file= $ENV{'log_file'}; + $log_file_full_path= $ENV{'log_file_full_path'}; + $log_slow_rate_test= $ENV{'log_slow_rate_test'}; + open(FILE, "$log_file_full_path") + or die("Cannot open file $log_file_full_path: $!\n"); + + if ($log_slow_rate_test) { + $one= 0; + $two= 0; + $three= 0; + while() { + $one++ if(/'connection_one'/); + $two++ if(/'connection_two'/); + $three++ if(/'connection_three'/); + } + $sum= $one + $two + $three; + $zero= 0; + if ($one == 0) { + $zero++; + } + if ($two == 0) { + $zero++; + } + if ($three == 0) { + $zero++; + } + print "[log_grep.inc] sum: $sum\n"; + print "[log_grep.inc] zero: $zero\n"; + } + else { + $grep_pattern= $ENV{'grep_pattern'}; + $lines= 0; + while() { + $lines++ if (/$grep_pattern/); + } + $log_expected_matches= $ENV{'log_expected_matches'}; + if ($log_expected_matches) { + if ($log_expected_matches != $lines) { + print "[log_grep.inc] ERROR: expected matches: $log_expected_matches, actual matches: $lines\n"; + print "[log_grep.inc] log file at $log_file_full_path\n"; + close(FILE); + open(FILE, "$log_file_full_path") + or die("Cannot open file $log_file_full_path: $!\n"); + while () { + print ; + } + print $command_file "--let \$log_grep_failed= 1;\n"; + } else { + print "[log_grep.inc] found expected match count: $log_expected_matches\n"; + } + } else { + print "[log_grep.inc] lines: $lines\n"; + } + } + close(FILE); + close($command_file); +EOF +--source $LOG_GREP_PERL_RESULT +--remove_file $LOG_GREP_PERL_RESULT +if ($log_grep_failed) +{ + SHOW SESSION STATUS LIKE 'Slow_queries'; + SHOW GLOBAL VARIABLES LIKE 'log%'; + SHOW GLOBAL VARIABLES LIKE 'long_query_time'; + SHOW GLOBAL VARIABLES LIKE 'min_examined_row_limit'; + SHOW GLOBAL VARIABLES LIKE 'query_cache%'; + SHOW GLOBAL VARIABLES LIKE 'slow_query%'; + SHOW SESSION VARIABLES LIKE 'log%'; + SHOW SESSION VARIABLES LIKE 'long_query_time'; + SHOW SESSION VARIABLES LIKE 'min_examined_row_limit'; + SHOW SESSION VARIABLES LIKE 'query_cache%'; + SHOW SESSION VARIABLES LIKE 'slow_query%'; + --die Testcase failed! +} diff --git a/mysql-test/include/log_slow_cleanup.inc b/mysql-test/include/log_slow_cleanup.inc new file mode 100644 index 00000000000..f3d87275a31 --- /dev/null +++ b/mysql-test/include/log_slow_cleanup.inc @@ -0,0 +1,6 @@ +--remove_files_wildcard $MYSQLTEST_VARDIR/tmp $log_slow_prefix-*.slog +--disable_query_log +EVAL SET GLOBAL log_output= $log_output_old; +EVAL SET GLOBAL slow_query_log_file= "$slow_query_log_file_old"; +EVAL SET GLOBAL slow_query_log= $slow_query_log_old; +--enable_query_log diff --git a/mysql-test/include/log_slow_grep.inc b/mysql-test/include/log_slow_grep.inc new file mode 100644 index 00000000000..004c8ccefbc --- /dev/null +++ b/mysql-test/include/log_slow_grep.inc @@ -0,0 +1,25 @@ +# Common extensions to the slow query log +--let grep_pattern = ^# Thread_id: .+ Schema: .+ QC_hit: (Yes|No)\$ +--let log_expected_matches = $log_slow_verbosity_expected_matches +--source include/log_grep.inc +--let grep_pattern = ^# Query_time: \d+\.\d+ Lock_time: \d+\.\d+ Rows_sent: \d+ Rows_examined: \d+\$ +--source include/log_grep.inc + --let grep_pattern = ^# Rows_affected: \d+ Bytes_sent: \d+\$ +--source include/log_grep.inc + +# Query plan +--let log_expected_matches = $log_slow_verbosity_queryplan_expected_matches +--let grep_pattern = ^# Full_scan: (Yes|No) Full_join: (Yes|No) Tmp_table: (Yes|No) Tmp_table_on_disk: (Yes|No)\$ +--source include/log_grep.inc +--let grep_pattern = ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)\$ +--source include/log_grep.inc + +# Temp tables +--let log_expected_matches = $log_slow_verbosity_tmptable_expected_matches +--source include/log_grep.inc +--let grep_pattern = ^# Tmp_tables: \d+ Tmp_disk_tables: \d+\$ +--source include/log_grep.inc + +# InnoDB/Engines +--let log_expected_matches = $log_slow_innodb_expected_matches +--let grep_pattern = ^# Pages_accessed: \d+ Pages_read: \d+ Pages_updated: \d+ Old_rows_read: \d+\n# Pages_read_time: \d+\.\d+ Engine_time: \d+\.\d+\$ diff --git a/mysql-test/include/log_slow_prepare.inc b/mysql-test/include/log_slow_prepare.inc new file mode 100644 index 00000000000..7abc56b7fb5 --- /dev/null +++ b/mysql-test/include/log_slow_prepare.inc @@ -0,0 +1,8 @@ +--disable_query_log +--let slow_query_log_old= `select @@slow_query_log` +--let slow_query_log_file_old= `select @@slow_query_log_file` +--let log_output_old= `select @@log_output` + +SET GLOBAL slow_query_log=0; +SET GLOBAL log_output=FILE; +--enable_query_log diff --git a/mysql-test/include/log_slow_start.inc b/mysql-test/include/log_slow_start.inc new file mode 100644 index 00000000000..e562a6976d3 --- /dev/null +++ b/mysql-test/include/log_slow_start.inc @@ -0,0 +1,6 @@ +--disable_query_log +--let log_file_full_path=$MYSQLTEST_VARDIR/tmp/$log_file.slog +--echo [slow_log_start.inc] $log_file +EVAL SET GLOBAL slow_query_log_file="$log_file_full_path"; +SET GLOBAL slow_query_log=1; +--enable_query_log diff --git a/mysql-test/include/log_slow_stop.inc b/mysql-test/include/log_slow_stop.inc new file mode 100644 index 00000000000..7ee24af9d8a --- /dev/null +++ b/mysql-test/include/log_slow_stop.inc @@ -0,0 +1,4 @@ +--disable_query_log +SET GLOBAL slow_query_log=0; +--echo [log_slow_stop.inc] $log_file +--enable_query_log diff --git a/mysql-test/main/analyze_engine_stats.combinations b/mysql-test/main/analyze_engine_stats.combinations new file mode 100644 index 00000000000..09620f9f4da --- /dev/null +++ b/mysql-test/main/analyze_engine_stats.combinations @@ -0,0 +1,5 @@ +[slow_query_log_on] +slow_query_log=ON + +[slow_query_log_off] +slow_query_log=OFF diff --git a/mysql-test/main/analyze_engine_stats.result b/mysql-test/main/analyze_engine_stats.result new file mode 100644 index 00000000000..cc4aa4620b5 --- /dev/null +++ b/mysql-test/main/analyze_engine_stats.result @@ -0,0 +1,118 @@ +create table t1 ( +pk int not null, +a varchar(64), +b varchar(64), +c varchar(64) +) engine=innodb; +insert into t1 select +seq, seq, seq, seq +from +seq_1_to_10000; +analyze table t1 persistent for all; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# Note the r_engine_stats below. Only non-zero members are printed +select '$out' as X; +X +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "r_loops": 1, + "rows": 10000, + "r_rows": 10000, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": "REPLACED" + }, + "filtered": 100, + "r_filtered": 100, + "attached_condition": "t1.pk < 120000" + } + } + ] + } +} +set @js='$out'; +set @out=(select json_extract(@js,'$**.r_engine_stats.pages_accessed')); +select cast(json_extract(@out,'$[0]') as DOUBLE) > 0 as PAGES_ACCESSED_MORE_THAN_ZERO; +PAGES_ACCESSED_MORE_THAN_ZERO +1 +# +# Try an UPDATE +# +select '$out' as X; +X +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "r_total_time_ms": "REPLACED", + "table": { + "update": 1, + "table_name": "t1", + "access_type": "ALL", + "rows": 10000, + "r_rows": 10000, + "r_filtered": 100, + "r_total_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": "REPLACED", + "pages_updated": "REPLACED" + }, + "attached_condition": "t1.pk < 120000" + } + } +} +set @js='$out'; +set @out=(select json_extract(@js,'$**.r_engine_stats.pages_updated')); +select cast(json_extract(@out,'$[0]') as DOUBLE) > 0 as PAGES_UPDATED_MORE_THAN_ZERO; +PAGES_UPDATED_MORE_THAN_ZERO +1 +# +# Try a DELETE +# +select '$out' as X; +X +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "r_total_time_ms": "REPLACED", + "table": { + "delete": 1, + "table_name": "t1", + "access_type": "ALL", + "rows": 10000, + "r_rows": 10000, + "r_filtered": 50, + "r_total_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": "REPLACED", + "pages_updated": "REPLACED" + }, + "attached_condition": "t1.pk MOD 2 = 1" + } + } +} +set @js='$out'; +set @out=(select json_extract(@js,'$**.r_engine_stats.pages_updated')); +select cast(json_extract(@out,'$[0]') as DOUBLE) > 0 as PAGES_UPDATED_MORE_THAN_ZERO; +PAGES_UPDATED_MORE_THAN_ZERO +1 +drop table t1; diff --git a/mysql-test/main/analyze_engine_stats.test b/mysql-test/main/analyze_engine_stats.test new file mode 100644 index 00000000000..a26c65a1aa4 --- /dev/null +++ b/mysql-test/main/analyze_engine_stats.test @@ -0,0 +1,64 @@ +# +# Tests for r_engine_stats in ANALYZE FORMAT=JSON output +# +--source include/analyze-format.inc +--source include/have_sequence.inc +--source include/have_innodb.inc + +create table t1 ( + pk int not null, + a varchar(64), + b varchar(64), + c varchar(64) +) engine=innodb; + +insert into t1 select + seq, seq, seq, seq +from + seq_1_to_10000; + +analyze table t1 persistent for all; + +--echo # Note the r_engine_stats below. Only non-zero members are printed +let $out=` +ANALYZE FORMAT=json +select * from t1 where pk < 120000; +`; + +# Don't use "source include/analyze-format.inc" as it replaces r_engine_stats +# Replace the "pages_accessed" value, too, as it is different for some +# platforms... +--replace_regex /("(r_[a-z_]*_time(_in_progress)?_ms|r_buffer_size|pages_accessed)": )[^, \n]*/\1"REPLACED"/ +evalp select '$out' as X; + +evalp set @js='$out'; +set @out=(select json_extract(@js,'$**.r_engine_stats.pages_accessed')); +select cast(json_extract(@out,'$[0]') as DOUBLE) > 0 as PAGES_ACCESSED_MORE_THAN_ZERO; + +--echo # +--echo # Try an UPDATE +--echo # + +let $out=`analyze format=json update t1 set b = b-1 where pk < 120000`; + +--replace_regex /("(r_[a-z_]*_time_ms|pages_accessed|pages_updated)": )[^, \n]*/\1"REPLACED"/ +evalp select '$out' as X; + +evalp set @js='$out'; +set @out=(select json_extract(@js,'$**.r_engine_stats.pages_updated')); +select cast(json_extract(@out,'$[0]') as DOUBLE) > 0 as PAGES_UPDATED_MORE_THAN_ZERO; + +--echo # +--echo # Try a DELETE +--echo # +let $out=`analyze format=json delete from t1 where mod(pk,2)=1`; + +--replace_regex /("(r_[a-z_]*_time_ms|pages_accessed|pages_updated)": )[^, \n]*/\1"REPLACED"/ +evalp select '$out' as X; + +evalp set @js='$out'; +set @out=(select json_extract(@js,'$**.r_engine_stats.pages_updated')); +select cast(json_extract(@out,'$[0]') as DOUBLE) > 0 as PAGES_UPDATED_MORE_THAN_ZERO; + +drop table t1; + diff --git a/mysql-test/main/analyze_format_json.result b/mysql-test/main/analyze_format_json.result index 8caf594841d..5572a4f35bb 100644 --- a/mysql-test/main/analyze_format_json.result +++ b/mysql-test/main/analyze_format_json.result @@ -22,6 +22,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 30, "attached_condition": "t0.a < 3" @@ -58,6 +59,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 0, "attached_condition": "t0.a > 9 and t0.a is not null" @@ -75,6 +77,7 @@ ANALYZE "r_loops": 0, "rows": 1, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null } @@ -108,6 +111,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t0.a is not null" @@ -127,6 +131,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 40, "attached_condition": "t1.b < 4" @@ -161,6 +166,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 20, "attached_condition": "tbl1.b < 20" @@ -176,6 +182,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 60, "attached_condition": "tbl2.b < 60" @@ -214,6 +221,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 20, "attached_condition": "tbl1.b < 20" @@ -229,6 +237,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 60, "attached_condition": "tbl2.b < 60" @@ -276,6 +285,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t1.a is not null" @@ -295,6 +305,7 @@ ANALYZE "r_rows": 0.2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "using_index": true @@ -337,6 +348,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 50, "attached_condition": "test.t1.a < 5" @@ -376,7 +388,8 @@ ANALYZE "rows": 1000, "r_rows": 1000, "r_filtered": 100, - "r_total_time_ms": "REPLACED" + "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED } } } @@ -405,6 +418,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 50, "index_condition": "t1.pk < 10", @@ -436,6 +450,7 @@ ANALYZE "r_rows": 10, "r_filtered": 50, "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "attached_condition": "t1.pk < 10 and t1.b > 4" } } @@ -481,6 +496,7 @@ ANALYZE "r_rows": 5, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -507,6 +523,7 @@ ANALYZE "r_rows": 203.8, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 98.13542689 } @@ -551,6 +568,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 50, "attached_condition": "tbl1.a < 5" @@ -575,6 +593,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 20, "attached_condition": "tbl2.a in (2,3)" @@ -632,6 +651,7 @@ ANALYZE "r_rows": 256, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -671,6 +691,7 @@ ANALYZE "r_rows": 256, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -724,6 +745,7 @@ ANALYZE "r_rows": 256, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -761,6 +783,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -775,6 +798,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 0, "attached_condition": "(t2.b,t2.b in (subquery#2))" @@ -807,6 +831,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -869,6 +894,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -883,6 +909,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 0, "attached_condition": "t3.f3 in (1,2)" @@ -913,6 +940,7 @@ ANALYZE "r_loops": 0, "rows": 2, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null } @@ -925,6 +953,7 @@ ANALYZE "r_loops": 0, "rows": 2, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null }, @@ -979,6 +1008,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 0, "attached_condition": "t1.a < 0" @@ -1009,6 +1039,7 @@ ANALYZE "r_loops": 0, "rows": 10, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null, "attached_condition": "t2.a < t1.a" @@ -1068,6 +1099,7 @@ ANALYZE "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 10, "r_filtered": 10, "attached_condition": "t11.a < 100" @@ -1083,6 +1115,7 @@ ANALYZE "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 70, "r_filtered": 70, "attached_condition": "t10.a < 700" @@ -1127,6 +1160,7 @@ ANALYZE "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 10, "r_filtered": 10, "attached_condition": "t11.a < 100 and t11.b is not null" @@ -1146,6 +1180,7 @@ ANALYZE "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 70, "r_filtered": 70, "attached_condition": "t10.a < 700" diff --git a/mysql-test/main/analyze_format_json_timings.result b/mysql-test/main/analyze_format_json_timings.result index 50e033b3415..dead44b3fbc 100644 --- a/mysql-test/main/analyze_format_json_timings.result +++ b/mysql-test/main/analyze_format_json_timings.result @@ -54,6 +54,7 @@ X "r_rows": 500, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t1.a < 700 and t1.b is not null" @@ -73,6 +74,7 @@ X "r_rows": 500, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 20, "attached_condition": "t2.a < 100" @@ -145,6 +147,7 @@ X "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t1.a is not null" @@ -164,6 +167,7 @@ X "r_rows": 2000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, diff --git a/mysql-test/main/analyze_stmt_orderby.result b/mysql-test/main/analyze_stmt_orderby.result index 8266b6e58d3..273c3f349bc 100644 --- a/mysql-test/main/analyze_stmt_orderby.result +++ b/mysql-test/main/analyze_stmt_orderby.result @@ -55,7 +55,8 @@ ANALYZE "rows": 10000, "r_rows": 10000, "r_filtered": 100, - "r_total_time_ms": "REPLACED" + "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED } } } @@ -111,6 +112,7 @@ ANALYZE "r_rows": 10, "r_filtered": 100, "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "attached_condition": "t2.a < 10" } } @@ -163,7 +165,8 @@ ANALYZE "rows": 10000, "r_rows": 10000, "r_filtered": 100, - "r_total_time_ms": "REPLACED" + "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED } } } @@ -243,6 +246,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t0.a is not null" @@ -262,6 +266,7 @@ ANALYZE "r_rows": 0.4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -347,6 +352,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t0.a is not null" @@ -368,6 +374,7 @@ ANALYZE "r_rows": 0.4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -417,6 +424,7 @@ ANALYZE "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 50, "attached_condition": "t2.a MOD 2 = 0" @@ -473,6 +481,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -487,6 +496,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -560,6 +570,7 @@ ANALYZE "r_rows": 5, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 80, "attached_condition": "t6.b > 0 and t6.a <= 5" @@ -575,6 +586,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -687,6 +699,7 @@ ANALYZE "r_rows": 20, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "using_index_for_group_by": true diff --git a/mysql-test/main/analyze_stmt_slow_query_log-master.opt b/mysql-test/main/analyze_stmt_slow_query_log-master.opt index 1c80c45b0c1..a0fe99a1676 100644 --- a/mysql-test/main/analyze_stmt_slow_query_log-master.opt +++ b/mysql-test/main/analyze_stmt_slow_query_log-master.opt @@ -1 +1 @@ ---slow-query-log --long-query-time=0.00001 --log-slow-verbosity=query_plan,explain +--slow-query-log --long-query-time=0.00001 --log-slow-verbosity=query_plan,explain,innodb diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index 7fb0d5801c1..22df7cae5e5 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -3881,6 +3881,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t1.a1 is not null" @@ -3929,6 +3930,7 @@ ANALYZE "r_loops": 0, "rows": 1, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null, "using_index": true @@ -3972,6 +3974,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -4181,6 +4184,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -4204,6 +4208,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t1.c is not null" @@ -4311,6 +4316,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/main/ctype_collate_context.result b/mysql-test/main/ctype_collate_context.result index 4ef3d9a6c7b..c924f11d9e2 100644 --- a/mysql-test/main/ctype_collate_context.result +++ b/mysql-test/main/ctype_collate_context.result @@ -3688,3 +3688,31 @@ DROP TABLE results_alter_db; DROP TABLE results_create_table; DROP TABLE results_alter_table; DROP TABLE results_convert_table; +# +# MDEV-30003 Assertion failure upon 2nd execution of SP trying to set collation on non-existing database +# +CREATE PROCEDURE p() ALTER SCHEMA db DEFAULT COLLATE = utf8_bin; +CALL p; +ERROR HY000: Can't create/write to file 'db.opt' (Errcode: 2 "No such file or directory") +CALL p; +ERROR HY000: Can't create/write to file 'db.opt' (Errcode: 2 "No such file or directory") +DROP PROCEDURE p; +CREATE DATABASE db1; +CREATE PROCEDURE p() CREATE DATABASE db1 COLLATE DEFAULT; +CALL p; +ERROR HY000: Can't create database 'db1'; database exists +CALL p; +ERROR HY000: Can't create database 'db1'; database exists +DROP DATABASE db1; +DROP PROCEDURE p; +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p() CREATE TABLE t1 (a INT) COLLATE DEFAULT; +CALL p; +ERROR 42S01: Table 't1' already exists +CALL p; +ERROR 42S01: Table 't1' already exists +DROP TABLE t1; +DROP PROCEDURE p; +# +# End of 10.9 tests +# diff --git a/mysql-test/main/ctype_collate_context.test b/mysql-test/main/ctype_collate_context.test index 6934bf487c3..95a46f2d830 100644 --- a/mysql-test/main/ctype_collate_context.test +++ b/mysql-test/main/ctype_collate_context.test @@ -366,3 +366,38 @@ DROP TABLE results_alter_db; DROP TABLE results_create_table; DROP TABLE results_alter_table; DROP TABLE results_convert_table; + +--echo # +--echo # MDEV-30003 Assertion failure upon 2nd execution of SP trying to set collation on non-existing database +--echo # + +CREATE PROCEDURE p() ALTER SCHEMA db DEFAULT COLLATE = utf8_bin; +--replace_regex /to file '.*db.opt'/to file 'db.opt'/ +--error 1 +CALL p; +--replace_regex /to file '.*db.opt'/to file 'db.opt'/ +--error 1 +CALL p; +DROP PROCEDURE p; + +CREATE DATABASE db1; +CREATE PROCEDURE p() CREATE DATABASE db1 COLLATE DEFAULT; +--error ER_DB_CREATE_EXISTS +CALL p; +--error ER_DB_CREATE_EXISTS +CALL p; +DROP DATABASE db1; +DROP PROCEDURE p; + +CREATE TABLE t1 (a INT); +CREATE PROCEDURE p() CREATE TABLE t1 (a INT) COLLATE DEFAULT; +--error ER_TABLE_EXISTS_ERROR +CALL p; +--error ER_TABLE_EXISTS_ERROR +CALL p; +DROP TABLE t1; +DROP PROCEDURE p; + +--echo # +--echo # End of 10.9 tests +--echo # diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 7c2fdb78234..55b33cdb1b4 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -19686,6 +19686,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 50, "attached_condition": "t1.a = 3" diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 6dab7cb3ad2..31522379151 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -383,6 +383,7 @@ ANALYZE "r_rows": 5, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -401,6 +402,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "trigcond(trigcond(t1.b is not null))" @@ -420,6 +422,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "trigcond(trigcond(t1.b is not null))" @@ -464,6 +467,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -478,6 +482,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, diff --git a/mysql-test/main/except.result b/mysql-test/main/except.result index d92bd0510cc..01d13f8c1e0 100644 --- a/mysql-test/main/except.result +++ b/mysql-test/main/except.result @@ -97,6 +97,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -120,6 +121,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -176,6 +178,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -199,6 +202,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -367,6 +371,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -381,6 +386,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -413,6 +419,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -427,6 +434,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -493,6 +501,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -507,6 +516,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -539,6 +549,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -553,6 +564,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, diff --git a/mysql-test/main/except_all.result b/mysql-test/main/except_all.result index 98acdc79978..26d28088681 100644 --- a/mysql-test/main/except_all.result +++ b/mysql-test/main/except_all.result @@ -157,6 +157,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -180,6 +181,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -241,6 +243,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -264,6 +267,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -494,6 +498,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -508,6 +513,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -540,6 +546,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -554,6 +561,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -619,6 +627,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -633,6 +642,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -665,6 +675,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -679,6 +690,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, diff --git a/mysql-test/main/explain_json.result b/mysql-test/main/explain_json.result index af319c84f3f..8eb7e5d5c3d 100644 --- a/mysql-test/main/explain_json.result +++ b/mysql-test/main/explain_json.result @@ -1168,6 +1168,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "using_index_for_group_by": true @@ -1520,6 +1521,7 @@ ANALYZE "r_loops": 0, "rows": 1, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null, "impossible_on_condition": true @@ -1534,6 +1536,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -1602,6 +1605,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -1620,6 +1624,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "trigcond(t2.pk is null) and trigcond(trigcond(t1.a is not null))", @@ -1694,6 +1699,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t1.a is not null" @@ -1713,6 +1719,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "using_index": true, @@ -1802,6 +1809,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t3.a is not null" @@ -1822,6 +1830,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "index_condition_bka": "t4.b + 1 <= t3.b + 1" diff --git a/mysql-test/main/explain_json_format_partitions.result b/mysql-test/main/explain_json_format_partitions.result index b76fe29625e..d33d744179c 100644 --- a/mysql-test/main/explain_json_format_partitions.result +++ b/mysql-test/main/explain_json_format_partitions.result @@ -47,6 +47,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 30, "attached_condition": "t1.a in (2,3,4)" @@ -74,6 +75,7 @@ ANALYZE "r_rows": 10, "r_filtered": 30, "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "attached_condition": "t1.a in (2,3,4)" } } @@ -97,6 +99,7 @@ ANALYZE "r_rows": 10, "r_filtered": 0, "r_total_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "attached_condition": "t1.a in (20,30,40)" } } diff --git a/mysql-test/main/intersect.result b/mysql-test/main/intersect.result index 015413ecb73..b81ef645dc9 100644 --- a/mysql-test/main/intersect.result +++ b/mysql-test/main/intersect.result @@ -127,6 +127,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -150,6 +151,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -173,6 +175,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -229,6 +232,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -252,6 +256,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -275,6 +280,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -419,6 +425,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -442,6 +449,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -456,6 +464,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -521,6 +530,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -544,6 +554,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -558,6 +569,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, diff --git a/mysql-test/main/intersect_all.result b/mysql-test/main/intersect_all.result index 4e5d9095d27..b1afcee2651 100644 --- a/mysql-test/main/intersect_all.result +++ b/mysql-test/main/intersect_all.result @@ -139,6 +139,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -162,6 +163,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -185,6 +187,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -241,6 +244,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -264,6 +268,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -287,6 +292,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -450,6 +456,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -473,6 +480,7 @@ ANALYZE "r_rows": 5, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -487,6 +495,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -552,6 +561,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -575,6 +585,7 @@ ANALYZE "r_rows": 5, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -589,6 +600,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, diff --git a/mysql-test/main/kill_debug.result b/mysql-test/main/kill_debug.result index 061e7602383..0c910906b92 100644 --- a/mysql-test/main/kill_debug.result +++ b/mysql-test/main/kill_debug.result @@ -234,6 +234,7 @@ connection default; set debug_sync='now WAIT_FOR go0'; set debug_sync='found_killee SIGNAL go1 WAIT_FOR go2'; kill $id; +select variable_value into @threads_cached from information_schema.global_status where variable_name='threads_cached'; set debug_sync='now SIGNAL go3'; drop table t1; set debug_sync='reset'; diff --git a/mysql-test/main/kill_debug.test b/mysql-test/main/kill_debug.test index 32a764004e3..6bade1d8d90 100644 --- a/mysql-test/main/kill_debug.test +++ b/mysql-test/main/kill_debug.test @@ -313,6 +313,12 @@ connection default; set debug_sync='now WAIT_FOR go0'; set debug_sync='found_killee SIGNAL go1 WAIT_FOR go2'; evalp kill $id; +select variable_value into @threads_cached from information_schema.global_status where variable_name='threads_cached'; set debug_sync='now SIGNAL go3'; +if (`select @@thread_handling != 'pool-of-threads'`) { + # cannot check that a thread was added to thread pool on windows, but the test works there w/o the wait + let wait_condition= select variable_value>@threads_cached from information_schema.global_status where variable_name='threads_cached'; + source include/wait_condition.inc; +} drop table t1; set debug_sync='reset'; diff --git a/mysql-test/main/log_slow_innodb.result b/mysql-test/main/log_slow_innodb.result new file mode 100644 index 00000000000..a7c2ac86eed --- /dev/null +++ b/mysql-test/main/log_slow_innodb.result @@ -0,0 +1,78 @@ +CREATE TABLE t1(a INT primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 select seq, seq from seq_1_to_1000; +SET SESSION min_examined_row_limit=0; +SET SESSION long_query_time=0; +SET SESSION log_slow_verbosity='innodb,query_plan'; +[slow_log_start.inc] log_slow_innodb-verbosity_1 +SELECT sum(a+b) FROM t1; +sum(a+b) +1001000 +UPDATE t1 set b=b+1 where a=1 or a=999; +[log_slow_stop.inc] log_slow_innodb-verbosity_1 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Thread_id: .+ Schema: .+ QC_hit: (Yes|No)$ expected_matches: 3 +[log_grep.inc] found expected match count: 3 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Query_time: \d+\.\d+ Lock_time: \d+\.\d+ Rows_sent: \d+ Rows_examined: \d+$ expected_matches: 3 +[log_grep.inc] found expected match count: 3 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Rows_affected: \d+ Bytes_sent: \d+$ expected_matches: 3 +[log_grep.inc] found expected match count: 3 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Full_scan: (Yes|No) Full_join: (Yes|No) Tmp_table: (Yes|No) Tmp_table_on_disk: (Yes|No)$ +[log_grep.inc] lines: 1 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_1 pattern: ^# Tmp_tables: \d+ Tmp_disk_tables: \d+$ +[log_grep.inc] lines: 0 +SET SESSION log_slow_verbosity='innodb,query_plan'; +[slow_log_start.inc] log_slow_innodb-verbosity_2 +SELECT 1; +1 +1 +[log_slow_stop.inc] log_slow_innodb-verbosity_2 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Thread_id: .+ Schema: .+ QC_hit: (Yes|No)$ expected_matches: 2 +[log_grep.inc] found expected match count: 2 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Query_time: \d+\.\d+ Lock_time: \d+\.\d+ Rows_sent: \d+ Rows_examined: \d+$ expected_matches: 2 +[log_grep.inc] found expected match count: 2 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Rows_affected: \d+ Bytes_sent: \d+$ expected_matches: 2 +[log_grep.inc] found expected match count: 2 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Full_scan: (Yes|No) Full_join: (Yes|No) Tmp_table: (Yes|No) Tmp_table_on_disk: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_2 pattern: ^# Tmp_tables: \d+ Tmp_disk_tables: \d+$ +[log_grep.inc] lines: 0 +SET SESSION log_slow_verbosity='query_plan'; +[log_slow_stop.inc] log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Thread_id: .+ Schema: .+ QC_hit: (Yes|No)$ expected_matches: 2 +[log_grep.inc] found expected match count: 2 +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Query_time: \d+\.\d+ Lock_time: \d+\.\d+ Rows_sent: \d+ Rows_examined: \d+$ expected_matches: 2 +[log_grep.inc] found expected match count: 2 +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Rows_affected: \d+ Bytes_sent: \d+$ expected_matches: 2 +[log_grep.inc] found expected match count: 2 +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Full_scan: (Yes|No) Full_join: (Yes|No) Tmp_table: (Yes|No) Tmp_table_on_disk: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Filesort: (Yes|No) Filesort_on_disk: (Yes|No) Merge_passes: \d+\ Priority_queue: (Yes|No)$ +[log_grep.inc] lines: 0 +[log_grep.inc] file: log_slow_innodb-verbosity_3 +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000) pattern: ^# Tmp_tables: \d+ Tmp_disk_tables: \d+$ +[log_grep.inc] lines: 0 +DROP TABLE t1; diff --git a/mysql-test/main/log_slow_innodb.test b/mysql-test/main/log_slow_innodb.test new file mode 100644 index 00000000000..2cd2b654ee5 --- /dev/null +++ b/mysql-test/main/log_slow_innodb.test @@ -0,0 +1,75 @@ +# +# Test the extended slow query log output format for various log_slow_verbosity values. +# Test that InnoDB stats for the extended slow query log are collected. +# +# This test file is based on tests from Percona server +# + +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/log_slow_prepare.inc +# Cannot be used with view protocol as number of temporary tables changes +--source include/no_view_protocol.inc + +--let $log_slow_prefix=log_slow_innodb + +# Force cold buffer pool +#--let $restart_parameters=--innodb_buffer_pool_load_at_startup=OFF +#--source include/restart_mysqld.inc + +CREATE TABLE t1(a INT primary key, b int) ENGINE=InnoDB; +INSERT INTO t1 select seq, seq from seq_1_to_1000; + +SET SESSION min_examined_row_limit=0; +SET SESSION long_query_time=0; + +# +# Test all enabled options with InnoDB-involving query +# +SET SESSION log_slow_verbosity='innodb,query_plan'; +--let log_file=$log_slow_prefix-verbosity_1 + +--source include/log_slow_start.inc +SELECT sum(a+b) FROM t1; +UPDATE t1 set b=b+1 where a=1 or a=999; +--source include/log_slow_stop.inc + +--let log_slow_verbosity_expected_matches= 3 +--let log_slow_verbosity_queryplan_matches= 1 +--let log_slow_verbosity_innodb_expected_matches= 2 +--let log_slow_verbosity_tmptable_expected_matches= 0 +--source include/log_slow_grep.inc + +# +# Test for "No InnoDB statistics available" in output when InnoDB stats are requested +# but the query does not involve InnoDB tables +# + +SET SESSION log_slow_verbosity='innodb,query_plan'; +--let log_file=$log_slow_prefix-verbosity_2 + +--source include/log_slow_start.inc +SELECT 1; +--source include/log_slow_stop.inc + +--let log_slow_verbosity_expected_matches= 2 +--let log_slow_verbosity_queryplan_matches= 1 +--let log_slow_verbosity_innodb_expected_matches= 0 +--source include/log_slow_grep.inc + +# +# Test 'query_plan' +# + +SET SESSION log_slow_verbosity='query_plan'; +let log_file=$log_slow_prefix-verbosity_3 + +--source include/log_slow_start.inc +INSERT INTO t1 VALUE(1000); +--source include/log_slow_stop.inc + +--let log_slow_verbosity_innodb_expected_matches= 1 +--source include/log_slow_grep.inc + +DROP TABLE t1; +--source include/log_slow_cleanup.inc diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 77df8536fa2..de0a8310ec1 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -550,7 +550,7 @@ The following specify which files/extra groups are read (specified before remain (Defaults to on; use --skip-log-slow-slave-statements to disable.) --log-slow-verbosity=name Verbosity level for the slow log. Any combination of: - innodb, query_plan, explain + innodb, query_plan, explain, engine, full --log-tc=name Path to transaction coordinator log (used for transactions that affect more than one storage engine, when binary log is disabled). diff --git a/mysql-test/main/opt_trace.test b/mysql-test/main/opt_trace.test index 5238af5c7a0..298299cb132 100644 --- a/mysql-test/main/opt_trace.test +++ b/mysql-test/main/opt_trace.test @@ -1,5 +1,8 @@ --source include/not_embedded.inc --source include/have_sequence.inc +# View protocol changes some plans +--source include/no_view_protocol.inc + SELECT table_name, column_name FROM information_schema.columns where table_name="OPTIMIZER_TRACE"; set optimizer_trace="enabled=on"; show variables like 'optimizer_trace'; diff --git a/mysql-test/main/order_by.result b/mysql-test/main/order_by.result index 1311f42dac2..90878019618 100644 --- a/mysql-test/main/order_by.result +++ b/mysql-test/main/order_by.result @@ -3424,6 +3424,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -3780,6 +3781,7 @@ ANALYZE "r_rows": 100, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -3946,6 +3948,7 @@ ANALYZE "r_rows": 5, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -3995,6 +3998,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -4050,6 +4054,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -4119,6 +4124,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -4291,6 +4297,7 @@ ANALYZE "r_rows": 50, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -4324,6 +4331,7 @@ ANALYZE "r_rows": 50, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 2, "attached_condition": "t1.b = t2.b" diff --git a/mysql-test/main/order_by_pack_big.result b/mysql-test/main/order_by_pack_big.result index 6b33d7d8202..eda697fdf99 100644 --- a/mysql-test/main/order_by_pack_big.result +++ b/mysql-test/main/order_by_pack_big.result @@ -116,6 +116,7 @@ ANALYZE "r_rows": 10000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -281,6 +282,7 @@ ANALYZE "r_rows": 10000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -442,6 +444,7 @@ ANALYZE "r_rows": 10000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -498,6 +501,7 @@ ANALYZE "r_rows": 10000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/main/partition_charset.result b/mysql-test/main/partition_charset.result index a0019dd8fc3..d9e496c475e 100644 --- a/mysql-test/main/partition_charset.result +++ b/mysql-test/main/partition_charset.result @@ -39,5 +39,17 @@ t1 CREATE TABLE `t1` ( (PARTITION `p0` VALUES LESS THAN ('a') ENGINE = MyISAM) DROP TABLE t1; # +# MDEV-30681 SIGFPE / UBSAN runtime error: division by zero in String::needs_conversion on ALTER +# +CREATE TABLE t1 (a BINARY (10)) PARTITION BY LIST COLUMNS (a) (PARTITION p VALUES IN (0xFF)); +SELECT COLUMN_TYPE, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t1'; +COLUMN_TYPE COLLATION_NAME +binary(10) NULL +ALTER TABLE t1 CHANGE COLUMN a a CHAR(10) BINARY; +SELECT COLUMN_TYPE, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t1'; +COLUMN_TYPE COLLATION_NAME +char(10) latin1_bin +DROP TABLE t1; +# # End of 10.9 tests # diff --git a/mysql-test/main/partition_charset.test b/mysql-test/main/partition_charset.test index b8a17ce4fca..87aa42b4f7c 100644 --- a/mysql-test/main/partition_charset.test +++ b/mysql-test/main/partition_charset.test @@ -43,6 +43,17 @@ ALTER TABLE t1 CHANGE COLUMN a a CHAR BINARY; SHOW CREATE TABLE t1; DROP TABLE t1; +--echo # +--echo # MDEV-30681 SIGFPE / UBSAN runtime error: division by zero in String::needs_conversion on ALTER +--echo # + +CREATE TABLE t1 (a BINARY (10)) PARTITION BY LIST COLUMNS (a) (PARTITION p VALUES IN (0xFF)); +SELECT COLUMN_TYPE, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t1'; +ALTER TABLE t1 CHANGE COLUMN a a CHAR(10) BINARY; +SELECT COLUMN_TYPE, COLLATION_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='t1'; +DROP TABLE t1; + + --echo # --echo # End of 10.9 tests --echo # diff --git a/mysql-test/main/rowid_filter.result b/mysql-test/main/rowid_filter.result index 3ba6eb39720..3f3e1d0f801 100644 --- a/mysql-test/main/rowid_filter.result +++ b/mysql-test/main/rowid_filter.result @@ -147,6 +147,7 @@ ANALYZE "r_rows": 60, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 11.69025803, "r_filtered": 100, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -281,6 +282,7 @@ ANALYZE "r_rows": 510, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 11.69025803, "r_filtered": 11.76470588, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -447,6 +449,7 @@ ANALYZE "r_rows": 71, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "index_condition": "orders.o_totalprice between 200000 and 230000" @@ -484,6 +487,7 @@ ANALYZE "r_rows": 0.154929577, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 1.631973386, "r_filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" @@ -598,6 +602,7 @@ ANALYZE "r_rows": 98, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'" @@ -617,6 +622,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 4.599999905, "r_filtered": 11.2244898, "attached_condition": "orders.o_totalprice between 200000 and 230000" @@ -767,6 +773,7 @@ ANALYZE "r_rows": 60, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 11.69025803, "r_filtered": 100, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -800,6 +807,7 @@ ANALYZE "r_rows": 0.266666667, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 9.266666412, "r_filtered": 100, "attached_condition": "orders.o_totalprice between 180000 and 230000" @@ -927,6 +935,7 @@ ANALYZE "r_rows": 510, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 11.69025803, "r_filtered": 11.76470588, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -947,6 +956,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 9.266666412, "r_filtered": 26.66666667, "attached_condition": "orders.o_totalprice between 180000 and 230000" @@ -1070,6 +1080,7 @@ ANALYZE "r_rows": 71, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "index_condition": "orders.o_totalprice between 200000 and 230000" @@ -1107,6 +1118,7 @@ ANALYZE "r_rows": 0.521126761, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 8.476269722, "r_filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" @@ -1242,6 +1254,7 @@ ANALYZE "r_rows": 71, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "index_condition": "orders.o_totalprice between 200000 and 230000" @@ -1266,6 +1279,7 @@ ANALYZE "r_rows": 6.704225352, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 8.476269722, "r_filtered": 7.773109244, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" @@ -1424,6 +1438,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.566194832, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", @@ -1444,6 +1459,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 7.466666698, "r_filtered": 14.28571429, "attached_condition": "orders.o_totalprice between 200000 and 250000" @@ -1561,6 +1577,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.566194832, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", @@ -1581,6 +1598,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 7.466666698, "r_filtered": 14.28571429, "attached_condition": "orders.o_totalprice between 200000 and 250000" @@ -1698,6 +1716,7 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.200000048, "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -1723,6 +1742,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.047460556, "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -1836,6 +1856,7 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.200000048, "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -1861,6 +1882,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.047460556, "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -1987,6 +2009,7 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": {}, "filtered": "REPLACED", "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -2012,6 +2035,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": {}, "filtered": "REPLACED", "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -2135,6 +2159,7 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": {}, "filtered": "REPLACED", "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -2160,6 +2185,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": {}, "filtered": "REPLACED", "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -2546,6 +2572,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 49.20000076, "r_filtered": 100, "index_condition": "t1.nm like '500%'", @@ -2599,6 +2626,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 49.20000076, "r_filtered": 100, "index_condition": "t1.nm like '500%'", @@ -2691,6 +2719,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 1.149999976, "r_filtered": 100, "attached_condition": "t1.nm like '75%'" @@ -2805,6 +2834,7 @@ ANALYZE "r_rows": 0, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.439999998, "r_filtered": 100, "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" @@ -2869,6 +2899,7 @@ ANALYZE "r_loops": 1, "rows": 853, "r_rows": 0, + "r_engine_stats": REPLACED, "filtered": 0.439999998, "r_filtered": 100, "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" diff --git a/mysql-test/main/rowid_filter_innodb.result b/mysql-test/main/rowid_filter_innodb.result index 9eab412ecbc..860c9b4db44 100644 --- a/mysql-test/main/rowid_filter_innodb.result +++ b/mysql-test/main/rowid_filter_innodb.result @@ -150,6 +150,7 @@ ANALYZE "r_rows": 60, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 10.07493782, "r_filtered": 100, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -284,6 +285,7 @@ ANALYZE "r_rows": 510, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 10.07493782, "r_filtered": 11.76470588, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -448,6 +450,7 @@ ANALYZE "r_rows": 98, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'", @@ -468,6 +471,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 4.733333111, "r_filtered": 11.2244898, "attached_condition": "orders.o_totalprice between 200000 and 230000" @@ -583,6 +587,7 @@ ANALYZE "r_rows": 98, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-01-31'", @@ -603,6 +608,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 4.733333111, "r_filtered": 11.2244898, "attached_condition": "orders.o_totalprice between 200000 and 230000" @@ -745,6 +751,7 @@ ANALYZE "r_rows": 60, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 10.07493782, "r_filtered": 100, "index_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'", @@ -765,6 +772,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 9.600000381, "r_filtered": 26.66666667, "attached_condition": "orders.o_totalprice between 180000 and 230000" @@ -886,6 +894,7 @@ ANALYZE "r_rows": 144, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "orders.o_totalprice between 180000 and 230000", @@ -912,6 +921,7 @@ ANALYZE "r_rows": 6.625, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.855656624, "r_filtered": 1.677148847, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30' and lineitem.l_quantity > 45" @@ -1028,6 +1038,7 @@ ANALYZE "r_rows": 71, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "orders.o_totalprice between 200000 and 230000", @@ -1053,6 +1064,7 @@ ANALYZE "r_rows": 6.704225352, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 8.492922783, "r_filtered": 7.773109244, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" @@ -1189,6 +1201,7 @@ ANALYZE "r_rows": 71, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "orders.o_totalprice between 200000 and 230000", @@ -1214,6 +1227,7 @@ ANALYZE "r_rows": 6.704225352, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 8.492922783, "r_filtered": 7.773109244, "attached_condition": "lineitem.l_shipDATE between '1997-01-01' and '1997-06-30'" @@ -1372,6 +1386,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.566194832, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", @@ -1392,6 +1407,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 5.666666508, "r_filtered": 14.28571429, "attached_condition": "orders.o_totalprice between 200000 and 250000" @@ -1509,6 +1525,7 @@ ANALYZE "r_rows": 18, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.566194832, "r_filtered": 38.88888889, "index_condition": "lineitem.l_receiptDATE between '1996-10-05' and '1996-10-10'", @@ -1529,6 +1546,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 5.666666508, "r_filtered": 14.28571429, "attached_condition": "orders.o_totalprice between 200000 and 250000" @@ -1646,6 +1664,7 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.333333254, "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -1671,6 +1690,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.047460556, "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -1784,6 +1804,7 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.333333254, "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -1809,6 +1830,7 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 3.047460556, "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -1935,6 +1957,9 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": 84 + }, "filtered": "REPLACED", "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -1960,6 +1985,9 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": 3 + }, "filtered": "REPLACED", "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -2083,6 +2111,9 @@ ANALYZE "r_rows": 41, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": 84 + }, "filtered": "REPLACED", "r_filtered": 2.43902439, "index_condition": "orders.o_totaldiscount between 18000 and 20000", @@ -2108,6 +2139,9 @@ ANALYZE "r_rows": 6, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": { + "pages_accessed": 3 + }, "filtered": "REPLACED", "r_filtered": 66.66666667, "attached_condition": "lineitem.l_shipDATE between '1996-10-01' and '1996-12-01'" @@ -2494,6 +2528,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 49.20000076, "r_filtered": 100, "index_condition": "t1.nm like '500%'", @@ -2547,6 +2582,7 @@ ANALYZE "r_rows": 1, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 49.20000076, "r_filtered": 100, "index_condition": "t1.nm like '500%'", @@ -2639,6 +2675,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 1.149999976, "r_filtered": 100, "attached_condition": "t1.nm like '75%'" @@ -2753,6 +2790,7 @@ ANALYZE "r_rows": 0, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 0.439999998, "r_filtered": 100, "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" @@ -2817,6 +2855,7 @@ ANALYZE "r_loops": 1, "rows": 853, "r_rows": 0, + "r_engine_stats": REPLACED, "filtered": 0.439999998, "r_filtered": 100, "attached_condition": "t1.nm like '3400%' or t1.nm like '3402%' or t1.nm like '3403%' or t1.nm like '3404%' or t1.nm like '3405%' or t1.nm like '3406%' or t1.nm like '3407%' or t1.nm like '3409%' or t1.nm like '3411%' or t1.nm like '3412%' or t1.nm like '3413%' or t1.nm like '3414%' or t1.nm like '3415%' or t1.nm like '3416%' or t1.nm like '3417%' or t1.nm like '3418%' or t1.nm like '3419%' or t1.nm like '3421%' or t1.nm like '3422%' or t1.nm like '3423%' or t1.nm like '3424%' or t1.nm like '3425%' or t1.nm like '3426%' or t1.nm like '3427%' or t1.nm like '3428%' or t1.nm like '3429%' or t1.nm like '3430%' or t1.nm like '3431%' or t1.nm like '3432%' or t1.nm like '3433%' or t1.nm like '3434%' or t1.nm like '3435%' or t1.nm like '3436%' or t1.nm like '3437%' or t1.nm like '3439%' or t1.nm like '3440%' or t1.nm like '3441%' or t1.nm like '3442%' or t1.nm like '3443%' or t1.nm like '3444%' or t1.nm like '3445%' or t1.nm like '3446%' or t1.nm like '3447%' or t1.nm like '3448%'" @@ -3922,6 +3961,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100, "attached_condition": "t.tp = 121 and t.rid = 'B5FCC8C7111E4E3CBC21AAF5012F59C2'", @@ -3943,6 +3983,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 }, @@ -3973,6 +4014,7 @@ ANALYZE "r_rows": 80, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 14.46428585, "r_filtered": 100 }, diff --git a/mysql-test/main/show_analyze.result b/mysql-test/main/show_analyze.result index 5595fadd60b..0e96c5887ea 100644 --- a/mysql-test/main/show_analyze.result +++ b/mysql-test/main/show_analyze.result @@ -426,6 +426,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/main/show_analyze_json.result b/mysql-test/main/show_analyze_json.result index 8506c4b9402..f24d32f15da 100644 --- a/mysql-test/main/show_analyze_json.result +++ b/mysql-test/main/show_analyze_json.result @@ -124,6 +124,7 @@ SHOW ANALYZE "r_rows": 1000, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 99.90000153, "r_filtered": 100, "attached_condition": "t1.a < 10" @@ -311,6 +312,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 60, "attached_condition": "a.a <= 5" @@ -331,6 +333,7 @@ SHOW ANALYZE "r_loops": 0, "rows": 10, "r_rows": null, + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": null, "attached_condition": "b.a >= 9" @@ -383,6 +386,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 60, "attached_condition": "a.a <= 5" @@ -407,6 +411,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 10, "attached_condition": "b.a >= 9" @@ -513,6 +518,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 20, "attached_condition": "a.a < 2" @@ -535,6 +541,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 30, "attached_condition": "b.a > 6" @@ -705,6 +712,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 20, "attached_condition": "a.a < 2" @@ -730,6 +738,7 @@ SHOW ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 95, "attached_condition": "b.a + a.a < 10" diff --git a/mysql-test/main/sp-memory-leak.result b/mysql-test/main/sp-memory-leak.result new file mode 100644 index 00000000000..37a0f119341 --- /dev/null +++ b/mysql-test/main/sp-memory-leak.result @@ -0,0 +1,42 @@ +# +# MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks +# +BEGIN NOT ATOMIC +IF SCALAR() expected_THEN_here; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_THEN_here; +END' at line 2 +BEGIN NOT ATOMIC +WHILE SCALAR() expected_DO_here; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_DO_here; +END' at line 2 +BEGIN NOT ATOMIC +REPEAT SELECT 1; UNTIL SCALAR() expected_END_here; +END +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'expected_END_here; +END' at line 2 +# +# MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error +# +BEGIN NOT ATOMIC +DECLARE cur CURSOR (a INT) FOR SELECT a+1; +OPEN cur(sp_followed_by_syntax_error(); +CLOSE cur; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '; +CLOSE cur; +END' at line 3 +BEGIN NOT ATOMIC +DECLARE cur CURSOR (a INT) FOR SELECT a+1; +OPEN cur(1,sp_followed_by_syntax_error(); +CLOSE cur; +END; +$$ +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '; +CLOSE cur; +END' at line 3 diff --git a/mysql-test/main/sp-memory-leak.test b/mysql-test/main/sp-memory-leak.test new file mode 100644 index 00000000000..0035044209a --- /dev/null +++ b/mysql-test/main/sp-memory-leak.test @@ -0,0 +1,54 @@ +--echo # +--echo # MDEV-30680 Warning: Memory not freed: 280 on mangled query, LeakSanitizer: detected memory leaks +--echo # + +DELIMITER $$; +--error ER_PARSE_ERROR +BEGIN NOT ATOMIC + IF SCALAR() expected_THEN_here; +END +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_PARSE_ERROR +BEGIN NOT ATOMIC + WHILE SCALAR() expected_DO_here; +END +$$ +DELIMITER ;$$ + + +DELIMITER $$; +--error ER_PARSE_ERROR +BEGIN NOT ATOMIC + REPEAT SELECT 1; UNTIL SCALAR() expected_END_here; +END +$$ +DELIMITER ;$$ + + +--echo # +--echo # MDEV-31578 DECLARE CURSOR: "Memory not freed: 280 bytes lost" on syntax error +--echo # + +DELIMITER $$; +--error ER_PARSE_ERROR +BEGIN NOT ATOMIC + DECLARE cur CURSOR (a INT) FOR SELECT a+1; + OPEN cur(sp_followed_by_syntax_error(); + CLOSE cur; +END; +$$ +DELIMITER ;$$ + +DELIMITER $$; +--error ER_PARSE_ERROR +BEGIN NOT ATOMIC + DECLARE cur CURSOR (a INT) FOR SELECT a+1; + OPEN cur(1,sp_followed_by_syntax_error(); + CLOSE cur; +END; +$$ +DELIMITER ;$$ diff --git a/mysql-test/main/subselect4.result b/mysql-test/main/subselect4.result index ecbb9a42112..78045e45373 100644 --- a/mysql-test/main/subselect4.result +++ b/mysql-test/main/subselect4.result @@ -2936,6 +2936,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -2960,6 +2961,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 50, "attached_condition": "((t1.b,(subquery#3) >= 4))" @@ -2982,6 +2984,7 @@ ANALYZE "r_rows": 2, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/main/subselect_cache.result b/mysql-test/main/subselect_cache.result index 5c2fd3e66fc..bbfc2281a13 100644 --- a/mysql-test/main/subselect_cache.result +++ b/mysql-test/main/subselect_cache.result @@ -61,6 +61,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -85,6 +86,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 18.75, "attached_condition": "t1.b = t2.c" @@ -118,6 +120,7 @@ ANALYZE "r_rows": 10, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } @@ -150,6 +153,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 18.75, "attached_condition": "t1.b = t2.c" @@ -190,6 +194,7 @@ ANALYZE "r_rows": 4, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 18.75, "attached_condition": "t1.b = t2.c" @@ -1704,7 +1709,7 @@ Subquery_cache_miss 18 show status like '%Handler_read%'; Variable_name Value Handler_read_first 0 -Handler_read_key 32 +Handler_read_key 29 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 @@ -1769,7 +1774,7 @@ Subquery_cache_miss 10 show status like '%Handler_read%'; Variable_name Value Handler_read_first 0 -Handler_read_key 13 +Handler_read_key 12 Handler_read_last 0 Handler_read_next 0 Handler_read_prev 0 diff --git a/mysql-test/main/type_json.result b/mysql-test/main/type_json.result index 681bd42c4e3..431a7f138f6 100644 --- a/mysql-test/main/type_json.result +++ b/mysql-test/main/type_json.result @@ -159,5 +159,23 @@ def j 250 (format=json) 9437283 16 Y 0 39 33 j {"a": {"b":"c"}} # +# MDEV-26506 Over-quoted JSON when combining JSON_ARRAYAGG with JSON_OBJECT +# +# maintain JSON property through internal temporary tables +create table t1 (a varchar(30)); +insert into t1 values ('root'); +select json_object('attr2',o) from (select a, json_arrayagg(json_object('attr1', a)) as o from t1) u; +json_object('attr2',o) +{"attr2": [{"attr1": "root"}]} +drop table t1; +create view v1 as select json_object(_latin1 'a', _latin1'b') as v1_json; +select v1_json from v1; +v1_json +{"a": "b"} +select json_arrayagg(v1_json) from v1; +json_arrayagg(v1_json) +[{"a": "b"}] +drop view v1; +# # End of 10.5 tests # diff --git a/mysql-test/main/type_json.test b/mysql-test/main/type_json.test index 38754ba6e1e..8effe78f803 100644 --- a/mysql-test/main/type_json.test +++ b/mysql-test/main/type_json.test @@ -121,6 +121,20 @@ SELECT json_object('a', (SELECT json_objectagg(b, c) FROM (SELECT 'b','c') d)) A --disable_ps_protocol --enable_view_protocol +--echo # +--echo # MDEV-26506 Over-quoted JSON when combining JSON_ARRAYAGG with JSON_OBJECT +--echo # +--echo # maintain JSON property through internal temporary tables +create table t1 (a varchar(30)); +insert into t1 values ('root'); +select json_object('attr2',o) from (select a, json_arrayagg(json_object('attr1', a)) as o from t1) u; +drop table t1; + +create view v1 as select json_object(_latin1 'a', _latin1'b') as v1_json; +select v1_json from v1; +select json_arrayagg(v1_json) from v1; +drop view v1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 21f2dbccd33..a1f20a62327 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3854,6 +3854,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/suite/compat/oracle/r/func_to_char.result b/mysql-test/suite/compat/oracle/r/func_to_char.result index a4978b07579..1f95acece5e 100644 --- a/mysql-test/suite/compat/oracle/r/func_to_char.result +++ b/mysql-test/suite/compat/oracle/r/func_to_char.result @@ -439,3 +439,10 @@ NULL 2021-01-24 drop table t1,t2; set @local.sql_mode=@sql_mode; +# +# MDEV-29152: Assertion failed ... upon TO_CHAR with wrong argument +# +SELECT TO_CHAR((VALUES('2022-12-12','2020-10-10'))); +ERROR HY000: Illegal parameter data type row for operation 'to_char' +SELECT TO_CHAR((STR_TO_DATE('2023-01-01', '%d-%m-%Y'), 'YYYY-MM-DD') ); +ERROR HY000: Illegal parameter data type row for operation 'to_char' diff --git a/mysql-test/suite/compat/oracle/t/func_to_char.test b/mysql-test/suite/compat/oracle/t/func_to_char.test index 9910fe60a84..7a40321538d 100644 --- a/mysql-test/suite/compat/oracle/t/func_to_char.test +++ b/mysql-test/suite/compat/oracle/t/func_to_char.test @@ -224,3 +224,13 @@ select * from t2; drop table t1,t2; set @local.sql_mode=@sql_mode; +--echo # +--echo # MDEV-29152: Assertion failed ... upon TO_CHAR with wrong argument +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT TO_CHAR((VALUES('2022-12-12','2020-10-10'))); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT TO_CHAR((STR_TO_DATE('2023-01-01', '%d-%m-%Y'), 'YYYY-MM-DD') ); + diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index 46cfb3b58ec..d0dadb6dd7c 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -3860,6 +3860,7 @@ ANALYZE "r_rows": 3, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/suite/federated/federatedx_create_handlers.result b/mysql-test/suite/federated/federatedx_create_handlers.result index f2e2247bae1..e740170640d 100644 --- a/mysql-test/suite/federated/federatedx_create_handlers.result +++ b/mysql-test/suite/federated/federatedx_create_handlers.result @@ -243,6 +243,7 @@ ANALYZE "r_rows": 7, "r_table_time_ms": "REPLACED", "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, "filtered": 100, "r_filtered": 100 } diff --git a/mysql-test/suite/innodb/r/innodb_row_lock_time_ms.result b/mysql-test/suite/innodb/r/innodb_row_lock_time_ms.result new file mode 100644 index 00000000000..984d789e058 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_row_lock_time_ms.result @@ -0,0 +1,40 @@ +CREATE TABLE `t`(`id` INT, PRIMARY KEY(`id`)) ENGINE=InnoDB STATS_PERSISTENT=0; +INSERT INTO t VALUES (1); +SET GLOBAL innodb_monitor_reset = "module_innodb"; +BEGIN; +SELECT * FROM t FOR UPDATE; +id +1 +connect con1,localhost,root,,; +SET innodb_lock_wait_timeout = 1; +SELECT * FROM t FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +disconnect con1; +connection default; +COMMIT; +SELECT variable_value > 100 FROM information_schema.global_status +WHERE LOWER(variable_name) = 'innodb_row_lock_time'; +variable_value > 100 +1 +SELECT variable_value > 100 FROM information_schema.global_status +WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'; +variable_value > 100 +1 +SELECT variable_value > 100 FROM information_schema.global_status +WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'; +variable_value > 100 +1 +SELECT count_reset > 100 FROM INFORMATION_SCHEMA.INNODB_METRICS +WHERE NAME="lock_row_lock_time"; +count_reset > 100 +1 +SELECT count_reset > 100 FROM INFORMATION_SCHEMA.INNODB_METRICS +WHERE NAME="lock_row_lock_time_max"; +count_reset > 100 +1 +SELECT count_reset > 100 FROM INFORMATION_SCHEMA.INNODB_METRICS +WHERE NAME="lock_row_lock_time_avg"; +count_reset > 100 +1 +DROP TABLE t; +SET GLOBAL innodb_monitor_reset=default; diff --git a/mysql-test/suite/innodb/t/innodb_row_lock_time_ms.test b/mysql-test/suite/innodb/t/innodb_row_lock_time_ms.test new file mode 100644 index 00000000000..4a100821819 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_row_lock_time_ms.test @@ -0,0 +1,42 @@ +--source include/have_innodb.inc +--source include/count_sessions.inc + +CREATE TABLE `t`(`id` INT, PRIMARY KEY(`id`)) ENGINE=InnoDB STATS_PERSISTENT=0; + +INSERT INTO t VALUES (1); + +SET GLOBAL innodb_monitor_reset = "module_innodb"; + +BEGIN; +SELECT * FROM t FOR UPDATE; + +--connect(con1,localhost,root,,) +SET innodb_lock_wait_timeout = 1; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t FOR UPDATE; +--disconnect con1 + +--connection default +COMMIT; + +SELECT variable_value > 100 FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_row_lock_time'; +SELECT variable_value > 100 FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_row_lock_time_max'; +SELECT variable_value > 100 FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_row_lock_time_avg'; + +SELECT count_reset > 100 FROM INFORMATION_SCHEMA.INNODB_METRICS + WHERE NAME="lock_row_lock_time"; +SELECT count_reset > 100 FROM INFORMATION_SCHEMA.INNODB_METRICS + WHERE NAME="lock_row_lock_time_max"; +SELECT count_reset > 100 FROM INFORMATION_SCHEMA.INNODB_METRICS + WHERE NAME="lock_row_lock_time_avg"; + +DROP TABLE t; + +--disable_warnings +SET GLOBAL innodb_monitor_reset=default; +--enable_warnings + +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/log_corruption.test b/mysql-test/suite/innodb/t/log_corruption.test index 6f7080f5b50..b4466c5efde 100644 --- a/mysql-test/suite/innodb/t/log_corruption.test +++ b/mysql-test/suite/innodb/t/log_corruption.test @@ -591,11 +591,11 @@ print OUT pack("x[470]N", 0x677700cf); # invalid (all-zero) checkpoint page 1 and an empty log page print OUT chr(0) x 1024; # valid checkpoint block 2 -print OUT pack("x[12]NNNx[264]", 0x12860c, 0, 0x80c); +print OUT pack("x[12]NNNx[264]", 0x12860c, 0, 0x120c); # pointer to the FILE_CHECKPOINT record, and checkpoint page checksum -print OUT pack("H*x[204]NNN", "590DBAACFE922582", 0x128612, 0, 0x101741b); +print OUT pack("H*x[204]NNN", "590DBAACFE922582", 0x128612, 0, 0x3b4ce62d); # log page -print OUT pack("NnnNx[496]N", 0x80000944, 12, 12, 1, 0x46c8a2a2); +print OUT pack("x[2560]NnnNx[496]N", 0x80000944, 12, 12, 1, 0x46c8a2a2); close OUT or die; EOF diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index 757c0cba4e5..74d25975022 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -1769,7 +1769,7 @@ VARIABLE_COMMENT Verbosity level for the slow log NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST innodb,query_plan,explain +ENUM_VALUE_LIST innodb,query_plan,explain,engine,full READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME LOG_WARNINGS diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 7a90160e4ba..d22a191209e 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -1919,7 +1919,7 @@ VARIABLE_COMMENT Verbosity level for the slow log NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST innodb,query_plan,explain +ENUM_VALUE_LIST innodb,query_plan,explain,engine,full READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME LOG_WARNINGS diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index fd8a99c2196..2e8decd7d06 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -23,7 +23,7 @@ #include #include -pthread_key(struct st_my_thread_var*, THR_KEY_mysys); +pthread_key(struct st_my_thread_var*, THR_KEY_mysys=-1); mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_lock, THR_LOCK_myisam, THR_LOCK_heap, THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, diff --git a/plugin/type_inet/item_inetfunc.cc b/plugin/type_inet/item_inetfunc.cc index 514a3760cd5..1551b53b695 100644 --- a/plugin/type_inet/item_inetfunc.cc +++ b/plugin/type_inet/item_inetfunc.cc @@ -151,14 +151,14 @@ String *Item_func_inet6_aton::val_str(String *buffer) if ((null_value= tmp.is_null())) return NULL; - Inet4Bundle::Fbt_null ipv4(*tmp.string()); + Type_handler_inet4::Fbt_null ipv4(*tmp.string()); if (!ipv4.is_null()) { ipv4.to_binary(buffer); return buffer; } - Inet6Bundle::Fbt_null ipv6(*tmp.string()); + Type_handler_inet6::Fbt_null ipv6(*tmp.string()); if (!ipv6.is_null()) { ipv6.to_binary(buffer); @@ -190,14 +190,14 @@ String *Item_func_inet6_ntoa::val_str_ascii(String *buffer) if ((null_value= tmp.is_null())) return NULL; - Inet4Bundle::Fbt_null ipv4(static_cast(*tmp.string())); + Type_handler_inet4::Fbt_null ipv4(static_cast(*tmp.string())); if (!ipv4.is_null()) { ipv4.to_string(buffer); return buffer; } - Inet6Bundle::Fbt_null ipv6(static_cast(*tmp.string())); + Type_handler_inet6::Fbt_null ipv6(static_cast(*tmp.string())); if (!ipv6.is_null()) { ipv6.to_string(buffer); @@ -218,13 +218,13 @@ longlong Item_func_is_ipv4::val_int() { DBUG_ASSERT(fixed()); String_ptr_and_buffer tmp(args[0]); - return !tmp.is_null() && !Inet4Bundle::Fbt_null(*tmp.string()).is_null(); + return !tmp.is_null() && !Type_handler_inet4::Fbt_null(*tmp.string()).is_null(); } -class IP6 : public Inet6Bundle::Fbt_null +class IP6 : public Type_handler_inet6::Fbt_null { public: - IP6(Item* arg) : Inet6Bundle::Fbt_null(arg) {} + IP6(Item* arg) : Type_handler_inet6::Fbt_null(arg) {} bool is_v4compat() const { static_assert(sizeof(in6_addr) == IN6_ADDR_SIZE, "unexpected in6_addr size"); @@ -246,7 +246,7 @@ longlong Item_func_is_ipv6::val_int() { DBUG_ASSERT(fixed()); String_ptr_and_buffer tmp(args[0]); - return !tmp.is_null() && !Inet6Bundle::Fbt_null(*tmp.string()).is_null(); + return !tmp.is_null() && !Type_handler_inet6::Fbt_null(*tmp.string()).is_null(); } /** diff --git a/plugin/type_inet/plugin.cc b/plugin/type_inet/plugin.cc index e2854314ac0..7a69d23b455 100644 --- a/plugin/type_inet/plugin.cc +++ b/plugin/type_inet/plugin.cc @@ -24,14 +24,14 @@ static struct st_mariadb_data_type plugin_descriptor_type_inet4= { MariaDB_DATA_TYPE_INTERFACE_VERSION, - Inet4Bundle::type_handler_fbt() + Type_handler_inet4::singleton() }; static struct st_mariadb_data_type plugin_descriptor_type_inet6= { MariaDB_DATA_TYPE_INTERFACE_VERSION, - Inet6Bundle::type_handler_fbt() + Type_handler_inet6::singleton() }; diff --git a/plugin/type_inet/sql_type_inet.cc b/plugin/type_inet/sql_type_inet.cc index 3d499620780..03c8d8133e5 100644 --- a/plugin/type_inet/sql_type_inet.cc +++ b/plugin/type_inet/sql_type_inet.cc @@ -259,9 +259,9 @@ bool Inet6::ascii_to_fbt(const char *str, size_t str_length) return true; } - Inet4Bundle::Fbt_null tmp(group_start_ptr, - (size_t) (str_end - group_start_ptr), - &my_charset_latin1); + Type_handler_inet4::Fbt_null tmp(group_start_ptr, + (size_t) (str_end - group_start_ptr), + &my_charset_latin1); if (tmp.is_null()) { DBUG_PRINT("error", ("ascii_to_ipv6(%.*s): invalid IPv6 address: " diff --git a/plugin/type_inet/sql_type_inet.h b/plugin/type_inet/sql_type_inet.h index 3ea06f6600c..bb14dab1dc2 100644 --- a/plugin/type_inet/sql_type_inet.h +++ b/plugin/type_inet/sql_type_inet.h @@ -44,7 +44,7 @@ public: #include "sql_type_fixedbin.h" -typedef FixedBinTypeBundle Inet6Bundle; +typedef Type_handler_fbt Type_handler_inet6; /***********************************************************************/ @@ -57,7 +57,7 @@ public: static const Name &default_value(); }; -typedef FixedBinTypeBundle Inet4Bundle; +typedef Type_handler_fbt Type_handler_inet4; #endif /* SQL_TYPE_INET_H */ diff --git a/plugin/type_mysql_json/type.cc b/plugin/type_mysql_json/type.cc index b897f64a3b2..a39c4ad2006 100644 --- a/plugin/type_mysql_json/type.cc +++ b/plugin/type_mysql_json/type.cc @@ -188,13 +188,6 @@ public: { return NULL; } - - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - if (type_handler_mysql_json.name().eq(name)) - return &type_handler_mysql_json; - return NULL; - } }; const Type_collection *Type_handler_mysql_json::type_collection() const diff --git a/plugin/type_mysql_timestamp/plugin.cc b/plugin/type_mysql_timestamp/plugin.cc index fd6ad896aa7..a524c5c0124 100644 --- a/plugin/type_mysql_timestamp/plugin.cc +++ b/plugin/type_mysql_timestamp/plugin.cc @@ -26,11 +26,6 @@ protected: const Type_handler *aggregate_common(const Type_handler *h1, const Type_handler *h2) const; public: - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - return NULL; - } - const Type_handler *aggregate_for_result(const Type_handler *h1, const Type_handler *h2) const override diff --git a/plugin/type_test/plugin.cc b/plugin/type_test/plugin.cc index 4c26c35f976..a649ebb3e41 100644 --- a/plugin/type_test/plugin.cc +++ b/plugin/type_test/plugin.cc @@ -26,10 +26,6 @@ protected: const Type_handler *aggregate_common(const Type_handler *h1, const Type_handler *h2) const; public: - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - return NULL; - } const Type_handler *aggregate_for_result(const Type_handler *h1, const Type_handler *h2) const override; diff --git a/plugin/type_uuid/CMakeLists.txt b/plugin/type_uuid/CMakeLists.txt index 9a379abef04..6b0d6a458bf 100644 --- a/plugin/type_uuid/CMakeLists.txt +++ b/plugin/type_uuid/CMakeLists.txt @@ -14,5 +14,5 @@ # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA MYSQL_ADD_PLUGIN(type_uuid - plugin.cc sql_type_uuid.cc item_uuidfunc.cc + plugin.cc item_uuidfunc.cc MANDATORY RECOMPILE_FOR_EMBEDDED) diff --git a/plugin/type_uuid/item_uuidfunc.cc b/plugin/type_uuid/item_uuidfunc.cc index 725b696f905..3f2b7434f73 100644 --- a/plugin/type_uuid/item_uuidfunc.cc +++ b/plugin/type_uuid/item_uuidfunc.cc @@ -33,7 +33,7 @@ String *Item_func_sys_guid::val_str(String *str) const Type_handler *Item_func_uuid::type_handler() const { - return UUIDBundle::type_handler_fbt(); + return Type_handler_uuid_new::singleton(); } bool Item_func_uuid::val_native(THD *, Native *to) diff --git a/plugin/type_uuid/mysql-test/type_uuid/order.result b/plugin/type_uuid/mysql-test/type_uuid/order.result new file mode 100644 index 00000000000..2f6ae3ed47c --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/order.result @@ -0,0 +1,768 @@ +create table t1 (a uuid, b int not null, index (a)); +insert t1 select sformat('11223344-5566-{:x}777-{}888-99aabbccddee', seq div 4, elt(1+(seq % 4),0,8,'c','e')),seq from seq_0_to_63; +Warnings: +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 33 +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 37 +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 41 +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 45 +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 49 +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 53 +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 57 +Warning 1292 Incorrect uuid value: '11223344-5566-f777-0888-99aabbccddee' for column `test`.`t1`.`a` at row 61 +select * from t1; +a b +11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 +NULL 32 +11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 +NULL 36 +11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 +NULL 40 +11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 +NULL 44 +11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 +NULL 48 +11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 +NULL 52 +11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 +NULL 56 +11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 +NULL 60 +11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 +select * from t1 order by a; +a b +NULL 40 +NULL 32 +NULL 36 +NULL 44 +NULL 48 +NULL 52 +NULL 56 +NULL 60 +11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 +11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-e888-99aabbccddee 23 +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +# now let's use the table as above, but created in 10.11.4 +select * from t2; +a b +11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-0888-99aabbccddee 32 +11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-0888-99aabbccddee 36 +11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-0888-99aabbccddee 40 +11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-0888-99aabbccddee 44 +11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-0888-99aabbccddee 48 +11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-0888-99aabbccddee 52 +11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-0888-99aabbccddee 56 +11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-0888-99aabbccddee 60 +11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 +select * from t2 order by a; +a b +11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-8777-0888-99aabbccddee 32 +11223344-5566-9777-0888-99aabbccddee 36 +11223344-5566-a777-0888-99aabbccddee 40 +11223344-5566-b777-0888-99aabbccddee 44 +11223344-5566-c777-0888-99aabbccddee 48 +11223344-5566-d777-0888-99aabbccddee 52 +11223344-5566-e777-0888-99aabbccddee 56 +11223344-5566-f777-0888-99aabbccddee 60 +11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-e888-99aabbccddee 63 +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` uuid DEFAULT NULL, + `b` int(11) NOT NULL, + KEY `a` (`a`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +explain select * from t1 left join t2 on (t1.a=t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 64 +1 SIMPLE t2 ref a a 17 test.t1.a 1 Using where +select * from t1 left join t2 on (t1.a=t2.a); +a b a b +11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +NULL 32 NULL NULL +NULL 36 NULL NULL +NULL 40 NULL NULL +NULL 44 NULL NULL +NULL 48 NULL NULL +NULL 52 NULL NULL +NULL 56 NULL NULL +NULL 60 NULL NULL +explain select * from t1 left join t2 on (t1.a<=>t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 64 +1 SIMPLE t2 ref a a 17 test.t1.a 1 Using where +select * from t1 left join t2 on (t1.a<=>t2.a); +a b a b +11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +NULL 32 NULL NULL +NULL 36 NULL NULL +NULL 40 NULL NULL +NULL 44 NULL NULL +NULL 48 NULL NULL +NULL 52 NULL NULL +NULL 56 NULL NULL +NULL 60 NULL NULL +explain select * from t2 left join t1 on (t1.a=t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 64 +1 SIMPLE t1 ref a a 17 test.t2.a 1 Using where +select * from t2 left join t1 on (t1.a=t2.a); +a b a b +11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-0888-99aabbccddee 32 NULL NULL +11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-0888-99aabbccddee 36 NULL NULL +11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-0888-99aabbccddee 40 NULL NULL +11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-0888-99aabbccddee 44 NULL NULL +11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-0888-99aabbccddee 48 NULL NULL +11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-0888-99aabbccddee 52 NULL NULL +11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-0888-99aabbccddee 56 NULL NULL +11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-0888-99aabbccddee 60 NULL NULL +11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +explain select * from t2 left join t1 on (t1.a<=>t2.a); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 64 +1 SIMPLE t1 ref a a 17 test.t2.a 1 Using where +select * from t2 left join t1 on (t1.a<=>t2.a); +a b a b +11223344-5566-0777-0888-99aabbccddee 0 11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-0888-99aabbccddee 32 NULL 32 +11223344-5566-8777-0888-99aabbccddee 32 NULL 36 +11223344-5566-8777-0888-99aabbccddee 32 NULL 40 +11223344-5566-8777-0888-99aabbccddee 32 NULL 44 +11223344-5566-8777-0888-99aabbccddee 32 NULL 48 +11223344-5566-8777-0888-99aabbccddee 32 NULL 52 +11223344-5566-8777-0888-99aabbccddee 32 NULL 56 +11223344-5566-8777-0888-99aabbccddee 32 NULL 60 +11223344-5566-8777-8888-99aabbccddee 33 11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-0888-99aabbccddee 36 NULL 32 +11223344-5566-9777-0888-99aabbccddee 36 NULL 36 +11223344-5566-9777-0888-99aabbccddee 36 NULL 40 +11223344-5566-9777-0888-99aabbccddee 36 NULL 44 +11223344-5566-9777-0888-99aabbccddee 36 NULL 48 +11223344-5566-9777-0888-99aabbccddee 36 NULL 52 +11223344-5566-9777-0888-99aabbccddee 36 NULL 56 +11223344-5566-9777-0888-99aabbccddee 36 NULL 60 +11223344-5566-9777-8888-99aabbccddee 37 11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-0888-99aabbccddee 40 NULL 32 +11223344-5566-a777-0888-99aabbccddee 40 NULL 36 +11223344-5566-a777-0888-99aabbccddee 40 NULL 40 +11223344-5566-a777-0888-99aabbccddee 40 NULL 44 +11223344-5566-a777-0888-99aabbccddee 40 NULL 48 +11223344-5566-a777-0888-99aabbccddee 40 NULL 52 +11223344-5566-a777-0888-99aabbccddee 40 NULL 56 +11223344-5566-a777-0888-99aabbccddee 40 NULL 60 +11223344-5566-a777-8888-99aabbccddee 41 11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-0888-99aabbccddee 44 NULL 32 +11223344-5566-b777-0888-99aabbccddee 44 NULL 36 +11223344-5566-b777-0888-99aabbccddee 44 NULL 40 +11223344-5566-b777-0888-99aabbccddee 44 NULL 44 +11223344-5566-b777-0888-99aabbccddee 44 NULL 48 +11223344-5566-b777-0888-99aabbccddee 44 NULL 52 +11223344-5566-b777-0888-99aabbccddee 44 NULL 56 +11223344-5566-b777-0888-99aabbccddee 44 NULL 60 +11223344-5566-b777-8888-99aabbccddee 45 11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-0888-99aabbccddee 48 NULL 32 +11223344-5566-c777-0888-99aabbccddee 48 NULL 36 +11223344-5566-c777-0888-99aabbccddee 48 NULL 40 +11223344-5566-c777-0888-99aabbccddee 48 NULL 44 +11223344-5566-c777-0888-99aabbccddee 48 NULL 48 +11223344-5566-c777-0888-99aabbccddee 48 NULL 52 +11223344-5566-c777-0888-99aabbccddee 48 NULL 56 +11223344-5566-c777-0888-99aabbccddee 48 NULL 60 +11223344-5566-c777-8888-99aabbccddee 49 11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-0888-99aabbccddee 52 NULL 32 +11223344-5566-d777-0888-99aabbccddee 52 NULL 36 +11223344-5566-d777-0888-99aabbccddee 52 NULL 40 +11223344-5566-d777-0888-99aabbccddee 52 NULL 44 +11223344-5566-d777-0888-99aabbccddee 52 NULL 48 +11223344-5566-d777-0888-99aabbccddee 52 NULL 52 +11223344-5566-d777-0888-99aabbccddee 52 NULL 56 +11223344-5566-d777-0888-99aabbccddee 52 NULL 60 +11223344-5566-d777-8888-99aabbccddee 53 11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-0888-99aabbccddee 56 NULL 32 +11223344-5566-e777-0888-99aabbccddee 56 NULL 36 +11223344-5566-e777-0888-99aabbccddee 56 NULL 40 +11223344-5566-e777-0888-99aabbccddee 56 NULL 44 +11223344-5566-e777-0888-99aabbccddee 56 NULL 48 +11223344-5566-e777-0888-99aabbccddee 56 NULL 52 +11223344-5566-e777-0888-99aabbccddee 56 NULL 56 +11223344-5566-e777-0888-99aabbccddee 56 NULL 60 +11223344-5566-e777-8888-99aabbccddee 57 11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-0888-99aabbccddee 60 NULL 32 +11223344-5566-f777-0888-99aabbccddee 60 NULL 36 +11223344-5566-f777-0888-99aabbccddee 60 NULL 40 +11223344-5566-f777-0888-99aabbccddee 60 NULL 44 +11223344-5566-f777-0888-99aabbccddee 60 NULL 48 +11223344-5566-f777-0888-99aabbccddee 60 NULL 52 +11223344-5566-f777-0888-99aabbccddee 60 NULL 56 +11223344-5566-f777-0888-99aabbccddee 60 NULL 60 +11223344-5566-f777-8888-99aabbccddee 61 11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 11223344-5566-f777-e888-99aabbccddee 63 +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' +Warning 1292 Incorrect uuid value: '11223344-5566-f777-0888-99aabbccddee' +Warnings: +select * from t1 union select * from t2; +a b +11223344-5566-0777-0888-99aabbccddee 0 +11223344-5566-0777-8888-99aabbccddee 1 +11223344-5566-0777-c888-99aabbccddee 2 +11223344-5566-0777-e888-99aabbccddee 3 +11223344-5566-1777-0888-99aabbccddee 4 +11223344-5566-1777-8888-99aabbccddee 5 +11223344-5566-1777-c888-99aabbccddee 6 +11223344-5566-1777-e888-99aabbccddee 7 +11223344-5566-2777-0888-99aabbccddee 8 +11223344-5566-2777-8888-99aabbccddee 9 +11223344-5566-2777-c888-99aabbccddee 10 +11223344-5566-2777-e888-99aabbccddee 11 +11223344-5566-3777-0888-99aabbccddee 12 +11223344-5566-3777-8888-99aabbccddee 13 +11223344-5566-3777-c888-99aabbccddee 14 +11223344-5566-3777-e888-99aabbccddee 15 +11223344-5566-4777-0888-99aabbccddee 16 +11223344-5566-4777-8888-99aabbccddee 17 +11223344-5566-4777-c888-99aabbccddee 18 +11223344-5566-4777-e888-99aabbccddee 19 +11223344-5566-5777-0888-99aabbccddee 20 +11223344-5566-5777-8888-99aabbccddee 21 +11223344-5566-5777-c888-99aabbccddee 22 +11223344-5566-5777-e888-99aabbccddee 23 +11223344-5566-6777-0888-99aabbccddee 24 +11223344-5566-6777-8888-99aabbccddee 25 +11223344-5566-6777-c888-99aabbccddee 26 +11223344-5566-6777-e888-99aabbccddee 27 +11223344-5566-7777-0888-99aabbccddee 28 +11223344-5566-7777-8888-99aabbccddee 29 +11223344-5566-7777-c888-99aabbccddee 30 +11223344-5566-7777-e888-99aabbccddee 31 +11223344-5566-8777-8888-99aabbccddee 33 +11223344-5566-8777-c888-99aabbccddee 34 +11223344-5566-8777-e888-99aabbccddee 35 +11223344-5566-9777-8888-99aabbccddee 37 +11223344-5566-9777-c888-99aabbccddee 38 +11223344-5566-9777-e888-99aabbccddee 39 +11223344-5566-a777-8888-99aabbccddee 41 +11223344-5566-a777-c888-99aabbccddee 42 +11223344-5566-a777-e888-99aabbccddee 43 +11223344-5566-b777-8888-99aabbccddee 45 +11223344-5566-b777-c888-99aabbccddee 46 +11223344-5566-b777-e888-99aabbccddee 47 +11223344-5566-c777-8888-99aabbccddee 49 +11223344-5566-c777-c888-99aabbccddee 50 +11223344-5566-c777-e888-99aabbccddee 51 +11223344-5566-d777-8888-99aabbccddee 53 +11223344-5566-d777-c888-99aabbccddee 54 +11223344-5566-d777-e888-99aabbccddee 55 +11223344-5566-e777-8888-99aabbccddee 57 +11223344-5566-e777-c888-99aabbccddee 58 +11223344-5566-e777-e888-99aabbccddee 59 +11223344-5566-f777-8888-99aabbccddee 61 +11223344-5566-f777-c888-99aabbccddee 62 +11223344-5566-f777-e888-99aabbccddee 63 +NULL 32 +NULL 36 +NULL 40 +NULL 44 +NULL 48 +NULL 52 +NULL 56 +NULL 60 +alter ignore table t2 force; +Warnings: +Warning 1292 Incorrect uuid value: '11223344-5566-8777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 33 +Warning 1292 Incorrect uuid value: '11223344-5566-9777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 37 +Warning 1292 Incorrect uuid value: '11223344-5566-a777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 41 +Warning 1292 Incorrect uuid value: '11223344-5566-b777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 45 +Warning 1292 Incorrect uuid value: '11223344-5566-c777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 49 +Warning 1292 Incorrect uuid value: '11223344-5566-d777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 53 +Warning 1292 Incorrect uuid value: '11223344-5566-e777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 57 +Warning 1292 Incorrect uuid value: '11223344-5566-f777-0888-99aabbccddee' for column `test`.`t2`.`a` at row 61 +drop table t1, t2; diff --git a/plugin/type_uuid/mysql-test/type_uuid/order.test b/plugin/type_uuid/mysql-test/type_uuid/order.test new file mode 100644 index 00000000000..46f76da98e3 --- /dev/null +++ b/plugin/type_uuid/mysql-test/type_uuid/order.test @@ -0,0 +1,40 @@ +# try all combinations of version and variant +source include/have_sequence.inc; + +create table t1 (a uuid, b int not null, index (a)); +insert t1 select sformat('11223344-5566-{:x}777-{}888-99aabbccddee', seq div 4, elt(1+(seq % 4),0,8,'c','e')),seq from seq_0_to_63; +select * from t1; +select * from t1 order by a; +show create table t1; + +--echo # now let's use the table as above, but created in 10.11.4 +let $datadir= `select @@datadir`; +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.frm $datadir/test/t2.frm +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYI $datadir/test/t2.MYI +--copy_file $MTR_SUITE_DIR/std_data/mdev-29959.MYD $datadir/test/t2.MYD +select * from t2; +select * from t2 order by a; +show create table t2; + +explain select * from t1 left join t2 on (t1.a=t2.a); +--sorted_result +select * from t1 left join t2 on (t1.a=t2.a); + +explain select * from t1 left join t2 on (t1.a<=>t2.a); +--sorted_result +select * from t1 left join t2 on (t1.a<=>t2.a); + +explain select * from t2 left join t1 on (t1.a=t2.a); +--sorted_result +select * from t2 left join t1 on (t1.a=t2.a); + +explain select * from t2 left join t1 on (t1.a<=>t2.a); +--sorted_result +select * from t2 left join t1 on (t1.a<=>t2.a); + +--sorted_result +select * from t1 union select * from t2; + +alter ignore table t2 force; + +drop table t1, t2; diff --git a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD new file mode 100644 index 00000000000..138a08deeb7 Binary files /dev/null and b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYD differ diff --git a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI new file mode 100644 index 00000000000..6dde55b27da Binary files /dev/null and b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.MYI differ diff --git a/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm new file mode 100644 index 00000000000..d03c730aff7 Binary files /dev/null and b/plugin/type_uuid/mysql-test/type_uuid/std_data/mdev-29959.frm differ diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result index ab30c262148..dcbf9c5e51d 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid.result @@ -413,156 +413,6 @@ a 00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000 -00000001-0000-0000-0000-000000000000 -00000002-0000-0000-0000-000000000000 -00000003-0000-0000-0000-000000000000 -00000004-0000-0000-0000-000000000000 -00000005-0000-0000-0000-000000000000 -00000006-0000-0000-0000-000000000000 -00000007-0000-0000-0000-000000000000 -00000008-0000-0000-0000-000000000000 -00000009-0000-0000-0000-000000000000 -0000000a-0000-0000-0000-000000000000 -0000000b-0000-0000-0000-000000000000 -0000000c-0000-0000-0000-000000000000 -0000000d-0000-0000-0000-000000000000 -0000000e-0000-0000-0000-000000000000 -0000000f-0000-0000-0000-000000000000 -00000100-0000-0000-0000-000000000000 -00000200-0000-0000-0000-000000000000 -00000300-0000-0000-0000-000000000000 -00000400-0000-0000-0000-000000000000 -00000500-0000-0000-0000-000000000000 -00000600-0000-0000-0000-000000000000 -00000700-0000-0000-0000-000000000000 -00000800-0000-0000-0000-000000000000 -00000900-0000-0000-0000-000000000000 -00000a00-0000-0000-0000-000000000000 -00000b00-0000-0000-0000-000000000000 -00000c00-0000-0000-0000-000000000000 -00000d00-0000-0000-0000-000000000000 -00000e00-0000-0000-0000-000000000000 -00000f00-0000-0000-0000-000000000000 -00010000-0000-0000-0000-000000000000 -00020000-0000-0000-0000-000000000000 -00030000-0000-0000-0000-000000000000 -00040000-0000-0000-0000-000000000000 -00050000-0000-0000-0000-000000000000 -00060000-0000-0000-0000-000000000000 -00070000-0000-0000-0000-000000000000 -00080000-0000-0000-0000-000000000000 -00090000-0000-0000-0000-000000000000 -000a0000-0000-0000-0000-000000000000 -000b0000-0000-0000-0000-000000000000 -000c0000-0000-0000-0000-000000000000 -000d0000-0000-0000-0000-000000000000 -000e0000-0000-0000-0000-000000000000 -000f0000-0000-0000-0000-000000000000 -01000000-0000-0000-0000-000000000000 -02000000-0000-0000-0000-000000000000 -03000000-0000-0000-0000-000000000000 -04000000-0000-0000-0000-000000000000 -05000000-0000-0000-0000-000000000000 -06000000-0000-0000-0000-000000000000 -07000000-0000-0000-0000-000000000000 -08000000-0000-0000-0000-000000000000 -09000000-0000-0000-0000-000000000000 -0a000000-0000-0000-0000-000000000000 -0b000000-0000-0000-0000-000000000000 -0c000000-0000-0000-0000-000000000000 -0d000000-0000-0000-0000-000000000000 -0e000000-0000-0000-0000-000000000000 -0f000000-0000-0000-0000-000000000000 -00000000-0001-0000-0000-000000000000 -00000000-0002-0000-0000-000000000000 -00000000-0003-0000-0000-000000000000 -00000000-0004-0000-0000-000000000000 -00000000-0005-0000-0000-000000000000 -00000000-0006-0000-0000-000000000000 -00000000-0007-0000-0000-000000000000 -00000000-0008-0000-0000-000000000000 -00000000-0009-0000-0000-000000000000 -00000000-000a-0000-0000-000000000000 -00000000-000b-0000-0000-000000000000 -00000000-000c-0000-0000-000000000000 -00000000-000d-0000-0000-000000000000 -00000000-000e-0000-0000-000000000000 -00000000-000f-0000-0000-000000000000 -00000000-0100-0000-0000-000000000000 -00000000-0200-0000-0000-000000000000 -00000000-0300-0000-0000-000000000000 -00000000-0400-0000-0000-000000000000 -00000000-0500-0000-0000-000000000000 -00000000-0600-0000-0000-000000000000 -00000000-0700-0000-0000-000000000000 -00000000-0800-0000-0000-000000000000 -00000000-0900-0000-0000-000000000000 -00000000-0a00-0000-0000-000000000000 -00000000-0b00-0000-0000-000000000000 -00000000-0c00-0000-0000-000000000000 -00000000-0d00-0000-0000-000000000000 -00000000-0e00-0000-0000-000000000000 -00000000-0f00-0000-0000-000000000000 -00000000-0000-0001-0000-000000000000 -00000000-0000-0002-0000-000000000000 -00000000-0000-0003-0000-000000000000 -00000000-0000-0004-0000-000000000000 -00000000-0000-0005-0000-000000000000 -00000000-0000-0006-0000-000000000000 -00000000-0000-0007-0000-000000000000 -00000000-0000-0008-0000-000000000000 -00000000-0000-0009-0000-000000000000 -00000000-0000-000a-0000-000000000000 -00000000-0000-000b-0000-000000000000 -00000000-0000-000c-0000-000000000000 -00000000-0000-000d-0000-000000000000 -00000000-0000-000e-0000-000000000000 -00000000-0000-000f-0000-000000000000 -00000000-0000-0100-0000-000000000000 -00000000-0000-0200-0000-000000000000 -00000000-0000-0300-0000-000000000000 -00000000-0000-0400-0000-000000000000 -00000000-0000-0500-0000-000000000000 -00000000-0000-0600-0000-000000000000 -00000000-0000-0700-0000-000000000000 -00000000-0000-0800-0000-000000000000 -00000000-0000-0900-0000-000000000000 -00000000-0000-0a00-0000-000000000000 -00000000-0000-0b00-0000-000000000000 -00000000-0000-0c00-0000-000000000000 -00000000-0000-0d00-0000-000000000000 -00000000-0000-0e00-0000-000000000000 -00000000-0000-0f00-0000-000000000000 -00000000-0000-0000-0001-000000000000 -00000000-0000-0000-0002-000000000000 -00000000-0000-0000-0003-000000000000 -00000000-0000-0000-0004-000000000000 -00000000-0000-0000-0005-000000000000 -00000000-0000-0000-0006-000000000000 -00000000-0000-0000-0007-000000000000 -00000000-0000-0000-0008-000000000000 -00000000-0000-0000-0009-000000000000 -00000000-0000-0000-000a-000000000000 -00000000-0000-0000-000b-000000000000 -00000000-0000-0000-000c-000000000000 -00000000-0000-0000-000d-000000000000 -00000000-0000-0000-000e-000000000000 -00000000-0000-0000-000f-000000000000 -00000000-0000-0000-0100-000000000000 -00000000-0000-0000-0200-000000000000 -00000000-0000-0000-0300-000000000000 -00000000-0000-0000-0400-000000000000 -00000000-0000-0000-0500-000000000000 -00000000-0000-0000-0600-000000000000 -00000000-0000-0000-0700-000000000000 -00000000-0000-0000-0800-000000000000 -00000000-0000-0000-0900-000000000000 -00000000-0000-0000-0a00-000000000000 -00000000-0000-0000-0b00-000000000000 -00000000-0000-0000-0c00-000000000000 -00000000-0000-0000-0d00-000000000000 -00000000-0000-0000-0e00-000000000000 -00000000-0000-0000-0f00-000000000000 00000000-0000-0000-0000-000000000001 00000000-0000-0000-0000-000000000002 00000000-0000-0000-0000-000000000003 @@ -653,6 +503,156 @@ a 00000000-0000-0000-0000-0d0000000000 00000000-0000-0000-0000-0e0000000000 00000000-0000-0000-0000-0f0000000000 +00000000-0000-0000-0001-000000000000 +00000000-0000-0000-0002-000000000000 +00000000-0000-0000-0003-000000000000 +00000000-0000-0000-0004-000000000000 +00000000-0000-0000-0005-000000000000 +00000000-0000-0000-0006-000000000000 +00000000-0000-0000-0007-000000000000 +00000000-0000-0000-0008-000000000000 +00000000-0000-0000-0009-000000000000 +00000000-0000-0000-000a-000000000000 +00000000-0000-0000-000b-000000000000 +00000000-0000-0000-000c-000000000000 +00000000-0000-0000-000d-000000000000 +00000000-0000-0000-000e-000000000000 +00000000-0000-0000-000f-000000000000 +00000000-0000-0000-0100-000000000000 +00000000-0000-0000-0200-000000000000 +00000000-0000-0000-0300-000000000000 +00000000-0000-0000-0400-000000000000 +00000000-0000-0000-0500-000000000000 +00000000-0000-0000-0600-000000000000 +00000000-0000-0000-0700-000000000000 +00000000-0000-0000-0800-000000000000 +00000000-0000-0000-0900-000000000000 +00000000-0000-0000-0a00-000000000000 +00000000-0000-0000-0b00-000000000000 +00000000-0000-0000-0c00-000000000000 +00000000-0000-0000-0d00-000000000000 +00000000-0000-0000-0e00-000000000000 +00000000-0000-0000-0f00-000000000000 +00000000-0000-0001-0000-000000000000 +00000000-0000-0002-0000-000000000000 +00000000-0000-0003-0000-000000000000 +00000000-0000-0004-0000-000000000000 +00000000-0000-0005-0000-000000000000 +00000000-0000-0006-0000-000000000000 +00000000-0000-0007-0000-000000000000 +00000000-0000-0008-0000-000000000000 +00000000-0000-0009-0000-000000000000 +00000000-0000-000a-0000-000000000000 +00000000-0000-000b-0000-000000000000 +00000000-0000-000c-0000-000000000000 +00000000-0000-000d-0000-000000000000 +00000000-0000-000e-0000-000000000000 +00000000-0000-000f-0000-000000000000 +00000000-0000-0100-0000-000000000000 +00000000-0000-0200-0000-000000000000 +00000000-0000-0300-0000-000000000000 +00000000-0000-0400-0000-000000000000 +00000000-0000-0500-0000-000000000000 +00000000-0000-0600-0000-000000000000 +00000000-0000-0700-0000-000000000000 +00000000-0000-0800-0000-000000000000 +00000000-0000-0900-0000-000000000000 +00000000-0000-0a00-0000-000000000000 +00000000-0000-0b00-0000-000000000000 +00000000-0000-0c00-0000-000000000000 +00000000-0000-0d00-0000-000000000000 +00000000-0000-0e00-0000-000000000000 +00000000-0000-0f00-0000-000000000000 +00000000-0001-0000-0000-000000000000 +00000000-0002-0000-0000-000000000000 +00000000-0003-0000-0000-000000000000 +00000000-0004-0000-0000-000000000000 +00000000-0005-0000-0000-000000000000 +00000000-0006-0000-0000-000000000000 +00000000-0007-0000-0000-000000000000 +00000000-0008-0000-0000-000000000000 +00000000-0009-0000-0000-000000000000 +00000000-000a-0000-0000-000000000000 +00000000-000b-0000-0000-000000000000 +00000000-000c-0000-0000-000000000000 +00000000-000d-0000-0000-000000000000 +00000000-000e-0000-0000-000000000000 +00000000-000f-0000-0000-000000000000 +00000000-0100-0000-0000-000000000000 +00000000-0200-0000-0000-000000000000 +00000000-0300-0000-0000-000000000000 +00000000-0400-0000-0000-000000000000 +00000000-0500-0000-0000-000000000000 +00000000-0600-0000-0000-000000000000 +00000000-0700-0000-0000-000000000000 +00000000-0800-0000-0000-000000000000 +00000000-0900-0000-0000-000000000000 +00000000-0a00-0000-0000-000000000000 +00000000-0b00-0000-0000-000000000000 +00000000-0c00-0000-0000-000000000000 +00000000-0d00-0000-0000-000000000000 +00000000-0e00-0000-0000-000000000000 +00000000-0f00-0000-0000-000000000000 +00000001-0000-0000-0000-000000000000 +00000002-0000-0000-0000-000000000000 +00000003-0000-0000-0000-000000000000 +00000004-0000-0000-0000-000000000000 +00000005-0000-0000-0000-000000000000 +00000006-0000-0000-0000-000000000000 +00000007-0000-0000-0000-000000000000 +00000008-0000-0000-0000-000000000000 +00000009-0000-0000-0000-000000000000 +0000000a-0000-0000-0000-000000000000 +0000000b-0000-0000-0000-000000000000 +0000000c-0000-0000-0000-000000000000 +0000000d-0000-0000-0000-000000000000 +0000000e-0000-0000-0000-000000000000 +0000000f-0000-0000-0000-000000000000 +00000100-0000-0000-0000-000000000000 +00000200-0000-0000-0000-000000000000 +00000300-0000-0000-0000-000000000000 +00000400-0000-0000-0000-000000000000 +00000500-0000-0000-0000-000000000000 +00000600-0000-0000-0000-000000000000 +00000700-0000-0000-0000-000000000000 +00000800-0000-0000-0000-000000000000 +00000900-0000-0000-0000-000000000000 +00000a00-0000-0000-0000-000000000000 +00000b00-0000-0000-0000-000000000000 +00000c00-0000-0000-0000-000000000000 +00000d00-0000-0000-0000-000000000000 +00000e00-0000-0000-0000-000000000000 +00000f00-0000-0000-0000-000000000000 +00010000-0000-0000-0000-000000000000 +00020000-0000-0000-0000-000000000000 +00030000-0000-0000-0000-000000000000 +00040000-0000-0000-0000-000000000000 +00050000-0000-0000-0000-000000000000 +00060000-0000-0000-0000-000000000000 +00070000-0000-0000-0000-000000000000 +00080000-0000-0000-0000-000000000000 +00090000-0000-0000-0000-000000000000 +000a0000-0000-0000-0000-000000000000 +000b0000-0000-0000-0000-000000000000 +000c0000-0000-0000-0000-000000000000 +000d0000-0000-0000-0000-000000000000 +000e0000-0000-0000-0000-000000000000 +000f0000-0000-0000-0000-000000000000 +01000000-0000-0000-0000-000000000000 +02000000-0000-0000-0000-000000000000 +03000000-0000-0000-0000-000000000000 +04000000-0000-0000-0000-000000000000 +05000000-0000-0000-0000-000000000000 +06000000-0000-0000-0000-000000000000 +07000000-0000-0000-0000-000000000000 +08000000-0000-0000-0000-000000000000 +09000000-0000-0000-0000-000000000000 +0a000000-0000-0000-0000-000000000000 +0b000000-0000-0000-0000-000000000000 +0c000000-0000-0000-0000-000000000000 +0d000000-0000-0000-0000-000000000000 +0e000000-0000-0000-0000-000000000000 +0f000000-0000-0000-0000-000000000000 SELECT COALESCE(NULL, a) FROM t1 ORDER BY a; COALESCE(NULL, a) 00000000-0000-0000-0000-000000000000 @@ -671,156 +671,6 @@ COALESCE(NULL, a) 00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000 00000000-0000-0000-0000-000000000000 -00000001-0000-0000-0000-000000000000 -00000002-0000-0000-0000-000000000000 -00000003-0000-0000-0000-000000000000 -00000004-0000-0000-0000-000000000000 -00000005-0000-0000-0000-000000000000 -00000006-0000-0000-0000-000000000000 -00000007-0000-0000-0000-000000000000 -00000008-0000-0000-0000-000000000000 -00000009-0000-0000-0000-000000000000 -0000000a-0000-0000-0000-000000000000 -0000000b-0000-0000-0000-000000000000 -0000000c-0000-0000-0000-000000000000 -0000000d-0000-0000-0000-000000000000 -0000000e-0000-0000-0000-000000000000 -0000000f-0000-0000-0000-000000000000 -00000100-0000-0000-0000-000000000000 -00000200-0000-0000-0000-000000000000 -00000300-0000-0000-0000-000000000000 -00000400-0000-0000-0000-000000000000 -00000500-0000-0000-0000-000000000000 -00000600-0000-0000-0000-000000000000 -00000700-0000-0000-0000-000000000000 -00000800-0000-0000-0000-000000000000 -00000900-0000-0000-0000-000000000000 -00000a00-0000-0000-0000-000000000000 -00000b00-0000-0000-0000-000000000000 -00000c00-0000-0000-0000-000000000000 -00000d00-0000-0000-0000-000000000000 -00000e00-0000-0000-0000-000000000000 -00000f00-0000-0000-0000-000000000000 -00010000-0000-0000-0000-000000000000 -00020000-0000-0000-0000-000000000000 -00030000-0000-0000-0000-000000000000 -00040000-0000-0000-0000-000000000000 -00050000-0000-0000-0000-000000000000 -00060000-0000-0000-0000-000000000000 -00070000-0000-0000-0000-000000000000 -00080000-0000-0000-0000-000000000000 -00090000-0000-0000-0000-000000000000 -000a0000-0000-0000-0000-000000000000 -000b0000-0000-0000-0000-000000000000 -000c0000-0000-0000-0000-000000000000 -000d0000-0000-0000-0000-000000000000 -000e0000-0000-0000-0000-000000000000 -000f0000-0000-0000-0000-000000000000 -01000000-0000-0000-0000-000000000000 -02000000-0000-0000-0000-000000000000 -03000000-0000-0000-0000-000000000000 -04000000-0000-0000-0000-000000000000 -05000000-0000-0000-0000-000000000000 -06000000-0000-0000-0000-000000000000 -07000000-0000-0000-0000-000000000000 -08000000-0000-0000-0000-000000000000 -09000000-0000-0000-0000-000000000000 -0a000000-0000-0000-0000-000000000000 -0b000000-0000-0000-0000-000000000000 -0c000000-0000-0000-0000-000000000000 -0d000000-0000-0000-0000-000000000000 -0e000000-0000-0000-0000-000000000000 -0f000000-0000-0000-0000-000000000000 -00000000-0001-0000-0000-000000000000 -00000000-0002-0000-0000-000000000000 -00000000-0003-0000-0000-000000000000 -00000000-0004-0000-0000-000000000000 -00000000-0005-0000-0000-000000000000 -00000000-0006-0000-0000-000000000000 -00000000-0007-0000-0000-000000000000 -00000000-0008-0000-0000-000000000000 -00000000-0009-0000-0000-000000000000 -00000000-000a-0000-0000-000000000000 -00000000-000b-0000-0000-000000000000 -00000000-000c-0000-0000-000000000000 -00000000-000d-0000-0000-000000000000 -00000000-000e-0000-0000-000000000000 -00000000-000f-0000-0000-000000000000 -00000000-0100-0000-0000-000000000000 -00000000-0200-0000-0000-000000000000 -00000000-0300-0000-0000-000000000000 -00000000-0400-0000-0000-000000000000 -00000000-0500-0000-0000-000000000000 -00000000-0600-0000-0000-000000000000 -00000000-0700-0000-0000-000000000000 -00000000-0800-0000-0000-000000000000 -00000000-0900-0000-0000-000000000000 -00000000-0a00-0000-0000-000000000000 -00000000-0b00-0000-0000-000000000000 -00000000-0c00-0000-0000-000000000000 -00000000-0d00-0000-0000-000000000000 -00000000-0e00-0000-0000-000000000000 -00000000-0f00-0000-0000-000000000000 -00000000-0000-0001-0000-000000000000 -00000000-0000-0002-0000-000000000000 -00000000-0000-0003-0000-000000000000 -00000000-0000-0004-0000-000000000000 -00000000-0000-0005-0000-000000000000 -00000000-0000-0006-0000-000000000000 -00000000-0000-0007-0000-000000000000 -00000000-0000-0008-0000-000000000000 -00000000-0000-0009-0000-000000000000 -00000000-0000-000a-0000-000000000000 -00000000-0000-000b-0000-000000000000 -00000000-0000-000c-0000-000000000000 -00000000-0000-000d-0000-000000000000 -00000000-0000-000e-0000-000000000000 -00000000-0000-000f-0000-000000000000 -00000000-0000-0100-0000-000000000000 -00000000-0000-0200-0000-000000000000 -00000000-0000-0300-0000-000000000000 -00000000-0000-0400-0000-000000000000 -00000000-0000-0500-0000-000000000000 -00000000-0000-0600-0000-000000000000 -00000000-0000-0700-0000-000000000000 -00000000-0000-0800-0000-000000000000 -00000000-0000-0900-0000-000000000000 -00000000-0000-0a00-0000-000000000000 -00000000-0000-0b00-0000-000000000000 -00000000-0000-0c00-0000-000000000000 -00000000-0000-0d00-0000-000000000000 -00000000-0000-0e00-0000-000000000000 -00000000-0000-0f00-0000-000000000000 -00000000-0000-0000-0001-000000000000 -00000000-0000-0000-0002-000000000000 -00000000-0000-0000-0003-000000000000 -00000000-0000-0000-0004-000000000000 -00000000-0000-0000-0005-000000000000 -00000000-0000-0000-0006-000000000000 -00000000-0000-0000-0007-000000000000 -00000000-0000-0000-0008-000000000000 -00000000-0000-0000-0009-000000000000 -00000000-0000-0000-000a-000000000000 -00000000-0000-0000-000b-000000000000 -00000000-0000-0000-000c-000000000000 -00000000-0000-0000-000d-000000000000 -00000000-0000-0000-000e-000000000000 -00000000-0000-0000-000f-000000000000 -00000000-0000-0000-0100-000000000000 -00000000-0000-0000-0200-000000000000 -00000000-0000-0000-0300-000000000000 -00000000-0000-0000-0400-000000000000 -00000000-0000-0000-0500-000000000000 -00000000-0000-0000-0600-000000000000 -00000000-0000-0000-0700-000000000000 -00000000-0000-0000-0800-000000000000 -00000000-0000-0000-0900-000000000000 -00000000-0000-0000-0a00-000000000000 -00000000-0000-0000-0b00-000000000000 -00000000-0000-0000-0c00-000000000000 -00000000-0000-0000-0d00-000000000000 -00000000-0000-0000-0e00-000000000000 -00000000-0000-0000-0f00-000000000000 00000000-0000-0000-0000-000000000001 00000000-0000-0000-0000-000000000002 00000000-0000-0000-0000-000000000003 @@ -911,6 +761,156 @@ COALESCE(NULL, a) 00000000-0000-0000-0000-0d0000000000 00000000-0000-0000-0000-0e0000000000 00000000-0000-0000-0000-0f0000000000 +00000000-0000-0000-0001-000000000000 +00000000-0000-0000-0002-000000000000 +00000000-0000-0000-0003-000000000000 +00000000-0000-0000-0004-000000000000 +00000000-0000-0000-0005-000000000000 +00000000-0000-0000-0006-000000000000 +00000000-0000-0000-0007-000000000000 +00000000-0000-0000-0008-000000000000 +00000000-0000-0000-0009-000000000000 +00000000-0000-0000-000a-000000000000 +00000000-0000-0000-000b-000000000000 +00000000-0000-0000-000c-000000000000 +00000000-0000-0000-000d-000000000000 +00000000-0000-0000-000e-000000000000 +00000000-0000-0000-000f-000000000000 +00000000-0000-0000-0100-000000000000 +00000000-0000-0000-0200-000000000000 +00000000-0000-0000-0300-000000000000 +00000000-0000-0000-0400-000000000000 +00000000-0000-0000-0500-000000000000 +00000000-0000-0000-0600-000000000000 +00000000-0000-0000-0700-000000000000 +00000000-0000-0000-0800-000000000000 +00000000-0000-0000-0900-000000000000 +00000000-0000-0000-0a00-000000000000 +00000000-0000-0000-0b00-000000000000 +00000000-0000-0000-0c00-000000000000 +00000000-0000-0000-0d00-000000000000 +00000000-0000-0000-0e00-000000000000 +00000000-0000-0000-0f00-000000000000 +00000000-0000-0001-0000-000000000000 +00000000-0000-0002-0000-000000000000 +00000000-0000-0003-0000-000000000000 +00000000-0000-0004-0000-000000000000 +00000000-0000-0005-0000-000000000000 +00000000-0000-0006-0000-000000000000 +00000000-0000-0007-0000-000000000000 +00000000-0000-0008-0000-000000000000 +00000000-0000-0009-0000-000000000000 +00000000-0000-000a-0000-000000000000 +00000000-0000-000b-0000-000000000000 +00000000-0000-000c-0000-000000000000 +00000000-0000-000d-0000-000000000000 +00000000-0000-000e-0000-000000000000 +00000000-0000-000f-0000-000000000000 +00000000-0000-0100-0000-000000000000 +00000000-0000-0200-0000-000000000000 +00000000-0000-0300-0000-000000000000 +00000000-0000-0400-0000-000000000000 +00000000-0000-0500-0000-000000000000 +00000000-0000-0600-0000-000000000000 +00000000-0000-0700-0000-000000000000 +00000000-0000-0800-0000-000000000000 +00000000-0000-0900-0000-000000000000 +00000000-0000-0a00-0000-000000000000 +00000000-0000-0b00-0000-000000000000 +00000000-0000-0c00-0000-000000000000 +00000000-0000-0d00-0000-000000000000 +00000000-0000-0e00-0000-000000000000 +00000000-0000-0f00-0000-000000000000 +00000000-0001-0000-0000-000000000000 +00000000-0002-0000-0000-000000000000 +00000000-0003-0000-0000-000000000000 +00000000-0004-0000-0000-000000000000 +00000000-0005-0000-0000-000000000000 +00000000-0006-0000-0000-000000000000 +00000000-0007-0000-0000-000000000000 +00000000-0008-0000-0000-000000000000 +00000000-0009-0000-0000-000000000000 +00000000-000a-0000-0000-000000000000 +00000000-000b-0000-0000-000000000000 +00000000-000c-0000-0000-000000000000 +00000000-000d-0000-0000-000000000000 +00000000-000e-0000-0000-000000000000 +00000000-000f-0000-0000-000000000000 +00000000-0100-0000-0000-000000000000 +00000000-0200-0000-0000-000000000000 +00000000-0300-0000-0000-000000000000 +00000000-0400-0000-0000-000000000000 +00000000-0500-0000-0000-000000000000 +00000000-0600-0000-0000-000000000000 +00000000-0700-0000-0000-000000000000 +00000000-0800-0000-0000-000000000000 +00000000-0900-0000-0000-000000000000 +00000000-0a00-0000-0000-000000000000 +00000000-0b00-0000-0000-000000000000 +00000000-0c00-0000-0000-000000000000 +00000000-0d00-0000-0000-000000000000 +00000000-0e00-0000-0000-000000000000 +00000000-0f00-0000-0000-000000000000 +00000001-0000-0000-0000-000000000000 +00000002-0000-0000-0000-000000000000 +00000003-0000-0000-0000-000000000000 +00000004-0000-0000-0000-000000000000 +00000005-0000-0000-0000-000000000000 +00000006-0000-0000-0000-000000000000 +00000007-0000-0000-0000-000000000000 +00000008-0000-0000-0000-000000000000 +00000009-0000-0000-0000-000000000000 +0000000a-0000-0000-0000-000000000000 +0000000b-0000-0000-0000-000000000000 +0000000c-0000-0000-0000-000000000000 +0000000d-0000-0000-0000-000000000000 +0000000e-0000-0000-0000-000000000000 +0000000f-0000-0000-0000-000000000000 +00000100-0000-0000-0000-000000000000 +00000200-0000-0000-0000-000000000000 +00000300-0000-0000-0000-000000000000 +00000400-0000-0000-0000-000000000000 +00000500-0000-0000-0000-000000000000 +00000600-0000-0000-0000-000000000000 +00000700-0000-0000-0000-000000000000 +00000800-0000-0000-0000-000000000000 +00000900-0000-0000-0000-000000000000 +00000a00-0000-0000-0000-000000000000 +00000b00-0000-0000-0000-000000000000 +00000c00-0000-0000-0000-000000000000 +00000d00-0000-0000-0000-000000000000 +00000e00-0000-0000-0000-000000000000 +00000f00-0000-0000-0000-000000000000 +00010000-0000-0000-0000-000000000000 +00020000-0000-0000-0000-000000000000 +00030000-0000-0000-0000-000000000000 +00040000-0000-0000-0000-000000000000 +00050000-0000-0000-0000-000000000000 +00060000-0000-0000-0000-000000000000 +00070000-0000-0000-0000-000000000000 +00080000-0000-0000-0000-000000000000 +00090000-0000-0000-0000-000000000000 +000a0000-0000-0000-0000-000000000000 +000b0000-0000-0000-0000-000000000000 +000c0000-0000-0000-0000-000000000000 +000d0000-0000-0000-0000-000000000000 +000e0000-0000-0000-0000-000000000000 +000f0000-0000-0000-0000-000000000000 +01000000-0000-0000-0000-000000000000 +02000000-0000-0000-0000-000000000000 +03000000-0000-0000-0000-000000000000 +04000000-0000-0000-0000-000000000000 +05000000-0000-0000-0000-000000000000 +06000000-0000-0000-0000-000000000000 +07000000-0000-0000-0000-000000000000 +08000000-0000-0000-0000-000000000000 +09000000-0000-0000-0000-000000000000 +0a000000-0000-0000-0000-000000000000 +0b000000-0000-0000-0000-000000000000 +0c000000-0000-0000-0000-000000000000 +0d000000-0000-0000-0000-000000000000 +0e000000-0000-0000-0000-000000000000 +0f000000-0000-0000-0000-000000000000 # # Lexicographical ORDER BY # @@ -1659,10 +1659,10 @@ INSERT INTO t1 VALUES (CAST(CONCAT('2','0000000-0000-0000-0000-000000000003') AS SELECT * FROM t1 ORDER BY a; a 10000000-0000-0000-0000-000000000001 -20000000-0000-0000-0000-000000000001 10000000-0000-0000-0000-000000000002 -20000000-0000-0000-0000-000000000002 10000000-0000-0000-0000-000000000003 +20000000-0000-0000-0000-000000000001 +20000000-0000-0000-0000-000000000002 20000000-0000-0000-0000-000000000003 DROP TABLE t1; # @@ -3178,8 +3178,8 @@ CREATE TABLE t1 (d UUID); INSERT INTO t1 VALUES ('00000000-0000-0000-0000-111111111111'), ('11111111-0000-0000-0000-000000000000'); SELECT * FROM t1 ORDER BY d; d -11111111-0000-0000-0000-000000000000 00000000-0000-0000-0000-111111111111 +11111111-0000-0000-0000-000000000000 SELECT * FROM t1 WHERE d <= ALL (SELECT * FROM t1); d 11111111-0000-0000-0000-000000000000 diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_memory.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_memory.result index f2a1e27d0d0..21086fef2cb 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_memory.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_memory.result @@ -25,7 +25,7 @@ a 00000000-0000-0000-0000-0000000000ff EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-0000-0000000000ff'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 17 const 4 Using where +1 SIMPLE t1 ref a a 17 const 2 Using where SELECT * FROM t1 WHERE a='garbage'; a Warnings: @@ -66,7 +66,7 @@ EXPLAIN SELECT * FROM t1 WHERE a IN '00000000-0000-0000-0000-0000000000f0' ); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 17 NULL 12 Using where +1 SIMPLE t1 range a a 17 NULL 6 Using where SELECT * FROM t1 WHERE a IN ( '00000000-0000-0000-0000-000000000080', @@ -85,7 +85,7 @@ EXPLAIN SELECT * FROM t1 WHERE a IN 'garbage' ); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 17 NULL 8 Using where +1 SIMPLE t1 range a a 17 NULL 4 Using where Warnings: Warning 1292 Incorrect uuid value: 'garbage' SELECT * FROM t1 WHERE a BETWEEN @@ -178,7 +178,7 @@ a 00000000-0000-0000-0000-0000000000ff EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-0000000000ff' AS UUID); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ref a a 17 const 4 100.00 Using where +1 SIMPLE t1 ref a a 17 const 2 100.00 Using where Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff' DROP TABLE t1; diff --git a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_myisam.result b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_myisam.result index 8df2c85ae48..736aea4555f 100644 --- a/plugin/type_uuid/mysql-test/type_uuid/type_uuid_myisam.result +++ b/plugin/type_uuid/mysql-test/type_uuid/type_uuid_myisam.result @@ -25,7 +25,7 @@ a 00000000-0000-0000-0000-0000000000ff EXPLAIN SELECT * FROM t1 WHERE a='00000000-0000-0000-0000-0000000000ff'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ref a a 17 const 1 Using where; Using index +1 SIMPLE t1 ref a a 17 const 7 Using where; Using index SELECT * FROM t1 WHERE a='garbage'; a Warnings: @@ -41,7 +41,7 @@ a 00000000-0000-0000-0000-0000000000ff EXPLAIN SELECT * FROM t1 WHERE a>='00000000-0000-0000-0000-0000000000fe'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 17 NULL 3 Using where; Using index +1 SIMPLE t1 range a a 17 NULL 28 Using where; Using index SELECT * FROM t1 WHERE a>='garbage'; a EXPLAIN SELECT * FROM t1 WHERE a>='garbage'; @@ -64,7 +64,7 @@ EXPLAIN SELECT * FROM t1 WHERE a IN '00000000-0000-0000-0000-0000000000f0' ); id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 17 NULL 4 Using where; Using index +1 SIMPLE t1 range a a 17 NULL 3 Using where; Using index SELECT * FROM t1 WHERE a IN ( '00000000-0000-0000-0000-000000000080', @@ -96,7 +96,7 @@ EXPLAIN SELECT * FROM t1 WHERE a BETWEEN '00000000-0000-0000-0000-000000000080' AND '00000000-0000-0000-0000-000000000081'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range a a 17 NULL 2 Using where; Using index +1 SIMPLE t1 range a a 17 NULL 1 Using where; Using index SELECT * FROM t1 WHERE a BETWEEN '00000000-0000-0000-0000-000000000080' AND 'garbage'; @@ -111,7 +111,7 @@ a 00000000-0000-0000-0000-0000000000ff EXPLAIN EXTENDED SELECT * FROM t1 WHERE a=CAST('00000000-0000-0000-0000-0000000000ff' AS UUID); id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ref a a 17 const 1 100.00 Using where; Using index +1 SIMPLE t1 ref a a 17 const 7 100.00 Using where; Using index Warnings: Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = UUID'00000000-0000-0000-0000-0000000000ff' DROP TABLE t1; diff --git a/plugin/type_uuid/plugin.cc b/plugin/type_uuid/plugin.cc index bd320a9a897..499019e948c 100644 --- a/plugin/type_uuid/plugin.cc +++ b/plugin/type_uuid/plugin.cc @@ -21,12 +21,83 @@ #include #include +/* + The whole purpose of this Type_handler_uuid_dispatcher is to choose + whether the field should use Type_handler_uuid_new or Type_handler_uuid_old + based on the version of MariaDB that created the table. + When created every field will use either Type_handler_uuid_new or _old. + Literals and functions always use _new. +*/ +class Type_handler_uuid_dispatcher: public Type_handler_uuid_new +{ +public: + Field *make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *root, + const LEX_CSTRING *name, const Record_addr &addr, + const Bit_addr &bit, + const Column_definition_attributes *attr, + uint32 flags) const override + { + bool new_uuid= share->mysql_version == 0 || + (share->mysql_version >= 100908 && share->mysql_version < 100999) || + (share->mysql_version >= 101006 && share->mysql_version < 101099) || + (share->mysql_version >= 101105 && share->mysql_version < 101199) || + (share->mysql_version >= 110003 && share->mysql_version < 110099) || + (share->mysql_version >= 110102 && share->mysql_version < 110199) || + share->mysql_version >= 110201; + static Type_handler *th[]= { + Type_handler_uuid_old::singleton(), Type_handler_uuid_new::singleton() + }; + return th[new_uuid]-> + make_table_field_from_def(share, root, name, addr, bit, attr, flags); + } +}; + +static Type_handler_uuid_dispatcher type_handler_uuid_dispatcher; + static struct st_mariadb_data_type plugin_descriptor_type_uuid= { MariaDB_DATA_TYPE_INTERFACE_VERSION, - UUIDBundle::type_handler_fbt() + &type_handler_uuid_dispatcher }; + +const Type_handler *Type_collection_uuid::find_in_array(const Type_handler *a, + const Type_handler *b, + bool for_cmp) const +{ + if (a == b) return a; + + /* + in the search below we'll find if we can convert `b` to `a`. + So, if one of the arguments is uuid and the other is not, + we should put uuid type in `a` and not-uuid in `b`. And if one type is + new uuid and the other is old uuid, new uuid should be in `a` + */ + if (a != Type_handler_uuid_new::singleton() && b->type_collection() == this) + std::swap(a, b); + + DBUG_ASSERT(a != &type_handler_uuid_dispatcher); + DBUG_ASSERT(b != &type_handler_uuid_dispatcher); + + /* + Search in the array for an element, equal to `b`. + If found - return `a`, if not found - return NULL. + Array is terminated by `a`. + */ + static const Type_handler *arr[]={ &type_handler_varchar, + &type_handler_string, &type_handler_tiny_blob, &type_handler_blob, + &type_handler_medium_blob, &type_handler_hex_hybrid, + // in aggregate_for_comparison() all types above cannot happen, + // so we'll start the search from here: + &type_handler_null, &type_handler_long_blob, + Type_handler_uuid_old::singleton(), Type_handler_uuid_new::singleton() }; + + for (int i= for_cmp ? 6 : 0; arr[i] != a; i++) + if (arr[i] == b) + return a; + return NULL; +} + /*************************************************************************/ class Create_func_uuid : public Create_func_arg0 @@ -71,17 +142,26 @@ static Plugin_function plugin_descriptor_function_uuid(&Create_func_uuid::s_singleton), plugin_descriptor_function_sys_guid(&Create_func_sys_guid::s_singleton); +static constexpr Name type_name={STRING_WITH_LEN("uuid")}; + +int uuid_init(void*) +{ + Type_handler_uuid_new::singleton()->set_name(type_name); + Type_handler_uuid_old::singleton()->set_name(type_name); + return 0; +} + /*************************************************************************/ maria_declare_plugin(type_uuid) { MariaDB_DATA_TYPE_PLUGIN, // the plugin type (see include/mysql/plugin.h) &plugin_descriptor_type_uuid, // pointer to type-specific plugin descriptor - "uuid", // plugin name + type_name.ptr(), // plugin name "MariaDB Corporation", // plugin author "Data type UUID", // the plugin description PLUGIN_LICENSE_GPL, // the plugin license (see include/mysql/plugin.h) - 0, // Pointer to plugin initialization function + uuid_init, // Pointer to plugin initialization function 0, // Pointer to plugin deinitialization function 0x0100, // Numeric version 0xAABB means AA.BB version NULL, // Status variables diff --git a/plugin/type_uuid/sql_type_uuid.cc b/plugin/type_uuid/sql_type_uuid.cc deleted file mode 100644 index 9b4a731dbb2..00000000000 --- a/plugin/type_uuid/sql_type_uuid.cc +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (c) 2019,2021 MariaDB Corporation - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ - -#define MYSQL_SERVER -#include "mariadb.h" -#include "my_net.h" -#include "sql_class.h" // THD, SORT_FIELD_ATTR -#include "opt_range.h" // SEL_ARG -#include "sql_type_uuid.h" - - -static bool get_digit(char ch, uint *val) -{ - if (ch >= '0' && ch <= '9') - { - *val= (uint) ch - '0'; - return false; - } - if (ch >= 'a' && ch <= 'f') - { - *val= (uint) ch - 'a' + 0x0a; - return false; - } - if (ch >= 'A' && ch <= 'F') - { - *val= (uint) ch - 'A' + 0x0a; - return false; - } - return true; -} - - -static bool get_digit(uint *val, const char *str, const char *end) -{ - if (str >= end) - return true; - return get_digit(*str, val); -} - - -static size_t skip_hyphens(const char *str, const char *end) -{ - const char *str0= str; - for ( ; str < end; str++) - { - if (str[0] != '-') - break; - } - return str - str0; -} - - -static const char *get_two_digits(char *val, const char *str, const char *end) -{ - uint hi, lo; - if (get_digit(&hi, str++, end)) - return NULL; - str+= skip_hyphens(str, end); - if (get_digit(&lo, str++, end)) - return NULL; - *val= (char) ((hi << 4) + lo); - return str; -} - - -bool UUID::ascii_to_fbt(const char *str, size_t str_length) -{ - const char *end= str + str_length; - /* - The format understood: - - Hyphen is not allowed on the first and the last position. - - Otherwise, hyphens are allowed on any (odd and even) position, - with any amount. - */ - if (str_length < 32) - goto err; - - for (uint oidx= 0; oidx < binary_length(); oidx++) - { - if (!(str= get_two_digits(&m_buffer[oidx], str, end))) - goto err; - // Allow hypheps after two digits, but not after the last digit - if (oidx + 1 < binary_length()) - str+= skip_hyphens(str, end); - } - if (str < end) - goto err; // Some input left - return false; -err: - bzero(m_buffer, sizeof(m_buffer)); - return true; -} - -size_t UUID::to_string(char *dst, size_t dstsize) const -{ - my_uuid2str((const uchar *) m_buffer, dst, 1); - return MY_UUID_STRING_LENGTH; -} - - -const Name &UUID::default_value() -{ - static Name def(STRING_WITH_LEN("00000000-0000-0000-0000-000000000000")); - return def; -} diff --git a/plugin/type_uuid/sql_type_uuid.h b/plugin/type_uuid/sql_type_uuid.h index ee39f542f05..272898efc8c 100644 --- a/plugin/type_uuid/sql_type_uuid.h +++ b/plugin/type_uuid/sql_type_uuid.h @@ -17,13 +17,103 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ #include "sql_type_fixedbin_storage.h" + +template class UUID: public FixedBinTypeStorage { + bool get_digit(char ch, uint *val) + { + if (ch >= '0' && ch <= '9') + { + *val= (uint) ch - '0'; + return false; + } + if (ch >= 'a' && ch <= 'f') + { + *val= (uint) ch - 'a' + 0x0a; + return false; + } + if (ch >= 'A' && ch <= 'F') + { + *val= (uint) ch - 'A' + 0x0a; + return false; + } + return true; + } + + bool get_digit(uint *val, const char *str, const char *end) + { + if (str >= end) + return true; + return get_digit(*str, val); + } + + size_t skip_hyphens(const char *str, const char *end) + { + const char *str0= str; + for ( ; str < end; str++) + { + if (str[0] != '-') + break; + } + return str - str0; + } + + const char *get_two_digits(char *val, const char *str, const char *end) + { + uint hi, lo; + if (get_digit(&hi, str++, end)) + return NULL; + str+= skip_hyphens(str, end); + if (get_digit(&lo, str++, end)) + return NULL; + *val= (char) ((hi << 4) + lo); + return str; + } + public: using FixedBinTypeStorage::FixedBinTypeStorage; - bool ascii_to_fbt(const char *str, size_t str_length); - size_t to_string(char *dst, size_t dstsize) const; - static const Name &default_value(); + bool ascii_to_fbt(const char *str, size_t str_length) + { + const char *end= str + str_length; + /* + The format understood: + - Hyphen is not allowed on the first and the last position. + - Otherwise, hyphens are allowed on any (odd and even) position, + with any amount. + */ + if (str_length < 32) + goto err; + + for (uint oidx= 0; oidx < binary_length(); oidx++) + { + if (!(str= get_two_digits(&m_buffer[oidx], str, end))) + goto err; + // Allow hypheps after two digits, but not after the last digit + if (oidx + 1 < binary_length()) + str+= skip_hyphens(str, end); + } + if (str < end) + goto err; // Some input left + if (m_buffer[6] & -m_buffer[8] & 0x80) + goto err; // impossible combination: version >= 8, variant = 0 + return false; + err: + bzero(m_buffer, sizeof(m_buffer)); + return true; + } + + size_t to_string(char *dst, size_t dstsize) const + { + my_uuid2str((const uchar *) m_buffer, dst, 1); + return MY_UUID_STRING_LENGTH; + } + + static const Name &default_value() + { + static Name def(STRING_WITH_LEN("00000000-0000-0000-0000-000000000000")); + return def; + } /* Binary (in-memory) UUIDv1 representation: @@ -86,21 +176,31 @@ public: // Convert the in-memory representation to the in-record representation static void memory_to_record(char *to, const char *from) { - segment(0).memory_to_record(to, from); - segment(1).memory_to_record(to, from); - segment(2).memory_to_record(to, from); - segment(3).memory_to_record(to, from); - segment(4).memory_to_record(to, from); + if (force_swap || (from[6] > 0 && from[6] < 0x60 && from[8] & 0x80)) + { + segment(0).memory_to_record(to, from); + segment(1).memory_to_record(to, from); + segment(2).memory_to_record(to, from); + segment(3).memory_to_record(to, from); + segment(4).memory_to_record(to, from); + } + else + memcpy(to, from, binary_length()); } // Convert the in-record representation to the in-memory representation static void record_to_memory(char *to, const char *from) { - segment(0).record_to_memory(to, from); - segment(1).record_to_memory(to, from); - segment(2).record_to_memory(to, from); - segment(3).record_to_memory(to, from); - segment(4).record_to_memory(to, from); + if (force_swap || (from[6] & -from[8] & 0x80)) + { + segment(0).record_to_memory(to, from); + segment(1).record_to_memory(to, from); + segment(2).record_to_memory(to, from); + segment(3).record_to_memory(to, from); + segment(4).record_to_memory(to, from); + } + else + memcpy(to, from, binary_length()); } /* @@ -179,8 +279,38 @@ public: }; +class Type_collection_uuid: public Type_collection +{ + const Type_handler *find_in_array(const Type_handler *what, + const Type_handler *stop, + bool for_comparison) const; +public: + const Type_handler *aggregate_for_result(const Type_handler *a, + const Type_handler *b) + const override + { return find_in_array(a, b, false); } + const Type_handler *aggregate_for_min_max(const Type_handler *a, + const Type_handler *b) + const override + { return find_in_array(a, b, false); } + const Type_handler *aggregate_for_comparison(const Type_handler *a, + const Type_handler *b) + const override + { return find_in_array(a, b, true); } + const Type_handler *aggregate_for_num_op(const Type_handler *a, + const Type_handler *b) + const override + { return NULL; } + + static Type_collection_uuid *singleton() + { + static Type_collection_uuid tc; + return &tc; + } +}; #include "sql_type_fixedbin.h" -typedef FixedBinTypeBundle UUIDBundle; +typedef Type_handler_fbt, Type_collection_uuid> Type_handler_uuid_old; +typedef Type_handler_fbt, Type_collection_uuid> Type_handler_uuid_new; #endif // SQL_TYPE_UUID_INCLUDED diff --git a/sql/ddl_log.cc b/sql/ddl_log.cc index 67c8a8bca4f..3be7cbfd5bd 100644 --- a/sql/ddl_log.cc +++ b/sql/ddl_log.cc @@ -143,23 +143,23 @@ static st_ddl_recovery recovery_state; mysql_mutex_t LOCK_gdl; /* Positions to different data in a ddl log block */ -#define DDL_LOG_ENTRY_TYPE_POS 0 +static constexpr unsigned DDL_LOG_ENTRY_TYPE_POS= 0; /* Note that ACTION_TYPE and PHASE_POS must be after each other. See update_phase() */ -#define DDL_LOG_ACTION_TYPE_POS 1 -#define DDL_LOG_PHASE_POS 2 -#define DDL_LOG_NEXT_ENTRY_POS 4 +static constexpr unsigned DDL_LOG_ACTION_TYPE_POS= 1; +static constexpr unsigned DDL_LOG_PHASE_POS= 2; +static constexpr unsigned DDL_LOG_NEXT_ENTRY_POS= 4; /* Flags to remember something unique about the query, like if .frm was used */ -#define DDL_LOG_FLAG_POS 8 +static constexpr unsigned DDL_LOG_FLAG_POS= 8; /* Used to store XID entry that was written to binary log */ -#define DDL_LOG_XID_POS 10 +static constexpr unsigned DDL_LOG_XID_POS= 10; /* Used to store unique uuid from the .frm file */ -#define DDL_LOG_UUID_POS 18 -/* ID_POS can be used to store something unique, like file size (8 bytes) */ -#define DDL_LOG_ID_POS DDL_LOG_UUID_POS + MY_UUID_SIZE -#define DDL_LOG_END_POS DDL_LOG_ID_POS + 8 +static constexpr unsigned DDL_LOG_UUID_POS= 18; +/* ID_POS can be used to store something unique, like file size (4 bytes) */ +static constexpr unsigned DDL_LOG_ID_POS= DDL_LOG_UUID_POS + MY_UUID_SIZE; +static constexpr unsigned DDL_LOG_END_POS= DDL_LOG_ID_POS + 8; /* Position to where names are stored in the ddl log blocks. The current @@ -167,19 +167,19 @@ mysql_mutex_t LOCK_gdl; space for constants in the header than what is between DDL_LOG_ID_POS and DDL_LOG_TMP_NAME_POS. */ -#define DDL_LOG_TMP_NAME_POS 56 +static constexpr unsigned DDL_LOG_TMP_NAME_POS= 56; /* Definitions for the ddl log header, the first block in the file */ /* IO_SIZE is stored in the header and can thus be changed */ -#define DDL_LOG_IO_SIZE IO_SIZE +static constexpr unsigned DDL_LOG_IO_SIZE= IO_SIZE; /* Header is stored in positions 0-3 */ -#define DDL_LOG_IO_SIZE_POS 4 -#define DDL_LOG_NAME_OFFSET_POS 6 +static constexpr unsigned DDL_LOG_IO_SIZE_POS= 4; +static constexpr unsigned DDL_LOG_NAME_OFFSET_POS= 6; /* Marks if we have done a backup of the ddl log */ -#define DDL_LOG_BACKUP_OFFSET_POS 8 +static constexpr unsigned DDL_LOG_BACKUP_OFFSET_POS= 8; /* Sum of the above variables */ -#define DDL_LOG_HEADER_SIZE 4+2+2+1 +static constexpr unsigned DDL_LOG_HEADER_SIZE= 4+2+2+1; /** Sync the ddl log file. @@ -1104,7 +1104,7 @@ static void execute_rename_table(DDL_LOG_ENTRY *ddl_log_entry, handler *file, { fr_length= build_table_filename(from_path, FN_REFLEN, from_db->str, from_table->str, "", - flags & FN_TO_IS_TMP); + flags & FN_FROM_IS_TMP); to_length= build_table_filename(to_path, FN_REFLEN, to_db->str, to_table->str, "", flags & FN_TO_IS_TMP); diff --git a/sql/ha_handler_stats.h b/sql/ha_handler_stats.h new file mode 100644 index 00000000000..726ba6041dc --- /dev/null +++ b/sql/ha_handler_stats.h @@ -0,0 +1,59 @@ +#ifndef HA_HANDLER_STATS_INCLUDED +#define HA_HANDLER_STATS_INCLUDED +/* + Copyright (c) 2023, MariaDB Foundation + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; version 2 of + the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA +*/ + +/* Definitions for parameters to do with handler-routines */ + +class ha_handler_stats +{ +public: + ulonglong pages_accessed; /* Pages accessed from page cache */ + ulonglong pages_updated; /* Pages changed in page cache */ + ulonglong pages_read_count; /* Pages read from disk */ + ulonglong pages_read_time; /* Time reading pages, in microsec. */ + ulonglong undo_records_read; + ulonglong engine_time; /* Time spent in engine in microsec */ + uint active; /* <> 0 if status has to be updated */ +#define first_stat pages_accessed +#define last_stat engine_time + inline void reset() + { + bzero((void*) this, sizeof(*this)); + } + inline void add(ha_handler_stats *stats) + { + ulonglong *to= &first_stat; + ulonglong *from= &stats->first_stat; + do + { + (*to)+= *from++; + } while (to++ != &last_stat); + } + inline bool has_stats() + { + ulonglong *to= &first_stat; + do + { + if (*to) + return 1; + } while (to++ != &last_stat); + return 0; + } +}; +#endif /* HA_HANDLER_STATS_INCLUDED */ diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index ee78f328503..151f0fcb5e5 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -590,6 +590,7 @@ bool ha_partition::initialize_partition(MEM_ROOT *mem_root) my_error(ER_MIX_HANDLER_ERROR, MYF(0)); DBUG_RETURN(1); } + file->handler_stats= handler_stats; } while (*(++file_array)); m_handler_status= handler_initialized; DBUG_RETURN(0); @@ -4048,6 +4049,13 @@ int ha_partition::discover_check_version() return m_file[0]->discover_check_version(); } +static int set_part_handler_stats(handler *h, void *stats) +{ + h->handler_stats= (ha_handler_stats*) stats; + return 0; +} + + /** Clone the open and locked partitioning handler. @@ -4095,6 +4103,9 @@ handler *ha_partition::clone(const char *name, MEM_ROOT *mem_root) HA_OPEN_IGNORE_IF_LOCKED | HA_OPEN_NO_PSI_CALL)) goto err; + if (handler_stats) + new_handler->loop_partitions(set_part_handler_stats, handler_stats); + DBUG_RETURN((handler*) new_handler); err: @@ -4103,6 +4114,16 @@ err: } +/* + Update all sub partitions to point to handler stats +*/ + +void ha_partition::handler_stats_updated() +{ + loop_partitions(set_part_handler_stats, handler_stats); +} + + /* Close handler object diff --git a/sql/ha_partition.h b/sql/ha_partition.h index f38aa60d1ac..49e212f683d 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1649,5 +1649,6 @@ public: bool can_convert_nocopy(const Field &field, const Column_definition &new_field) const override; + void handler_stats_updated() override; }; #endif /* HA_PARTITION_INCLUDED */ diff --git a/sql/handler.cc b/sql/handler.cc index 85cd06be3e3..b8c6f43288d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -3224,6 +3224,7 @@ handler *handler::clone(const char *name, MEM_ROOT *mem_root) if (new_handler->ha_open(table, name, table->db_stat, HA_OPEN_IGNORE_IF_LOCKED, mem_root)) goto err; + new_handler->handler_stats= handler_stats; return new_handler; diff --git a/sql/handler.h b/sql/handler.h index f4eaa5d612f..b67e66d73c5 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -35,6 +35,7 @@ #include "sql_array.h" /* Dynamic_array<> */ #include "mdl.h" #include "vers_string.h" +#include "ha_handler_stats.h" #include "sql_analyze_stmt.h" // for Exec_time_tracker @@ -3125,13 +3126,23 @@ protected: ha_rows estimation_rows_to_insert; handler *lookup_handler; + /* Statistics for the query. Updated if handler_stats.in_use is set */ + ha_handler_stats active_handler_stats; + void set_handler_stats(); public: handlerton *ht; /* storage engine of this handler */ uchar *ref; /* Pointer to current row */ uchar *dup_ref; /* Pointer to duplicate row */ uchar *lookup_buffer; + /* General statistics for the table like number of row, file sizes etc */ ha_statistics stats; + /* + Collect query stats here if pointer is != NULL. + This is a pointer because if we do a clone of the handler, we want to + use the original handler for collecting statistics. + */ + ha_handler_stats *handler_stats; /** MultiRangeRead-related members: */ range_seq_t mrr_iter; /* Iterator to traverse the range sequence */ @@ -3325,8 +3336,8 @@ public: :table_share(share_arg), table(0), estimation_rows_to_insert(0), lookup_handler(this), - ht(ht_arg), ref(0), lookup_buffer(NULL), end_range(NULL), - implicit_emptied(0), + ht(ht_arg), ref(0), lookup_buffer(NULL), handler_stats(NULL), + end_range(NULL), implicit_emptied(0), mark_trx_read_write_done(0), check_table_binlog_row_based_done(0), check_table_binlog_row_based_result(0), @@ -4758,6 +4769,22 @@ public: { check_table_binlog_row_based_done= 0; } + virtual void handler_stats_updated() {} + + inline void ha_handler_stats_reset() + { + handler_stats= &active_handler_stats; + active_handler_stats.reset(); + active_handler_stats.active= 1; + handler_stats_updated(); + } + inline void ha_handler_stats_disable() + { + handler_stats= 0; + active_handler_stats.active= 0; + handler_stats_updated(); + } + private: /* Cache result to avoid extra calls */ inline void mark_trx_read_write() @@ -5113,6 +5140,7 @@ public: } bool log_not_redoable_operation(const char *operation); + protected: Handler_share *get_ha_share_ptr(); void set_ha_share_ptr(Handler_share *arg_ha_share); diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index a5f6d9307c6..083eb7ba8e7 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -996,7 +996,10 @@ class Item_func_tochar :public Item_str_func bool check_arguments() const override { - return check_argument_types_can_return_text(1, arg_count); + return + (args[0]->check_type_can_return_date(func_name_cstring()) && + args[0]->check_type_can_return_time(func_name_cstring())) || + check_argument_types_can_return_text(1, arg_count); } public: diff --git a/sql/log.cc b/sql/log.cc index 7545d5baed5..b0acc1809b9 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3323,6 +3323,10 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, char buff[80], *end; char query_time_buff[22+7], lock_time_buff[22+7]; size_t buff_len; + ulonglong log_slow_verbosity= thd->variables.log_slow_verbosity; + if (log_slow_verbosity & LOG_SLOW_VERBOSITY_FULL) + log_slow_verbosity= ~(ulonglong) 0; + end= buff; if (!(specialflag & SPECIAL_SHORT_LOG_FORMAT)) @@ -3349,7 +3353,6 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, my_b_write(&log_file, (uchar*) "\n", 1)) goto err; - /* For slow query log */ sprintf(query_time_buff, "%.6f", ulonglong2double(query_utime)/1000000.0); sprintf(lock_time_buff, "%.6f", ulonglong2double(lock_utime)/1000000.0); if (my_b_printf(&log_file, @@ -3365,8 +3368,33 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, (ulong) (thd->status_var.bytes_sent - thd->bytes_sent_old))) goto err; - if ((thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) - && thd->tmp_tables_used && + if (unlikely(log_slow_verbosity & + LOG_SLOW_VERBOSITY_ENGINE) && + thd->handler_stats.has_stats()) + { + ha_handler_stats *stats= &thd->handler_stats; + double tracker_frequency= timer_tracker_frequency(); + sprintf(query_time_buff, "%.4f", + 1000.0 * ulonglong2double(stats->pages_read_time)/ + tracker_frequency); + sprintf(lock_time_buff, "%.4f", + 1000.0 * ulonglong2double(stats->engine_time)/ + tracker_frequency); + + if (my_b_printf(&log_file, + "# Pages_accessed: %lu Pages_read: %lu " + "Pages_updated: %lu Old_rows_read: %lu\n" + "# Pages_read_time: %s Engine_time: %s\n", + (ulong) stats->pages_accessed, + (ulong) stats->pages_read_count, + (ulong) stats->pages_updated, + (ulong) stats->undo_records_read, + query_time_buff, lock_time_buff)) + goto err; + } + + if ((log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) && + thd->tmp_tables_used && my_b_printf(&log_file, "# Tmp_tables: %lu Tmp_disk_tables: %lu " "Tmp_table_sizes: %s\n", @@ -3380,7 +3408,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, ErrConvDQName(thd->spcont->m_sp).ptr())) goto err; - if ((thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) && + if ((log_slow_verbosity & LOG_SLOW_VERBOSITY_QUERY_PLAN) && (thd->query_plan_flags & (QPLAN_FULL_SCAN | QPLAN_FULL_JOIN | QPLAN_TMP_TABLE | QPLAN_TMP_DISK | QPLAN_FILESORT | QPLAN_FILESORT_DISK | @@ -3402,8 +3430,7 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, "Yes" : "No") )) goto err; - if (thd->variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_EXPLAIN && - thd->lex->explain) + if (log_slow_verbosity & LOG_SLOW_VERBOSITY_EXPLAIN && thd->lex->explain) { StringBuffer<128> buf; DBUG_ASSERT(!thd->free_list); diff --git a/sql/log_slow.h b/sql/log_slow.h index c6b3407a811..366906d7cb3 100644 --- a/sql/log_slow.h +++ b/sql/log_slow.h @@ -19,9 +19,15 @@ #define LOG_SLOW_INCLUDED #define LOG_SLOW_VERBOSITY_INIT 0 -#define LOG_SLOW_VERBOSITY_INNODB (1U << 0) +#define LOG_SLOW_VERBOSITY_INNODB (1U << 0) /* Old option */ #define LOG_SLOW_VERBOSITY_QUERY_PLAN (1U << 1) #define LOG_SLOW_VERBOSITY_EXPLAIN (1U << 2) +#define LOG_SLOW_VERBOSITY_STORAGE_ENGINE (1U << 3) /* Replaces InnoDB */ +#define LOG_SLOW_VERBOSITY_FULL (1U << 4) + +#define LOG_SLOW_VERBOSITY_ENGINE (LOG_SLOW_VERBOSITY_FULL | \ + LOG_SLOW_VERBOSITY_INNODB | \ + LOG_SLOW_VERBOSITY_STORAGE_ENGINE) #define QPLAN_INIT QPLAN_QC_NO diff --git a/sql/sp_head.h b/sql/sp_head.h index 5b4aa36e518..97593930b6f 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -620,20 +620,24 @@ public: restore_lex(THD *thd) { DBUG_ENTER("sp_head::restore_lex"); + /* + There is no a need to free the current thd->lex here. + - In the majority of the cases restore_lex() is called + on success and thd->lex does not need to be deleted. + - In cases when restore_lex() is called on error, + e.g. from sp_create_assignment_instr(), thd->lex is + already linked to some sp_instr_xxx (using sp_lex_keeper). + + Note, we don't get to here in case of a syntax error + when the current thd->lex is not yet completely + initialized and linked. It gets automatically deleted + by the Bison %destructor in sql_yacc.yy. + */ LEX *oldlex= (LEX *) m_lex.pop(); if (!oldlex) DBUG_RETURN(false); // Nothing to restore - LEX *sublex= thd->lex; // This restores thd->lex and thd->stmt_lex - if (thd->restore_from_local_lex_to_old_lex(oldlex)) - DBUG_RETURN(true); - if (!sublex->sp_lex_in_use) - { - sublex->sphead= NULL; - lex_end(sublex); - delete sublex; - } - DBUG_RETURN(false); + DBUG_RETURN(thd->restore_from_local_lex_to_old_lex(oldlex)); } /** diff --git a/sql/sql_analyze_stmt.h b/sql/sql_analyze_stmt.h index 30706889eff..d1faa58a273 100644 --- a/sql/sql_analyze_stmt.h +++ b/sql/sql_analyze_stmt.h @@ -35,10 +35,10 @@ log, should the query be slow. 2. Timing data. Measuring the time it took to run parts of query has noticeable overhead. Because of that, we measure the time only when running "ANALYZE $stmt"). - */ /* fake microseconds as cycles if cycles isn't available */ + static inline double timer_tracker_frequency() { #if (MY_TIMER_ROUTINE_CYCLES) @@ -48,6 +48,7 @@ static inline double timer_tracker_frequency() #endif } + class Gap_time_tracker; void attach_gap_time_tracker(THD *thd, Gap_time_tracker *gap_tracker, ulonglong timeval); void process_gap_time_tracker(THD *thd, ulonglong timeval); @@ -75,8 +76,6 @@ protected: { ulonglong end= measure(); cycles += end - last_start; - if (unlikely(end < last_start)) - cycles += ULONGLONG_MAX; process_gap_time_tracker(thd, end); if (my_gap_tracker) @@ -111,13 +110,23 @@ public: // interface for getting the time ulonglong get_loops() const { return count; } - double get_time_ms() const + + inline double cycles_to_ms(ulonglong cycles_arg) const { // convert 'cycles' to milliseconds. - return 1000.0 * static_cast(cycles) / + return 1000.0 * static_cast(cycles_arg) / timer_tracker_frequency(); } + double get_time_ms() const + { + return cycles_to_ms(cycles); + } + ulonglong get_cycles() const + { + return cycles; + } + bool has_timed_statistics() const { return cycles > 0; } }; diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 65c4e232e56..dcdb026bb8c 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -969,11 +969,12 @@ int close_thread_tables(THD *thd) void close_thread_table(THD *thd, TABLE **table_ptr) { TABLE *table= *table_ptr; + handler *file= table->file; DBUG_ENTER("close_thread_table"); DBUG_PRINT("tcache", ("table: '%s'.'%s' %p", table->s->db.str, table->s->table_name.str, table)); - DBUG_ASSERT(!table->file->keyread_enabled()); - DBUG_ASSERT(table->file->inited == handler::NONE); + DBUG_ASSERT(!file->keyread_enabled()); + DBUG_ASSERT(file->inited == handler::NONE); /* The metadata lock must be released after giving back @@ -983,13 +984,20 @@ void close_thread_table(THD *thd, TABLE **table_ptr) table->s->db.str, table->s->table_name.str, MDL_SHARED)); - table->vcol_cleanup_expr(thd); table->mdl_ticket= NULL; - table->file->update_global_table_stats(); - table->file->update_global_index_stats(); - + file->update_global_table_stats(); + file->update_global_index_stats(); + if (unlikely(thd->variables.log_slow_verbosity & + LOG_SLOW_VERBOSITY_ENGINE) && + likely(file->handler_stats)) + { + Exec_time_tracker *tracker; + if ((tracker= file->get_time_tracker())) + file->handler_stats->engine_time+= tracker->get_cycles(); + thd->handler_stats.add(file->handler_stats); + } /* This look is needed to allow THD::notify_shared_lock() to traverse the thd->open_tables list without having to worry that @@ -1003,17 +1011,17 @@ void close_thread_table(THD *thd, TABLE **table_ptr) if (! table->needs_reopen()) { /* Avoid having MERGE tables with attached children in table cache. */ - table->file->extra(HA_EXTRA_DETACH_CHILDREN); + file->extra(HA_EXTRA_DETACH_CHILDREN); /* Free memory and reset for next loop. */ free_field_buffers_larger_than(table, MAX_TDC_BLOB_SIZE); - table->file->ha_reset(); + file->ha_reset(); } /* Do this *before* entering the TABLE_SHARE::tdc.LOCK_table_share critical section. */ - MYSQL_UNBIND_TABLE(table->file); + MYSQL_UNBIND_TABLE(file); tc_release_table(table); DBUG_VOID_RETURN; diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bc1e2362cc7..1f984bc3a72 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5827,6 +5827,7 @@ void THD::store_slow_query_state(Sub_statement_state *backup) backup->tmp_tables_disk_used= tmp_tables_disk_used; backup->tmp_tables_size= tmp_tables_size; backup->tmp_tables_used= tmp_tables_used; + backup->handler_stats= handler_stats; } /* Reset variables related to slow query log */ @@ -5842,6 +5843,8 @@ void THD::reset_slow_query_state() tmp_tables_disk_used= 0; tmp_tables_size= 0; tmp_tables_used= 0; + if ((variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_ENGINE)) + handler_stats.reset(); } /* @@ -5860,6 +5863,8 @@ void THD::add_slow_query_state(Sub_statement_state *backup) tmp_tables_disk_used+= backup->tmp_tables_disk_used; tmp_tables_size+= backup->tmp_tables_size; tmp_tables_used+= backup->tmp_tables_used; + if ((variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_ENGINE)) + handler_stats.add(&backup->handler_stats); } diff --git a/sql/sql_class.h b/sql/sql_class.h index cd365a89706..5536675ebde 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -51,6 +51,7 @@ #include "backup.h" #include "xa.h" #include "ddl_log.h" /* DDL_LOG_STATE */ +#include "ha_handler_stats.h" // ha_handler_stats */ extern "C" void set_thd_stage_info(void *thd, @@ -1855,6 +1856,7 @@ public: ulonglong cuted_fields, sent_row_count, examined_row_count; ulonglong affected_rows; ulonglong bytes_sent_old; + ha_handler_stats handler_stats; ulong tmp_tables_used; ulong tmp_tables_disk_used; ulong query_plan_fsort_passes; @@ -2692,6 +2694,7 @@ public: struct system_status_var status_var; // Per thread statistic vars struct system_status_var org_status_var; // For user statistics struct system_status_var *initial_status_var; /* used by show status */ + ha_handler_stats handler_stats; // Handler statistics THR_LOCK_INFO lock_info; // Locking info of this thread /** Protects THD data accessed from other threads: @@ -5604,6 +5607,12 @@ public: lex= backup_lex; } + bool should_collect_handler_stats() const + { + return (variables.log_slow_verbosity & LOG_SLOW_VERBOSITY_ENGINE) || + lex->analyze_stmt; + } + bool vers_insert_history_fast(const TABLE *table) { DBUG_ASSERT(table->versioned()); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 186ab64f5d3..af6c65cd067 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -56,7 +56,7 @@ invoked on a running DELETE statement. */ -Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *thd) +Explain_delete* Delete_plan::save_explain_delete_data(THD *thd, MEM_ROOT *mem_root) { Explain_query *query= thd->lex->explain; Explain_delete *explain= @@ -73,7 +73,7 @@ Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *t else { explain->deleting_all_rows= false; - if (Update_plan::save_explain_data_intern(mem_root, explain, + if (Update_plan::save_explain_data_intern(thd, mem_root, explain, thd->lex->analyze_stmt)) return 0; } @@ -84,21 +84,22 @@ Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *t Explain_update* -Update_plan::save_explain_update_data(MEM_ROOT *mem_root, THD *thd) +Update_plan::save_explain_update_data(THD *thd, MEM_ROOT *mem_root) { Explain_query *query= thd->lex->explain; Explain_update* explain= new (mem_root) Explain_update(mem_root, thd->lex->analyze_stmt); if (!explain) return 0; - if (save_explain_data_intern(mem_root, explain, thd->lex->analyze_stmt)) + if (save_explain_data_intern(thd, mem_root, explain, thd->lex->analyze_stmt)) return 0; query->add_upd_del_plan(explain); return explain; } -bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root, +bool Update_plan::save_explain_data_intern(THD *thd, + MEM_ROOT *mem_root, Explain_update *explain, bool is_analyze) { @@ -120,9 +121,13 @@ bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root, return 0; } - if (is_analyze) + if (is_analyze || + (thd->variables.log_slow_verbosity & + LOG_SLOW_VERBOSITY_ENGINE)) table->file->set_time_tracker(&explain->table_tracker); + explain->handler_for_stats= table->file; + select_lex->set_explain_type(TRUE); explain->select_type= select_lex->type; /* Partitions */ @@ -474,7 +479,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, query_type= THD::STMT_QUERY_TYPE; error= -1; deleted= maybe_deleted; - if (!query_plan.save_explain_delete_data(thd->mem_root, thd)) + if (!query_plan.save_explain_delete_data(thd, thd->mem_root)) error= 1; goto cleanup; } @@ -602,7 +607,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, if (thd->lex->describe) goto produce_explain_and_leave; - if (!(explain= query_plan.save_explain_delete_data(thd->mem_root, thd))) + if (!(explain= query_plan.save_explain_delete_data(thd, thd->mem_root))) goto got_error; ANALYZE_START_TRACKING(thd, &explain->command_tracker); @@ -990,7 +995,7 @@ produce_explain_and_leave: We come here for various "degenerate" query plans: impossible WHERE, no-partitions-used, impossible-range, etc. */ - if (!(query_plan.save_explain_delete_data(thd->mem_root, thd))) + if (!(query_plan.save_explain_delete_data(thd, thd->mem_root))) goto got_error; send_nothing_and_leave: diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 60965305b3f..56331313853 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -1823,6 +1823,26 @@ void Explain_rowid_filter::print_explain_json(Explain_query *query, writer->end_object(); // rowid_filter } +static void trace_engine_stats(handler *file, Json_writer *writer) +{ + if (file && file->handler_stats) + { + ha_handler_stats *hs= file->handler_stats; + writer->add_member("r_engine_stats").start_object(); + if (hs->pages_accessed) + writer->add_member("pages_accessed").add_ull(hs->pages_accessed); + if (hs->pages_updated) + writer->add_member("pages_updated").add_ull(hs->pages_updated); + if (hs->pages_read_count) + writer->add_member("pages_read_count").add_ull(hs->pages_read_count); + if (hs->pages_read_time) + writer->add_member("pages_read_time_ms"). + add_double(hs->pages_read_time / 1000.0); + if (hs->undo_records_read) + writer->add_member("old_rows_read").add_ull(hs->undo_records_read); + writer->end_object(); + } +} void Explain_table_access::print_explain_json(Explain_query *query, Json_writer *writer, @@ -1964,6 +1984,7 @@ void Explain_table_access::print_explain_json(Explain_query *query, writer->add_member("r_table_time_ms").add_double(total_time); writer->add_member("r_other_time_ms").add_double(extra_time_tracker.get_time_ms()); } + trace_engine_stats(handler_for_stats, writer); } /* `filtered` */ @@ -2668,6 +2689,8 @@ void Explain_update::print_explain_json(Explain_query *query, } } + trace_engine_stats(handler_for_stats, writer); + if (where_cond) { writer->add_member("attached_condition"); diff --git a/sql/sql_explain.h b/sql/sql_explain.h index c2625c14b51..dbb3ce817bb 100644 --- a/sql/sql_explain.h +++ b/sql/sql_explain.h @@ -766,6 +766,7 @@ public: pushed_index_cond(NULL), sjm_nest(NULL), pre_join_sort(NULL), + handler_for_stats(NULL), jbuf_unpack_tracker(timed), rowid_filter(NULL) {} @@ -874,6 +875,16 @@ public: Exec_time_tracker op_tracker; Gap_time_tracker extra_time_tracker; + /* + Note: This pointer is only valid until notify_tables_are_closed() is + called. After that, the tables may be freed or reused, together with their + handler_stats objects. + + notify_tables_are_closed() disables printing of FORMAT=JSON output. + r_engine_stats is only printed in FORMAT=JSON output, so we're fine. + */ + handler *handler_for_stats; + /* When using join buffer: Track the reads from join buffer */ Table_access_tracker jbuf_tracker; @@ -925,7 +936,8 @@ public: Explain_update(MEM_ROOT *root, bool is_analyze) : Explain_node(root), filesort_tracker(NULL), - command_tracker(is_analyze) + command_tracker(is_analyze), + handler_for_stats(NULL) {} virtual enum explain_node_type get_type() { return EXPLAIN_UPDATE; } @@ -985,6 +997,9 @@ public: /* TODO: This tracks time to read rows from the table */ Exec_time_tracker table_tracker; + /* The same as Explain_table_access::handler_for_stats */ + handler *handler_for_stats; + virtual int print_explain(Explain_query *query, select_result_sink *output, uint8 explain_flags, bool is_analyze); virtual void print_explain_json(Explain_query *query, Json_writer *writer, diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 588bfa95ead..019e4c5e23a 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -486,11 +486,15 @@ bool sp_create_assignment_instr(THD *thd, bool no_lookahead, be deleted by the destructor ~sp_instr_xxx(). So we should remove "lex" from the stack sp_head::m_lex, to avoid double free. - Note, in case "lex" is not owned by any sp_instr_xxx, - it's also safe to remove it from the stack right now. - So we can remove it unconditionally, without testing lex->sp_lex_in_use. */ lex->sphead->restore_lex(thd); + /* + No needs for "delete lex" here: "lex" is already linked + to the sp_instr_stmt (using sp_lex_keeper) instance created by + the call for new_sp_instr_stmt() above. It will be freed + by ~sp_head/~sp_instr/~sp_lex_keeper during THD::end_statement(). + */ + DBUG_ASSERT(lex->sp_lex_in_use); // used by sp_instr_stmt return true; } enum_var_type inner_option_type= lex->option_type; @@ -3939,7 +3943,8 @@ void Query_tables_list::destroy_query_tables_list() LEX::LEX() : explain(NULL), result(0), part_info(NULL), arena_for_set_stmt(0), - mem_root_for_set_stmt(0), json_table(NULL), default_used(0), + mem_root_for_set_stmt(0), json_table(NULL), analyze_stmt(0), + default_used(0), with_rownum(0), is_lex_started(0), option_type(OPT_DEFAULT), context_analysis_only(0), sphead(0), limit_rows_examined_cnt(ULONGLONG_MAX) { @@ -6831,7 +6836,6 @@ bool LEX::sp_for_loop_implicit_cursor_statement(THD *thd, if (unlikely(!(bounds->m_index= new (thd->mem_root) sp_assignment_lex(thd, this)))) return true; - bounds->m_index->sp_lex_in_use= true; sphead->reset_lex(thd, bounds->m_index); DBUG_ASSERT(thd->lex != this); /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index a7231b92cd6..03f12fe19fc 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -3014,9 +3014,9 @@ public: void set_impossible_where() { impossible_where= true; } void set_no_partitions() { no_partitions= true; } - Explain_update* save_explain_update_data(MEM_ROOT *mem_root, THD *thd); + Explain_update* save_explain_update_data(THD *thd, MEM_ROOT *mem_root); protected: - bool save_explain_data_intern(MEM_ROOT *mem_root, Explain_update *eu, bool is_analyze); + bool save_explain_data_intern(THD *thd, MEM_ROOT *mem_root, Explain_update *eu, bool is_analyze); public: virtual ~Update_plan() = default; @@ -3051,7 +3051,7 @@ public: deleting_all_rows= false; } - Explain_delete* save_explain_delete_data(MEM_ROOT *mem_root, THD *thd); + Explain_delete* save_explain_delete_data(THD *thd, MEM_ROOT *mem_root); }; enum account_lock_type @@ -3476,6 +3476,12 @@ public: sp_head *sphead; sp_name *spname; + void delete_if_not_sp_lex_in_use() + { + if (!sp_lex_in_use) + delete this; + } + sp_pcontext *spcont; st_sp_chistics sp_chistics; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 607877dfb83..d2d4c214a09 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -10380,6 +10380,15 @@ bool parse_sql(THD *thd, Parser_state *parser_state, bool mysql_parse_status= thd->variables.sql_mode & MODE_ORACLE ? ORAparse(thd) : MYSQLparse(thd); + + if (mysql_parse_status) + /* + Restore the original LEX if it was replaced when parsing + a stored procedure. We must ensure that a parsing error + does not leave any side effects in the THD. + */ + LEX::cleanup_lex_after_parse_error(thd); + DBUG_ASSERT(opt_bootstrap || mysql_parse_status || thd->lex->select_stack_top == 0); thd->lex->current_select= thd->lex->first_select_lex(); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index b18b4b49ca9..8279df0ecc5 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -26012,7 +26012,8 @@ cp_buffer_from_ref(THD *thd, TABLE *table, TABLE_REF *ref) thd->count_cuted_fields= CHECK_FIELD_IGNORE; for (store_key **copy=ref->key_copy ; *copy ; copy++) { - if ((*copy)->copy(thd) & 1) + if ((*copy)->copy(thd) & 1 || + (ref->null_rejecting && (*copy)->null_key)) { result= 1; break; @@ -28231,12 +28232,22 @@ bool JOIN_TAB::save_explain_data(Explain_table_access *eta, jbuf_unpack_tracker= &eta->jbuf_unpack_tracker; /* Enable the table access time tracker only for "ANALYZE stmt" */ - if (thd->lex->analyze_stmt) + if (unlikely(thd->lex->analyze_stmt || + thd->variables.log_slow_verbosity & + LOG_SLOW_VERBOSITY_ENGINE)) { table->file->set_time_tracker(&eta->op_tracker); - eta->op_tracker.set_gap_tracker(&eta->extra_time_tracker); - - eta->jbuf_unpack_tracker.set_gap_tracker(&eta->jbuf_extra_time_tracker); + /* + Set handler_for_stats even if we are not running an ANALYZE command. + There's no harm, and in case somebody runs a SHOW ANALYZE command we'll + be able to print the engine statistics. + */ + eta->handler_for_stats= table->file; + if (likely(thd->lex->analyze_stmt)) + { + eta->op_tracker.set_gap_tracker(&eta->extra_time_tracker); + eta->jbuf_unpack_tracker.set_gap_tracker(&eta->jbuf_extra_time_tracker); + } } /* No need to save id and select_type here, they are kept in Explain_select */ diff --git a/sql/sql_string.cc b/sql/sql_string.cc index 7a8aa4ef0f4..208805b91ba 100644 --- a/sql/sql_string.cc +++ b/sql/sql_string.cc @@ -677,7 +677,7 @@ bool String::append_with_prefill(const char *s,uint32 arg_length, } -int Binary_string::strstr(const char *search, uint32 search_length, uint32 offset) +int Binary_string::strstr(const char *search, uint32 search_length, uint32 offset) const { if (search_length + offset <= str_length) { @@ -703,7 +703,7 @@ skip: return -1; } -int Binary_string::strstr(const Binary_string &s, uint32 offset) +int Binary_string::strstr(const Binary_string &s, uint32 offset) const { return strstr(s.ptr(), s.length(), offset); } @@ -712,7 +712,7 @@ int Binary_string::strstr(const Binary_string &s, uint32 offset) ** Search string from end. Offset is offset to the end of string */ -int Binary_string::strrstr(const Binary_string &s, uint32 offset) +int Binary_string::strrstr(const Binary_string &s, uint32 offset) const { if (s.length() <= offset && offset <= str_length) { diff --git a/sql/sql_string.h b/sql/sql_string.h index dbb4760ab34..d112a8842b9 100644 --- a/sql/sql_string.h +++ b/sql/sql_string.h @@ -406,10 +406,10 @@ public: } // Returns offset to substring or -1 - int strstr(const Binary_string &search, uint32 offset=0); - int strstr(const char *search, uint32 search_length, uint32 offset=0); + int strstr(const Binary_string &search, uint32 offset=0) const; + int strstr(const char *search, uint32 search_length, uint32 offset=0) const; // Returns offset to substring or -1 - int strrstr(const Binary_string &search, uint32 offset=0); + int strrstr(const Binary_string &search, uint32 offset=0) const; /* The following append operations do not extend the strings and in production diff --git a/sql/sql_table.cc b/sql/sql_table.cc index a510de15027..d59fe54e698 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -12532,7 +12532,9 @@ bool HA_CREATE_INFO:: else { // Make sure we don't do double resolution in direct SQL execution - DBUG_ASSERT(!default_table_charset || thd->stmt_arena->is_stmt_execute()); + DBUG_ASSERT(!default_table_charset || + thd->stmt_arena->is_stmt_execute() || + thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP); if (!(default_table_charset= default_cscl.resolved_to_context(ctx))) return true; @@ -12544,7 +12546,8 @@ bool HA_CREATE_INFO:: { // Make sure we don't do double resolution in direct SQL execution DBUG_ASSERT(!alter_table_convert_to_charset || - thd->stmt_arena->is_stmt_execute()); + thd->stmt_arena->is_stmt_execute() || + thd->stmt_arena->state == Query_arena::STMT_INITIALIZED_FOR_SP); if (!(alter_table_convert_to_charset= convert_cscl.resolved_to_context(ctx))) return true; diff --git a/sql/sql_type.cc b/sql/sql_type.cc index 269532e2390..07161f3e810 100644 --- a/sql/sql_type.cc +++ b/sql/sql_type.cc @@ -94,10 +94,6 @@ Vers_type_trx vers_type_trx; class Type_collection_std: public Type_collection { public: - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - return NULL; - } const Type_handler *aggregate_for_result(const Type_handler *a, const Type_handler *b) const override @@ -137,10 +133,6 @@ public: { return false; } - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - return NULL; - } const Type_handler *aggregate_for_result(const Type_handler *a, const Type_handler *b) const override @@ -212,7 +204,7 @@ Type_handler::handler_by_name(THD *thd, const LEX_CSTRING &name) } #ifdef HAVE_SPATIAL - const Type_handler *ha= type_collection_geometry.handler_by_name(name); + const Type_handler *ha= Type_collection_geometry_handler_by_name(name); if (ha) return ha; #endif diff --git a/sql/sql_type.h b/sql/sql_type.h index 8ebdb38db49..b39157c3706 100644 --- a/sql/sql_type.h +++ b/sql/sql_type.h @@ -3384,17 +3384,12 @@ public: class Name: private LEX_CSTRING { public: - Name(const char *str_arg, uint length_arg) - { - DBUG_ASSERT(length_arg < UINT_MAX32); - LEX_CSTRING::str= str_arg; - LEX_CSTRING::length= length_arg; - } - Name(const LEX_CSTRING &lcs) - { - LEX_CSTRING::str= lcs.str; - LEX_CSTRING::length= lcs.length; - } + constexpr Name(const char *str_arg, uint length_arg) : + LEX_CSTRING({str_arg, length_arg}) + { } + constexpr Name(const LEX_CSTRING &lcs) : + LEX_CSTRING(lcs) + { } const char *ptr() const { return LEX_CSTRING::str; } uint length() const { return (uint) LEX_CSTRING::length; } const LEX_CSTRING &lex_cstring() const { return *this; } @@ -7396,7 +7391,6 @@ class Type_collection public: virtual ~Type_collection() = default; virtual bool init(Type_handler_data *) { return false; } - virtual const Type_handler *handler_by_name(const LEX_CSTRING &name) const= 0; virtual const Type_handler *aggregate_for_result(const Type_handler *h1, const Type_handler *h2) const= 0; diff --git a/sql/sql_type_fixedbin.h b/sql/sql_type_fixedbin.h index 852ec1269eb..2a2cc1e1ff6 100644 --- a/sql/sql_type_fixedbin.h +++ b/sql/sql_type_fixedbin.h @@ -31,9 +31,13 @@ /***********************************************************************/ -template -class FixedBinTypeBundle +template class Type_collection_fbt; + +template > +class Type_handler_fbt: public Type_handler { + /* =[ internal helper classes ]=============================== */ + public: class Fbt: public FbtImpl { @@ -41,7 +45,7 @@ public: using FbtImpl::m_buffer; bool make_from_item(Item *item, bool warn) { - if (item->type_handler() == type_handler_fbt()) + if (item->type_handler() == singleton()) { Native tmp(m_buffer, sizeof(m_buffer)); bool rc= item->val_native(current_thd, &tmp); @@ -78,14 +82,14 @@ public: str->charset()); if (rc && warn) current_thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, - type_handler_fbt()->name().ptr(), ErrConvString(str).ptr()); + singleton()->name().ptr(), ErrConvString(str).ptr()); return rc; } if (str->length() != sizeof(m_buffer)) { if (warn) current_thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, - type_handler_fbt()->name().ptr(), ErrConvString(str).ptr()); + singleton()->name().ptr(), ErrConvString(str).ptr()); return true; } DBUG_ASSERT(str->ptr() != m_buffer); @@ -125,7 +129,7 @@ public: { if (item->maybe_null()) return true; - if (item->type_handler() == type_handler_fbt()) + if (item->type_handler() == singleton()) return false; if (!item->const_item() || item->is_expensive()) return true; @@ -200,16 +204,14 @@ public: { return to_fbt().to_binary(to); } - size_t to_string(char *dst, size_t dstsize) const - { - return to_fbt().to_string(dst, dstsize); - } bool to_string(String *to) const { return to_fbt().to_string(to); } }; + /* =[ API classes ]=========================================== */ + class Type_std_attributes_fbt: public Type_std_attributes { public: @@ -220,847 +222,66 @@ public: { } }; - class Type_handler_fbt: public Type_handler + class Item_literal_fbt: public Item_literal { - bool character_or_binary_string_to_native(THD *thd, const String *str, - Native *to) const - { - if (str->charset() == &my_charset_bin) - { - // Convert from a binary string - if (str->length() != FbtImpl::binary_length() || - to->copy(str->ptr(), str->length())) - { - thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, - name().ptr(), ErrConvString(str).ptr()); - return true; - } - return false; - } - // Convert from a character string - Fbt_null tmp(*str); - if (tmp.is_null()) - thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, - name().ptr(), ErrConvString(str).ptr()); - return tmp.is_null() || tmp.to_native(to); - } - + Fbt m_value; public: - ~Type_handler_fbt() override {} - - const Type_collection *type_collection() const override + Item_literal_fbt(THD *thd) + :Item_literal(thd), + m_value(Fbt::zero()) + { } + Item_literal_fbt(THD *thd, const Fbt &value) + :Item_literal(thd), + m_value(value) + { } + const Type_handler *type_handler() const override { - static Type_collection_fbt type_collection_fbt; - return &type_collection_fbt; + return singleton(); } - - const Name &default_value() const override - { - return FbtImpl::default_value(); - } - ulong KEY_pack_flags(uint column_nr) const override - { - return FbtImpl::KEY_pack_flags(column_nr); - } - protocol_send_type_t protocol_send_type() const override - { - return PROTOCOL_SEND_STRING; - } - bool Item_append_extended_type_info(Send_field_extended_metadata *to, - const Item *item) const override - { - return to->set_data_type_name(name().lex_cstring()); - } - - enum_field_types field_type() const override - { - return MYSQL_TYPE_STRING; - } - - Item_result result_type() const override - { - return STRING_RESULT; - } - - Item_result cmp_type() const override - { - return STRING_RESULT; - } - - enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) - const override - { - return DYN_COL_STRING; - } - - uint32 max_display_length_for_field(const Conv_source &src) const override - { - return FbtImpl::max_char_length(); - } - - const Type_handler *type_handler_for_comparison() const override - { - return this; - } - - int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const override - { - DBUG_ASSERT(field->type_handler() == this); - Fbt_null ni(item); // Convert Item to Fbt - if (ni.is_null()) - return 0; - NativeBuffer tmp; - if (field->val_native(&tmp)) - { - DBUG_ASSERT(0); - return 0; - } - return -ni.cmp(tmp); - } - CHARSET_INFO *charset_for_protocol(const Item *item) const override - { - return item->collation.collation; - } - - bool is_scalar_type() const override { return true; } - bool is_val_native_ready() const override { return true; } - bool can_return_int() const override { return false; } - bool can_return_decimal() const override { return false; } - bool can_return_real() const override { return false; } - bool can_return_str() const override { return true; } - bool can_return_text() const override { return true; } - bool can_return_date() const override { return false; } - bool can_return_time() const override { return false; } - bool convert_to_binary_using_val_native() const override { return true; } - - decimal_digits_t Item_time_precision(THD *thd, Item *item) const override + longlong val_int() override { return 0; } - decimal_digits_t Item_datetime_precision(THD *thd, Item *item) const override + double val_real() override { return 0; } - decimal_digits_t Item_decimal_scale(const Item *item) const override + String *val_str(String *to) override { - return 0; + return m_value.to_string(to) ? NULL : to; } - decimal_digits_t Item_decimal_precision(const Item *item) const override + my_decimal *val_decimal(my_decimal *to) override { - /* This will be needed if we ever allow cast from Fbt to DECIMAL. */ - return (FbtImpl::binary_length()*8+7)/10*3; // = bytes to decimal digits + my_decimal_set_zero(to); + return to; } - - /* - Returns how many digits a divisor adds into a division result. - See Item::divisor_precision_increment() in item.h for more comments. - */ - decimal_digits_t Item_divisor_precision_increment(const Item *) const override - { - return 0; - } - /** - Makes a temporary table Field to handle numeric aggregate functions, - e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc. - */ - Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const override - { - DBUG_ASSERT(0); - return 0; - } - Field *make_conversion_table_field(MEM_ROOT *root, TABLE *table, uint metadata, - const Field *target) const override - { - const Record_addr tmp(NULL, Bit_addr(true)); - return new (table->in_use->mem_root) Field_fbt(&empty_clex_str, tmp); - } - // Fix attributes after the parser - bool Column_definition_fix_attributes(Column_definition *c) const override - { - c->length= FbtImpl::max_char_length(); - return false; - } - - bool Column_definition_prepare_stage1(THD *thd, MEM_ROOT *mem_root, - Column_definition *def, - column_definition_type_t type, - const Column_derived_attributes *derived_attr) - const override - { - def->prepare_stage1_simple(&my_charset_numeric); - return false; - } - - bool Column_definition_redefine_stage1(Column_definition *def, - const Column_definition *dup, - const handler *file) const override - { - def->redefine_stage1_common(dup, file); - def->set_compression_method(dup->compression_method()); - def->create_length_to_internal_length_string(); - return false; - } - - bool Column_definition_prepare_stage2(Column_definition *def, handler *file, - ulonglong table_flags) const override - { - def->pack_flag= FIELDFLAG_BINARY; - return false; - } - - bool partition_field_check(const LEX_CSTRING &field_name, - Item *item_expr) const override - { - if (item_expr->cmp_type() != STRING_RESULT) - { - my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0)); - return true; - } - return false; - } - - bool partition_field_append_value(String *to, Item *item_expr, - CHARSET_INFO *field_cs, - partition_value_print_mode_t mode) - const override - { - StringBuffer fbtstr; - Fbt_null fbt(item_expr); - if (fbt.is_null()) - { - my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); - return true; - } - return fbt.to_string(&fbtstr) || - to->append('\'') || - to->append(fbtstr) || - to->append('\''); - } - - Field *make_table_field(MEM_ROOT *root, const LEX_CSTRING *name, - const Record_addr &addr, - const Type_all_attributes &attr, - TABLE_SHARE *table) const override - { - return new (root) Field_fbt(name, addr); - } - - Field * make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root, - const LEX_CSTRING *name, const Record_addr &addr, - const Bit_addr &bit, - const Column_definition_attributes *attr, - uint32 flags) const override - { - return new (mem_root) Field_fbt(name, addr); - } - void Column_definition_attributes_frm_pack(const Column_definition_attributes *def, - uchar *buff) const override - { - def->frm_pack_basic(buff); - def->frm_pack_charset(buff); - } - bool Column_definition_attributes_frm_unpack(Column_definition_attributes *def, - TABLE_SHARE *share, const uchar *buffer, - LEX_CUSTRING *gis_options) - const override - { - def->frm_unpack_basic(buffer); - return def->frm_unpack_charset(share, buffer); - } - void make_sort_key_part(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, - String *) const override - { - DBUG_ASSERT(item->type_handler() == this); - NativeBuffer tmp; - item->val_native_result(current_thd, &tmp); - if (item->maybe_null()) - { - if (item->null_value) - { - memset(to, 0, FbtImpl::binary_length() + 1); - return; - } - *to++= 1; - } - DBUG_ASSERT(!item->null_value); - DBUG_ASSERT(FbtImpl::binary_length() == tmp.length()); - DBUG_ASSERT(FbtImpl::binary_length() == sort_field->length); - FbtImpl::memory_to_record((char*) to, tmp.ptr()); - } - uint make_packed_sort_key_part(uchar *to, Item *item, - const SORT_FIELD_ATTR *sort_field, - String *) const override - { - DBUG_ASSERT(item->type_handler() == this); - NativeBuffer tmp; - item->val_native_result(current_thd, &tmp); - if (item->maybe_null()) - { - if (item->null_value) - { - *to++=0; - return 0; - } - *to++= 1; - } - DBUG_ASSERT(!item->null_value); - DBUG_ASSERT(FbtImpl::binary_length() == tmp.length()); - DBUG_ASSERT(FbtImpl::binary_length() == sort_field->length); - FbtImpl::memory_to_record((char*) to, tmp.ptr()); - return tmp.length(); - } - void sort_length(THD *thd, const Type_std_attributes *item, - SORT_FIELD_ATTR *attr) const override - { - attr->original_length= attr->length= FbtImpl::binary_length(); - attr->suffix_length= 0; - } - uint32 max_display_length(const Item *item) const override - { - return FbtImpl::max_char_length(); - } - uint32 calc_pack_length(uint32 length) const override - { - return FbtImpl::binary_length(); - } - void Item_update_null_value(Item *item) const override - { - NativeBuffer tmp; - item->val_native(current_thd, &tmp); - } - bool Item_save_in_value(THD *thd, Item *item, st_value *value) const override - { - value->m_type= DYN_COL_STRING; - String *str= item->val_str(&value->m_string); - if (str != &value->m_string && !item->null_value) - { - // "item" returned a non-NULL value - if (Fbt_null(*str).is_null()) - { - /* - The value was not-null, but conversion to FBT failed: - SELECT a, DECODE_ORACLE(fbtcol, 'garbage', '', '::01', '01') - FROM t1; - */ - thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, - name().ptr(), ErrConvString(str).ptr()); - value->m_type= DYN_COL_NULL; - return true; - } - // "item" returned a non-NULL value, and it was a valid FBT - value->m_string.set(str->ptr(), str->length(), str->charset()); - } - return check_null(item, value); - } - void Item_param_setup_conversion(THD *thd, Item_param *param) const override - { - param->setup_conversion_string(thd, thd->variables.character_set_client); - } - void Item_param_set_param_func(Item_param *param, - uchar **pos, ulong len) const override - { - param->set_param_str(pos, len); - } - bool Item_param_set_from_value(THD *thd, Item_param *param, - const Type_all_attributes *attr, - const st_value *val) const override - { - param->unsigned_flag= false; - param->setup_conversion_string(thd, attr->collation.collation); - /* - Exact value of max_length is not known unless fbt is converted to - charset of connection, so we have to set it later. - */ - return param->set_str(val->m_string.ptr(), val->m_string.length(), - attr->collation.collation, - attr->collation.collation); - } - bool Item_param_val_native(THD *thd, Item_param *item, Native *to) - const override - { - StringBuffer buffer; - String *str= item->val_str(&buffer); - if (!str) - return true; - Fbt_null tmp(*str); - return tmp.is_null() || tmp.to_native(to); - } - bool Item_send(Item *item, Protocol *p, st_value *buf) const override - { - return Item_send_str(item, p, buf); - } - int Item_save_in_field(Item *item, Field *field, bool no_conversions) - const override - { - if (field->type_handler() == this) - { - NativeBuffer tmp; - bool rc= item->val_native(current_thd, &tmp); - if (rc || item->null_value) - return set_field_to_null_with_conversions(field, no_conversions); - field->set_notnull(); - return field->store_native(tmp); - } - return item->save_str_in_field(field, no_conversions); - } - - String *print_item_value(THD *thd, Item *item, String *str) const override - { - StringBuffer buf; - String *result= item->val_str(&buf); - /* - TODO: This should eventually use one of these notations: - 1. CAST('xxx' AS Fbt) - Problem: CAST is not supported as a NAME_CONST() argument. - 2. Fbt'xxx' - Problem: This syntax is not supported by the parser yet. - */ - return !result || str->realloc(result->length() + 2) || - str->append(STRING_WITH_LEN("'")) || - str->append(result->ptr(), result->length()) || - str->append(STRING_WITH_LEN("'")) ? nullptr : str; - } - - /** - Check if - WHERE expr=value AND expr=const - can be rewritten as: - WHERE const=value AND expr=const - - "this" is the comparison handler that is used by "target". - - @param target - the predicate expr=value, - whose "expr" argument will be replaced to "const". - @param target_expr - the target's "expr" which will be replaced to "const". - @param target_value - the target's second argument, it will remain unchanged. - @param source - the equality predicate expr=const (or expr<=>const) - that can be used to rewrite the "target" part - (under certain conditions, see the code). - @param source_expr - the source's "expr". It should be exactly equal to - the target's "expr" to make condition rewrite possible. - @param source_const - the source's "const" argument, it will be inserted - into "target" instead of "expr". - */ - bool can_change_cond_ref_to_const(Item_bool_func2 *target, Item *target_expr, - Item *target_value, Item_bool_func2 *source, - Item *source_expr, Item *source_const) - const override - { - /* - WHERE COALESCE(col)='xxx' AND COALESCE(col)=CONCAT(a); --> - WHERE COALESCE(col)='xxx' AND 'xxx'=CONCAT(a); - */ - return target->compare_type_handler() == source->compare_type_handler(); - } - bool subquery_type_allows_materialization(const Item *inner, - const Item *outer, bool) const override - { - /* - Example: - SELECT * FROM t1 WHERE a IN (SELECT col FROM t1 GROUP BY col); - Allow materialization only if the outer column is also FBT. - This can be changed for more relaxed rules in the future. - */ - DBUG_ASSERT(inner->type_handler() == this); - return outer->type_handler() == this; - } - /** - Make a simple constant replacement item for a constant "src", - so the new item can futher be used for comparison with "cmp", e.g.: - src = cmp -> replacement = cmp - - "this" is the type handler that is used to compare "src" and "cmp". - - @param thd - current thread, for mem_root - @param src - The item that we want to replace. It's a const item, - but it can be complex enough to calculate on every row. - @param cmp - The src's comparand. - @retval - a pointer to the created replacement Item - @retval - NULL, if could not create a replacement (e.g. on EOM). - NULL is also returned for ROWs, because instead of replacing - a Item_row to a new Item_row, Type_handler_row just replaces - its elements. - */ - Item *make_const_item_for_comparison(THD *thd, Item *src, - const Item *cmp) const override - { - Fbt_null tmp(src); - if (tmp.is_null()) - return new (thd->mem_root) Item_null(thd, src->name.str); - return new (thd->mem_root) Item_literal_fbt(thd, tmp); - } - Item_cache *Item_get_cache(THD *thd, const Item *item) const override - { - return new (thd->mem_root) Item_cache_fbt(thd); - } - - Item *create_typecast_item(THD *thd, Item *item, - const Type_cast_attributes &attr) const override - { - return new (thd->mem_root) Item_typecast_fbt(thd, item); - } - Item_copy *create_item_copy(THD *thd, Item *item) const override - { - return new (thd->mem_root) Item_copy_fbt(thd, item); - } - int cmp_native(const Native &a, const Native &b) const override - { - return FbtImpl::cmp(a.to_lex_cstring(), b.to_lex_cstring()); - } - bool set_comparator_func(THD *thd, Arg_comparator *cmp) const override - { - return cmp->set_cmp_func_native(thd); - } - bool Item_const_eq(const Item_const *a, const Item_const *b, - bool binary_cmp) const override - { - return false; - } - bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr, - Item *a, Item *b) const override - { - Fbt_null na(a), nb(b); - return !na.is_null() && !nb.is_null() && !na.cmp(nb); - } - bool Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name, - Type_handler_hybrid_field_type *h, - Type_all_attributes *attr, - Item **items, uint nitems) const override - { - attr->Type_std_attributes::operator=(Type_std_attributes_fbt()); - h->set_handler(this); - /* - If some of the arguments cannot be safely converted to "FBT NOT NULL", - then mark the entire function nullability as NULL-able. - Otherwise, keep the generic nullability calculated by earlier stages: - - either by the most generic way in Item_func::fix_fields() - - or by Item_func_xxx::fix_length_and_dec() before the call of - Item_hybrid_func_fix_attributes() - IFNULL() is special. It does not need to test args[0]. - */ - uint first= dynamic_cast(attr) ? 1 : 0; - for (uint i= first; i < nitems; i++) - { - if (Fbt::fix_fields_maybe_null_on_conversion_to_fbt(items[i])) - { - attr->set_type_maybe_null(true); - break; - } - } - return false; - } - bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, - Item **items, uint nitems) const override - { - return Item_hybrid_func_fix_attributes(thd, func->func_name_cstring(), - func, func, items, nitems); - - } - bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const override - { - func->Type_std_attributes::operator=(Type_std_attributes_fbt()); - func->set_handler(this); - return false; - } - bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - - bool Item_val_native_with_conversion(THD *thd, Item *item, - Native *to) const override - { - if (item->type_handler() == this) - return item->val_native(thd, to); // No conversion needed - StringBuffer buffer; - String *str= item->val_str(&buffer); - return str ? character_or_binary_string_to_native(thd, str, to) : true; - } - bool Item_val_native_with_conversion_result(THD *thd, Item *item, - Native *to) const override - { - if (item->type_handler() == this) - return item->val_native_result(thd, to); // No conversion needed - StringBuffer buffer; - String *str= item->str_result(&buffer); - return str ? character_or_binary_string_to_native(thd, str, to) : true; - } - - bool Item_val_bool(Item *item) const override - { - NativeBuffer tmp; - if (item->val_native(current_thd, &tmp)) - return false; - return !Fbt::only_zero_bytes(tmp.ptr(), tmp.length()); - } - void Item_get_date(THD *thd, Item *item, Temporal::Warn *buff, - MYSQL_TIME *ltime, date_mode_t fuzzydate) const override + bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override { set_zero_time(ltime, MYSQL_TIMESTAMP_TIME); - } - - longlong Item_val_int_signed_typecast(Item *item) const override - { - DBUG_ASSERT(0); - return 0; - } - - longlong Item_val_int_unsigned_typecast(Item *item) const override - { - DBUG_ASSERT(0); - return 0; - } - - String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) - const override - { - NativeBuffer tmp; - if ((item->null_value= item->arguments()[0]->val_native(current_thd, &tmp))) - return nullptr; - DBUG_ASSERT(tmp.length() == FbtImpl::binary_length()); - if (str->set_hex(tmp.ptr(), tmp.length())) - { - str->length(0); - str->set_charset(item->collation.collation); - } - return str; - } - - String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *item, - String *str) const override - { - NativeBuffer native; - if (item->val_native(current_thd, &native)) - { - DBUG_ASSERT(item->null_value); - return nullptr; - } - DBUG_ASSERT(native.length() == FbtImpl::binary_length()); - Fbt_null tmp(native.ptr(), native.length()); - return tmp.is_null() || tmp.to_string(str) ? nullptr : str; - } - double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *) - const override - { - return 0; - } - longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *) - const override - { - return 0; - } - my_decimal * - Item_func_hybrid_field_type_val_decimal(Item_func_hybrid_field_type *, - my_decimal *to) const override - { - my_decimal_set_zero(to); - return to; - } - void Item_func_hybrid_field_type_get_date(THD *, - Item_func_hybrid_field_type *, - Temporal::Warn *, - MYSQL_TIME *to, - date_mode_t fuzzydate) - const override - { - set_zero_time(to, MYSQL_TIMESTAMP_TIME); - } - // WHERE is Item_func_min_max_val_native??? - String *Item_func_min_max_val_str(Item_func_min_max *func, String *str) - const override - { - Fbt_null tmp(func); - return tmp.is_null() || tmp.to_string(str) ? nullptr : str; - } - double Item_func_min_max_val_real(Item_func_min_max *) const override - { - return 0; - } - longlong Item_func_min_max_val_int(Item_func_min_max *) const override - { - return 0; - } - my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *, - my_decimal *to) const override - { - my_decimal_set_zero(to); - return to; - } - bool Item_func_min_max_get_date(THD *thd, Item_func_min_max*, MYSQL_TIME *to, - date_mode_t fuzzydate) const override - { - set_zero_time(to, MYSQL_TIMESTAMP_TIME); return false; } + bool val_native(THD *thd, Native *to) override + { + return m_value.to_native(to); + } + void print(String *str, enum_query_type query_type) override + { + StringBuffer tmp; + tmp.append(singleton()->name().lex_cstring()); + my_caseup_str(&my_charset_latin1, tmp.c_ptr()); + str->append(tmp); + str->append('\''); + m_value.to_string(&tmp); + str->append(tmp); + str->append('\''); + } + Item *get_copy(THD *thd) override + { return get_item_copy(thd, this); } - bool Item_func_between_fix_length_and_dec(Item_func_between *func) const override + // Non-overriding methods + void set_value(const Fbt &value) { - return false; - } - longlong Item_func_between_val_int(Item_func_between *func) const override - { - return func->val_int_cmp_native(); - } - - cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const override - { - return new (thd->mem_root) cmp_item_fbt; - } - - in_vector *make_in_vector(THD *thd, const Item_func_in *func, - uint nargs) const override - { - return new (thd->mem_root) in_fbt(thd, nargs); - } - - bool Item_func_in_fix_comparator_compatible_types(THD *thd, - Item_func_in *func) - const override - { - if (func->compatible_types_scalar_bisection_possible()) - { - return func->value_list_convert_const_to_int(thd) || - func->fix_for_scalar_comparison_using_bisection(thd); - } - return - func->fix_for_scalar_comparison_using_cmp_items(thd, - 1U << (uint) STRING_RESULT); - } - bool Item_func_round_fix_length_and_dec(Item_func_round *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - - bool Item_func_abs_fix_length_and_dec(Item_func_abs *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - - bool Item_func_neg_fix_length_and_dec(Item_func_neg *func) const override - { - return Item_func_or_sum_illegal_param(func); - } - - bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_double_typecast_fix_length_and_dec(Item_double_typecast *item) - const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_float_typecast_fix_length_and_dec(Item_float_typecast *item) - const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *item) - const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *item) - const override - { - if (item->cast_charset() == &my_charset_bin) - { - static Item_char_typecast_func_handler_fbt_to_binary - item_char_typecast_func_handler_fbt_to_binary; - item->fix_length_and_dec_native_to_binary(FbtImpl::binary_length()); - item->set_func_handler(&item_char_typecast_func_handler_fbt_to_binary); - return false; - } - item->fix_length_and_dec_str(); - return false; - } - - bool Item_time_typecast_fix_length_and_dec(Item_time_typecast *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_date_typecast_fix_length_and_dec(Item_date_typecast *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *item) - const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_func_plus_fix_length_and_dec(Item_func_plus *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_func_minus_fix_length_and_dec(Item_func_minus *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_func_mul_fix_length_and_dec(Item_func_mul *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_func_div_fix_length_and_dec(Item_func_div *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - bool Item_func_mod_fix_length_and_dec(Item_func_mod *item) const override - { - return Item_func_or_sum_illegal_param(item); - } - }; - - class cmp_item_fbt: public cmp_item_scalar - { - Fbt m_native; - public: - cmp_item_fbt() - :cmp_item_scalar(), - m_native(Fbt::zero()) - { } - void store_value(Item *item) override - { - m_native= Fbt(item, &m_null_value); - } - int cmp_not_null(const Value *val) override - { - DBUG_ASSERT(!val->is_null()); - DBUG_ASSERT(val->is_string()); - Fbt_null tmp(val->m_string); - DBUG_ASSERT(!tmp.is_null()); - return m_native.cmp(tmp); - } - int cmp(Item *arg) override - { - Fbt_null tmp(arg); - return m_null_value || tmp.is_null() ? UNKNOWN : m_native.cmp(tmp) != 0; - } - int compare(cmp_item *ci) override - { - cmp_item_fbt *tmp= static_cast(ci); - DBUG_ASSERT(!m_null_value); - DBUG_ASSERT(!tmp->m_null_value); - return m_native.cmp(tmp->m_native); - } - cmp_item *make_same(THD *thd) override - { - return new (thd->mem_root) cmp_item_fbt(); + m_value= value; } }; @@ -1080,7 +301,7 @@ public: if (get_thd()->count_cuted_fields <= CHECK_FIELD_EXPRESSION) return; const TABLE_SHARE *s= table->s; - static const Name type_name= type_handler_fbt()->name(); + static const Name type_name= singleton()->name(); get_thd()->push_warning_truncated_value_for_field(level, type_name.ptr(), str.ptr(), s ? s->db.str : nullptr, s ? s->table_name.str : nullptr, field_name.str); @@ -1123,7 +344,7 @@ public: } const Type_handler *type_handler() const override { - return type_handler_fbt(); + return singleton(); } uint32 max_display_length() const override { return field_length; } bool str_needs_quotes() const override { return true; } @@ -1172,14 +393,14 @@ public: void sql_type(String &str) const override { - static Name name= type_handler_fbt()->name(); + static Name name= singleton()->name(); str.set_ascii(name.ptr(), name.length()); } void make_send_field(Send_field *to) override { Field::make_send_field(to); - to->set_data_type_name(type_handler_fbt()->name().lex_cstring()); + to->set_data_type_name(singleton()->name().lex_cstring()); } bool validate_value_in_record(THD *thd, const uchar *record) const override @@ -1410,7 +631,8 @@ public: */ DBUG_ASSERT(item->type_handler()->type_handler_base_or_self()-> is_traditional_scalar_type() || - item->type_handler() == type_handler()); + item->type_handler()->type_collection() == + type_handler()->type_collection()); return true; } /** @@ -1425,7 +647,8 @@ public: // See the DBUG_ASSERT comment in can_optimize_keypart_ref() DBUG_ASSERT(item->type_handler()->type_handler_base_or_self()-> is_traditional_scalar_type() || - item->type_handler() == type_handler()); + item->type_handler()->type_collection() == + type_handler()->type_collection()); return true; } void hash_not_null(Hasher *hasher) override @@ -1495,13 +718,171 @@ public: uint size_of() const override { return sizeof(*this); } }; + + class cmp_item_fbt: public cmp_item_scalar + { + Fbt m_native; + public: + cmp_item_fbt() + :cmp_item_scalar(), + m_native(Fbt::zero()) + { } + void store_value(Item *item) override + { + m_native= Fbt(item, &m_null_value); + } + int cmp_not_null(const Value *val) override + { + DBUG_ASSERT(!val->is_null()); + DBUG_ASSERT(val->is_string()); + Fbt_null tmp(val->m_string); + DBUG_ASSERT(!tmp.is_null()); + return m_native.cmp(tmp); + } + int cmp(Item *arg) override + { + Fbt_null tmp(arg); + return m_null_value || tmp.is_null() ? UNKNOWN : m_native.cmp(tmp) != 0; + } + int compare(cmp_item *ci) override + { + cmp_item_fbt *tmp= static_cast(ci); + DBUG_ASSERT(!m_null_value); + DBUG_ASSERT(!tmp->m_null_value); + return m_native.cmp(tmp->m_native); + } + cmp_item *make_same(THD *thd) override + { + return new (thd->mem_root) cmp_item_fbt(); + } + }; + + class in_fbt :public in_vector + { + Fbt m_value; + static int cmp_fbt(void *cmp_arg, Fbt *a, Fbt *b) + { + return a->cmp(*b); + } + public: + in_fbt(THD *thd, uint elements) + :in_vector(thd, elements, sizeof(Fbt), (qsort2_cmp) cmp_fbt, 0), + m_value(Fbt::zero()) + { } + const Type_handler *type_handler() const override + { + return singleton(); + } + void set(uint pos, Item *item) override + { + Fbt *buff= &((Fbt *) base)[pos]; + Fbt_null value(item); + if (value.is_null()) + *buff= Fbt::zero(); + else + *buff= value; + } + uchar *get_value(Item *item) override + { + Fbt_null value(item); + if (value.is_null()) + return 0; + m_value= value; + return (uchar *) &m_value; + } + Item* create_item(THD *thd) override + { + return new (thd->mem_root) Item_literal_fbt(thd); + } + void value_to_item(uint pos, Item *item) override + { + const Fbt &buff= (((Fbt*) base)[pos]); + static_cast(item)->set_value(buff); + } + }; + + class Item_copy_fbt: public Item_copy + { + NativeBuffer m_value; + public: + Item_copy_fbt(THD *thd, Item *item_arg): Item_copy(thd, item_arg) {} + + bool val_native(THD *thd, Native *to) override + { + if (null_value) + return true; + return to->copy(m_value.ptr(), m_value.length()); + } + String *val_str(String *to) override + { + if (null_value) + return NULL; + Fbt_null tmp(m_value.ptr(), m_value.length()); + return tmp.is_null() || tmp.to_string(to) ? NULL : to; + } + my_decimal *val_decimal(my_decimal *to) override + { + my_decimal_set_zero(to); + return to; + } + double val_real() override + { + return 0; + } + longlong val_int() override + { + return 0; + } + bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override + { + set_zero_time(ltime, MYSQL_TIMESTAMP_TIME); + return null_value; + } + void copy() override + { + null_value= item->val_native(current_thd, &m_value); + DBUG_ASSERT(null_value == item->null_value); + } + int save_in_field(Field *field, bool no_conversions) override + { + return Item::save_in_field(field, no_conversions); + } + Item *get_copy(THD *thd) override + { return get_item_copy(thd, this); } + }; + + class Item_char_typecast_func_handler_fbt_to_binary: + public Item_handled_func::Handler_str + { + public: + const Type_handler *return_type_handler(const Item_handled_func *item) + const override + { + if (item->max_length > MAX_FIELD_VARCHARLENGTH) + return Type_handler::blob_type_handler(item->max_length); + if (item->max_length > 255) + return &type_handler_varchar; + return &type_handler_string; + } + bool fix_length_and_dec(Item_handled_func *xitem) const override + { + return false; + } + String *val_str(Item_handled_func *item, String *to) const override + { + DBUG_ASSERT(dynamic_cast(item)); + return static_cast(item)-> + val_str_binary_from_native(to); + } + }; + class Item_typecast_fbt: public Item_func { public: Item_typecast_fbt(THD *thd, Item *a) :Item_func(thd, a) {} const Type_handler *type_handler() const override - { return type_handler_fbt(); } + { return singleton(); } enum Functype functype() const override { return CHAR_TYPECAST_FUNC; } bool eq(const Item *item, bool binary_cmp) const override @@ -1518,7 +899,7 @@ public: } LEX_CSTRING func_name_cstring() const override { - static Name name= type_handler_fbt()->name(); + static Name name= singleton()->name(); size_t len= 9+name.length()+1; char *buf= (char*)current_thd->alloc(len); strmov(strmov(buf, "cast_as_"), name.ptr()); @@ -1529,7 +910,7 @@ public: str->append(STRING_WITH_LEN("cast(")); args[0]->print(str, query_type); str->append(STRING_WITH_LEN(" as ")); - str->append(type_handler_fbt()->name().lex_cstring()); + str->append(singleton()->name().lex_cstring()); str->append(')'); } bool fix_length_and_dec(THD *thd) override @@ -1576,7 +957,7 @@ public: NativeBuffer m_value; public: Item_cache_fbt(THD *thd) - :Item_cache(thd, type_handler_fbt()) { } + :Item_cache(thd, singleton()) { } Item *get_copy(THD *thd) { return get_item_copy(thd, this); } bool cache_value() @@ -1644,267 +1025,890 @@ public: } }; - class Item_literal_fbt: public Item_literal + /* =[ methods ]=============================================== */ +private: + + bool character_or_binary_string_to_native(THD *thd, const String *str, + Native *to) const { - Fbt m_value; - public: - Item_literal_fbt(THD *thd) - :Item_literal(thd), - m_value(Fbt::zero()) - { } - Item_literal_fbt(THD *thd, const Fbt &value) - :Item_literal(thd), - m_value(value) - { } - const Type_handler *type_handler() const override + if (str->charset() == &my_charset_bin) { - return type_handler_fbt(); - } - longlong val_int() override - { - return 0; - } - double val_real() override - { - return 0; - } - String *val_str(String *to) override - { - return m_value.to_string(to) ? NULL : to; - } - my_decimal *val_decimal(my_decimal *to) override - { - my_decimal_set_zero(to); - return to; - } - bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override - { - set_zero_time(ltime, MYSQL_TIMESTAMP_TIME); - return false; - } - bool val_native(THD *thd, Native *to) override - { - return m_value.to_native(to); - } - void print(String *str, enum_query_type query_type) override - { - StringBuffer tmp; - tmp.append(type_handler_fbt()->name().lex_cstring()); - my_caseup_str(&my_charset_latin1, tmp.c_ptr()); - str->append(tmp); - str->append('\''); - m_value.to_string(&tmp); - str->append(tmp); - str->append('\''); - } - Item *get_copy(THD *thd) override - { return get_item_copy(thd, this); } - - // Non-overriding methods - void set_value(const Fbt &value) - { - m_value= value; - } - }; - - class Item_copy_fbt: public Item_copy - { - NativeBuffer m_value; - public: - Item_copy_fbt(THD *thd, Item *item_arg): Item_copy(thd, item_arg) {} - - bool val_native(THD *thd, Native *to) override - { - if (null_value) + // Convert from a binary string + if (str->length() != FbtImpl::binary_length() || + to->copy(str->ptr(), str->length())) + { + thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, + name().ptr(), ErrConvString(str).ptr()); return true; - return to->copy(m_value.ptr(), m_value.length()); - } - String *val_str(String *to) override - { - if (null_value) - return NULL; - Fbt_null tmp(m_value.ptr(), m_value.length()); - return tmp.is_null() || tmp.to_string(to) ? NULL : to; - } - my_decimal *val_decimal(my_decimal *to) override - { - my_decimal_set_zero(to); - return to; - } - double val_real() override - { - return 0; - } - longlong val_int() override - { - return 0; - } - bool get_date(THD *thd, MYSQL_TIME *ltime, date_mode_t fuzzydate) override - { - set_zero_time(ltime, MYSQL_TIMESTAMP_TIME); - return null_value; - } - void copy() override - { - null_value= item->val_native(current_thd, &m_value); - DBUG_ASSERT(null_value == item->null_value); - } - int save_in_field(Field *field, bool no_conversions) override - { - return Item::save_in_field(field, no_conversions); - } - Item *get_copy(THD *thd) override - { return get_item_copy(thd, this); } - }; - - class in_fbt :public in_vector - { - Fbt m_value; - static int cmp_fbt(void *cmp_arg, Fbt *a, Fbt *b) - { - return a->cmp(*b); - } - public: - in_fbt(THD *thd, uint elements) - :in_vector(thd, elements, sizeof(Fbt), (qsort2_cmp) cmp_fbt, 0), - m_value(Fbt::zero()) - { } - const Type_handler *type_handler() const override - { - return type_handler_fbt(); - } - void set(uint pos, Item *item) override - { - Fbt *buff= &((Fbt *) base)[pos]; - Fbt_null value(item); - if (value.is_null()) - *buff= Fbt::zero(); - else - *buff= value; - } - uchar *get_value(Item *item) override - { - Fbt_null value(item); - if (value.is_null()) - return 0; - m_value= value; - return (uchar *) &m_value; - } - Item* create_item(THD *thd) override - { - return new (thd->mem_root) Item_literal_fbt(thd); - } - void value_to_item(uint pos, Item *item) override - { - const Fbt &buff= (((Fbt*) base)[pos]); - static_cast(item)->set_value(buff); - } - }; - - class Item_char_typecast_func_handler_fbt_to_binary: - public Item_handled_func::Handler_str - { - public: - const Type_handler *return_type_handler(const Item_handled_func *item) - const override - { - if (item->max_length > MAX_FIELD_VARCHARLENGTH) - return Type_handler::blob_type_handler(item->max_length); - if (item->max_length > 255) - return &type_handler_varchar; - return &type_handler_string; - } - bool fix_length_and_dec(Item_handled_func *xitem) const override - { + } return false; } - String *val_str(Item_handled_func *item, String *to) const override - { - DBUG_ASSERT(dynamic_cast(item)); - return static_cast(item)-> - val_str_binary_from_native(to); - } - }; + // Convert from a character string + Fbt_null tmp(*str); + if (tmp.is_null()) + thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, + name().ptr(), ErrConvString(str).ptr()); + return tmp.is_null() || tmp.to_native(to); + } - class Type_collection_fbt: public Type_collection +public: + ~Type_handler_fbt() override {} + + const Type_collection *type_collection() const override { - const Type_handler *aggregate_common(const Type_handler *a, - const Type_handler *b) const - { - if (a == b) - return a; - return NULL; - } - const Type_handler *aggregate_if_string(const Type_handler *a, - const Type_handler *b) const - { - static const Type_aggregator::Pair agg[]= - { - {type_handler_fbt(), &type_handler_null, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_varchar, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_string, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_tiny_blob, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_blob, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_medium_blob, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_long_blob, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_hex_hybrid, type_handler_fbt()}, - {NULL,NULL,NULL} - }; - return Type_aggregator::find_handler_in_array(agg, a, b, true); - } - public: - const Type_handler *aggregate_for_result(const Type_handler *a, - const Type_handler *b) - const override - { - const Type_handler *h; - if ((h= aggregate_common(a, b)) || - (h= aggregate_if_string(a, b))) - return h; - return NULL; - } + return TypeCollectionImpl::singleton(); + } - const Type_handler *aggregate_for_min_max(const Type_handler *a, - const Type_handler *b) + const Name &default_value() const override + { + return FbtImpl::default_value(); + } + ulong KEY_pack_flags(uint column_nr) const override + { + return FbtImpl::KEY_pack_flags(column_nr); + } + protocol_send_type_t protocol_send_type() const override + { + return PROTOCOL_SEND_STRING; + } + bool Item_append_extended_type_info(Send_field_extended_metadata *to, + const Item *item) const override + { + return to->set_data_type_name(name().lex_cstring()); + } + + enum_field_types field_type() const override + { + return MYSQL_TYPE_STRING; + } + + Item_result result_type() const override + { + return STRING_RESULT; + } + + Item_result cmp_type() const override + { + return STRING_RESULT; + } + + enum_dynamic_column_type dyncol_type(const Type_all_attributes *attr) + const override + { + return DYN_COL_STRING; + } + + uint32 max_display_length_for_field(const Conv_source &src) const override + { + return FbtImpl::max_char_length(); + } + + const Type_handler *type_handler_for_comparison() const override + { + return this; + } + + int stored_field_cmp_to_item(THD *thd, Field *field, Item *item) const override + { + DBUG_ASSERT(field->type_handler() == this); + Fbt_null ni(item); // Convert Item to Fbt + if (ni.is_null()) + return 0; + NativeBuffer tmp; + if (field->val_native(&tmp)) + { + DBUG_ASSERT(0); + return 0; + } + return -ni.cmp(tmp); + } + CHARSET_INFO *charset_for_protocol(const Item *item) const override + { + return item->collation.collation; + } + + bool is_scalar_type() const override { return true; } + bool is_val_native_ready() const override { return true; } + bool can_return_int() const override { return false; } + bool can_return_decimal() const override { return false; } + bool can_return_real() const override { return false; } + bool can_return_str() const override { return true; } + bool can_return_text() const override { return true; } + bool can_return_date() const override { return false; } + bool can_return_time() const override { return false; } + bool convert_to_binary_using_val_native() const override { return true; } + + decimal_digits_t Item_time_precision(THD *thd, Item *item) const override + { + return 0; + } + decimal_digits_t Item_datetime_precision(THD *thd, Item *item) const override + { + return 0; + } + decimal_digits_t Item_decimal_scale(const Item *item) const override + { + return 0; + } + decimal_digits_t Item_decimal_precision(const Item *item) const override + { + /* This will be needed if we ever allow cast from Fbt to DECIMAL. */ + return (FbtImpl::binary_length()*8+7)/10*3; // = bytes to decimal digits + } + + /* + Returns how many digits a divisor adds into a division result. + See Item::divisor_precision_increment() in item.h for more comments. + */ + decimal_digits_t Item_divisor_precision_increment(const Item *) const override + { + return 0; + } + /** + Makes a temporary table Field to handle numeric aggregate functions, + e.g. SUM(DISTINCT expr), AVG(DISTINCT expr), etc. + */ + Field *make_num_distinct_aggregator_field(MEM_ROOT *, const Item *) const override + { + DBUG_ASSERT(0); + return 0; + } + Field *make_conversion_table_field(MEM_ROOT *root, TABLE *table, uint metadata, + const Field *target) const override + { + const Record_addr tmp(NULL, Bit_addr(true)); + return new (table->in_use->mem_root) Field_fbt(&empty_clex_str, tmp); + } + // Fix attributes after the parser + bool Column_definition_fix_attributes(Column_definition *c) const override + { + c->length= FbtImpl::max_char_length(); + return false; + } + + bool Column_definition_prepare_stage1(THD *, MEM_ROOT *, + Column_definition *def, + column_definition_type_t, + const Column_derived_attributes *) + const override + { + def->prepare_stage1_simple(&my_charset_numeric); + return false; + } + + bool Column_definition_redefine_stage1(Column_definition *def, + const Column_definition *dup, + const handler *file) const override + { + def->redefine_stage1_common(dup, file); + def->set_compression_method(dup->compression_method()); + def->create_length_to_internal_length_string(); + return false; + } + + bool Column_definition_prepare_stage2(Column_definition *def, handler *file, + ulonglong table_flags) const override + { + def->pack_flag= FIELDFLAG_BINARY; + return false; + } + + bool partition_field_check(const LEX_CSTRING &field_name, + Item *item_expr) const override + { + if (item_expr->cmp_type() != STRING_RESULT) + { + my_error(ER_WRONG_TYPE_COLUMN_VALUE_ERROR, MYF(0)); + return true; + } + return false; + } + + bool partition_field_append_value(String *to, Item *item_expr, + CHARSET_INFO *field_cs, + partition_value_print_mode_t mode) + const override + { + StringBuffer fbtstr; + Fbt_null fbt(item_expr); + if (fbt.is_null()) + { + my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0)); + return true; + } + return fbt.to_string(&fbtstr) || + to->append('\'') || + to->append(fbtstr) || + to->append('\''); + } + + Field *make_table_field(MEM_ROOT *root, const LEX_CSTRING *name, + const Record_addr &addr, + const Type_all_attributes &attr, + TABLE_SHARE *table) const override + { + return new (root) Field_fbt(name, addr); + } + + Field * make_table_field_from_def(TABLE_SHARE *share, MEM_ROOT *mem_root, + const LEX_CSTRING *name, const Record_addr &addr, + const Bit_addr &bit, + const Column_definition_attributes *attr, + uint32 flags) const override + { + return new (mem_root) Field_fbt(name, addr); + } + void Column_definition_attributes_frm_pack(const Column_definition_attributes *def, + uchar *buff) const override + { + def->frm_pack_basic(buff); + def->frm_pack_charset(buff); + } + bool Column_definition_attributes_frm_unpack(Column_definition_attributes *def, + TABLE_SHARE *share, const uchar *buffer, + LEX_CUSTRING *gis_options) + const override + { + def->frm_unpack_basic(buffer); + return def->frm_unpack_charset(share, buffer); + } + void make_sort_key_part(uchar *to, Item *item, const SORT_FIELD_ATTR *sort_field, + String *) const override + { + DBUG_ASSERT(item->type_handler() == this); + NativeBuffer tmp; + item->val_native_result(current_thd, &tmp); + if (item->maybe_null()) + { + if (item->null_value) + { + memset(to, 0, FbtImpl::binary_length() + 1); + return; + } + *to++= 1; + } + DBUG_ASSERT(!item->null_value); + DBUG_ASSERT(FbtImpl::binary_length() == tmp.length()); + DBUG_ASSERT(FbtImpl::binary_length() == sort_field->length); + FbtImpl::memory_to_record((char*) to, tmp.ptr()); + } + uint make_packed_sort_key_part(uchar *to, Item *item, + const SORT_FIELD_ATTR *sort_field, + String *) const override + { + DBUG_ASSERT(item->type_handler() == this); + NativeBuffer tmp; + item->val_native_result(current_thd, &tmp); + if (item->maybe_null()) + { + if (item->null_value) + { + *to++=0; + return 0; + } + *to++= 1; + } + DBUG_ASSERT(!item->null_value); + DBUG_ASSERT(FbtImpl::binary_length() == tmp.length()); + DBUG_ASSERT(FbtImpl::binary_length() == sort_field->length); + FbtImpl::memory_to_record((char*) to, tmp.ptr()); + return tmp.length(); + } + void sort_length(THD *thd, const Type_std_attributes *item, + SORT_FIELD_ATTR *attr) const override + { + attr->original_length= attr->length= FbtImpl::binary_length(); + attr->suffix_length= 0; + } + uint32 max_display_length(const Item *item) const override + { + return FbtImpl::max_char_length(); + } + uint32 calc_pack_length(uint32 length) const override + { + return FbtImpl::binary_length(); + } + void Item_update_null_value(Item *item) const override + { + NativeBuffer tmp; + item->val_native(current_thd, &tmp); + } + bool Item_save_in_value(THD *thd, Item *item, st_value *value) const override + { + value->m_type= DYN_COL_STRING; + String *str= item->val_str(&value->m_string); + if (str != &value->m_string && !item->null_value) + { + // "item" returned a non-NULL value + if (Fbt_null(*str).is_null()) + { + /* + The value was not-null, but conversion to FBT failed: + SELECT a, DECODE_ORACLE(fbtcol, 'garbage', '', '::01', '01') + FROM t1; + */ + thd->push_warning_wrong_value(Sql_condition::WARN_LEVEL_WARN, + name().ptr(), ErrConvString(str).ptr()); + value->m_type= DYN_COL_NULL; + return true; + } + // "item" returned a non-NULL value, and it was a valid FBT + value->m_string.set(str->ptr(), str->length(), str->charset()); + } + return check_null(item, value); + } + void Item_param_setup_conversion(THD *thd, Item_param *param) const override + { + param->setup_conversion_string(thd, thd->variables.character_set_client); + } + void Item_param_set_param_func(Item_param *param, + uchar **pos, ulong len) const override + { + param->set_param_str(pos, len); + } + bool Item_param_set_from_value(THD *thd, Item_param *param, + const Type_all_attributes *attr, + const st_value *val) const override + { + param->unsigned_flag= false; + param->setup_conversion_string(thd, attr->collation.collation); + /* + Exact value of max_length is not known unless fbt is converted to + charset of connection, so we have to set it later. + */ + return param->set_str(val->m_string.ptr(), val->m_string.length(), + attr->collation.collation, + attr->collation.collation); + } + bool Item_param_val_native(THD *thd, Item_param *item, Native *to) + const override + { + StringBuffer buffer; + String *str= item->val_str(&buffer); + if (!str) + return true; + Fbt_null tmp(*str); + return tmp.is_null() || tmp.to_native(to); + } + bool Item_send(Item *item, Protocol *p, st_value *buf) const override + { + return Item_send_str(item, p, buf); + } + int Item_save_in_field(Item *item, Field *field, bool no_conversions) + const override + { + if (field->type_handler() == this) + { + NativeBuffer tmp; + bool rc= item->val_native(current_thd, &tmp); + if (rc || item->null_value) + return set_field_to_null_with_conversions(field, no_conversions); + field->set_notnull(); + return field->store_native(tmp); + } + return item->save_str_in_field(field, no_conversions); + } + + String *print_item_value(THD *thd, Item *item, String *str) const override + { + StringBuffer buf; + String *result= item->val_str(&buf); + /* + TODO: This should eventually use one of these notations: + 1. CAST('xxx' AS Fbt) + Problem: CAST is not supported as a NAME_CONST() argument. + 2. Fbt'xxx' + Problem: This syntax is not supported by the parser yet. + */ + return !result || str->realloc(result->length() + 2) || + str->append(STRING_WITH_LEN("'")) || + str->append(result->ptr(), result->length()) || + str->append(STRING_WITH_LEN("'")) ? nullptr : str; + } + + /** + Check if + WHERE expr=value AND expr=const + can be rewritten as: + WHERE const=value AND expr=const + + "this" is the comparison handler that is used by "target". + + @param target - the predicate expr=value, + whose "expr" argument will be replaced to "const". + @param target_expr - the target's "expr" which will be replaced to "const". + @param target_value - the target's second argument, it will remain unchanged. + @param source - the equality predicate expr=const (or expr<=>const) + that can be used to rewrite the "target" part + (under certain conditions, see the code). + @param source_expr - the source's "expr". It should be exactly equal to + the target's "expr" to make condition rewrite possible. + @param source_const - the source's "const" argument, it will be inserted + into "target" instead of "expr". + */ + bool can_change_cond_ref_to_const(Item_bool_func2 *target, Item *target_expr, + Item *target_value, Item_bool_func2 *source, + Item *source_expr, Item *source_const) + const override + { + /* + WHERE COALESCE(col)='xxx' AND COALESCE(col)=CONCAT(a); --> + WHERE COALESCE(col)='xxx' AND 'xxx'=CONCAT(a); + */ + return target->compare_type_handler() == source->compare_type_handler(); + } + bool subquery_type_allows_materialization(const Item *inner, + const Item *outer, bool) const override + { + /* + Example: + SELECT * FROM t1 WHERE a IN (SELECT col FROM t1 GROUP BY col); + Allow materialization only if the outer column is also FBT. + This can be changed for more relaxed rules in the future. + */ + DBUG_ASSERT(inner->type_handler() == this); + return outer->type_handler() == this; + } + /** + Make a simple constant replacement item for a constant "src", + so the new item can futher be used for comparison with "cmp", e.g.: + src = cmp -> replacement = cmp + + "this" is the type handler that is used to compare "src" and "cmp". + + @param thd - current thread, for mem_root + @param src - The item that we want to replace. It's a const item, + but it can be complex enough to calculate on every row. + @param cmp - The src's comparand. + @retval - a pointer to the created replacement Item + @retval - NULL, if could not create a replacement (e.g. on EOM). + NULL is also returned for ROWs, because instead of replacing + a Item_row to a new Item_row, Type_handler_row just replaces + its elements. + */ + Item *make_const_item_for_comparison(THD *thd, Item *src, + const Item *cmp) const override + { + Fbt_null tmp(src); + if (tmp.is_null()) + return new (thd->mem_root) Item_null(thd, src->name.str); + return new (thd->mem_root) Item_literal_fbt(thd, tmp); + } + Item_cache *Item_get_cache(THD *thd, const Item *item) const override + { + return new (thd->mem_root) Item_cache_fbt(thd); + } + + Item *create_typecast_item(THD *thd, Item *item, + const Type_cast_attributes &attr) const override + { + return new (thd->mem_root) Item_typecast_fbt(thd, item); + } + Item_copy *create_item_copy(THD *thd, Item *item) const override + { + return new (thd->mem_root) Item_copy_fbt(thd, item); + } + int cmp_native(const Native &a, const Native &b) const override + { + return FbtImpl::cmp(a.to_lex_cstring(), b.to_lex_cstring()); + } + bool set_comparator_func(THD *thd, Arg_comparator *cmp) const override + { + return cmp->set_cmp_func_native(thd); + } + bool Item_const_eq(const Item_const *a, const Item_const *b, + bool binary_cmp) const override + { + return false; + } + bool Item_eq_value(THD *thd, const Type_cmp_attributes *attr, + Item *a, Item *b) const override + { + Fbt_null na(a), nb(b); + return !na.is_null() && !nb.is_null() && !na.cmp(nb); + } + bool Item_hybrid_func_fix_attributes(THD *thd, const LEX_CSTRING &name, + Type_handler_hybrid_field_type *h, + Type_all_attributes *attr, + Item **items, uint nitems) const override + { + attr->Type_std_attributes::operator=(Type_std_attributes_fbt()); + h->set_handler(this); + /* + If some of the arguments cannot be safely converted to "FBT NOT NULL", + then mark the entire function nullability as NULL-able. + Otherwise, keep the generic nullability calculated by earlier stages: + - either by the most generic way in Item_func::fix_fields() + - or by Item_func_xxx::fix_length_and_dec() before the call of + Item_hybrid_func_fix_attributes() + IFNULL() is special. It does not need to test args[0]. + */ + uint first= dynamic_cast(attr) ? 1 : 0; + for (uint i= first; i < nitems; i++) + { + if (Fbt::fix_fields_maybe_null_on_conversion_to_fbt(items[i])) + { + attr->set_type_maybe_null(true); + break; + } + } + return false; + } + bool Item_func_min_max_fix_attributes(THD *thd, Item_func_min_max *func, + Item **items, uint nitems) const override + { + return Item_hybrid_func_fix_attributes(thd, func->func_name_cstring(), + func, func, items, nitems); + + } + bool Item_sum_hybrid_fix_length_and_dec(Item_sum_hybrid *func) const override + { + func->Type_std_attributes::operator=(Type_std_attributes_fbt()); + func->set_handler(this); + return false; + } + bool Item_sum_sum_fix_length_and_dec(Item_sum_sum *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + bool Item_sum_avg_fix_length_and_dec(Item_sum_avg *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + bool Item_sum_variance_fix_length_and_dec(Item_sum_variance *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + + bool Item_val_native_with_conversion(THD *thd, Item *item, + Native *to) const override + { + if (item->type_handler() == this) + return item->val_native(thd, to); // No conversion needed + StringBuffer buffer; + String *str= item->val_str(&buffer); + return str ? character_or_binary_string_to_native(thd, str, to) : true; + } + bool Item_val_native_with_conversion_result(THD *thd, Item *item, + Native *to) const override + { + if (item->type_handler() == this) + return item->val_native_result(thd, to); // No conversion needed + StringBuffer buffer; + String *str= item->str_result(&buffer); + return str ? character_or_binary_string_to_native(thd, str, to) : true; + } + + bool Item_val_bool(Item *item) const override + { + NativeBuffer tmp; + if (item->val_native(current_thd, &tmp)) + return false; + return !Fbt::only_zero_bytes(tmp.ptr(), tmp.length()); + } + void Item_get_date(THD *thd, Item *item, Temporal::Warn *buff, + MYSQL_TIME *ltime, date_mode_t fuzzydate) const override + { + set_zero_time(ltime, MYSQL_TIMESTAMP_TIME); + } + + longlong Item_val_int_signed_typecast(Item *item) const override + { + DBUG_ASSERT(0); + return 0; + } + + longlong Item_val_int_unsigned_typecast(Item *item) const override + { + DBUG_ASSERT(0); + return 0; + } + + String *Item_func_hex_val_str_ascii(Item_func_hex *item, String *str) + const override + { + NativeBuffer tmp; + if ((item->null_value= item->arguments()[0]->val_native(current_thd, &tmp))) + return nullptr; + DBUG_ASSERT(tmp.length() == FbtImpl::binary_length()); + if (str->set_hex(tmp.ptr(), tmp.length())) + { + str->length(0); + str->set_charset(item->collation.collation); + } + return str; + } + + String *Item_func_hybrid_field_type_val_str(Item_func_hybrid_field_type *item, + String *str) const override + { + NativeBuffer native; + if (item->val_native(current_thd, &native)) + { + DBUG_ASSERT(item->null_value); + return nullptr; + } + DBUG_ASSERT(native.length() == FbtImpl::binary_length()); + Fbt_null tmp(native.ptr(), native.length()); + return tmp.is_null() || tmp.to_string(str) ? nullptr : str; + } + double Item_func_hybrid_field_type_val_real(Item_func_hybrid_field_type *) const override - { - return aggregate_for_result(a, b); - } + { + return 0; + } + longlong Item_func_hybrid_field_type_val_int(Item_func_hybrid_field_type *) + const override + { + return 0; + } + my_decimal * + Item_func_hybrid_field_type_val_decimal(Item_func_hybrid_field_type *, + my_decimal *to) const override + { + my_decimal_set_zero(to); + return to; + } + void Item_func_hybrid_field_type_get_date(THD *, + Item_func_hybrid_field_type *, + Temporal::Warn *, + MYSQL_TIME *to, + date_mode_t fuzzydate) + const override + { + set_zero_time(to, MYSQL_TIMESTAMP_TIME); + } + // WHERE is Item_func_min_max_val_native??? + String *Item_func_min_max_val_str(Item_func_min_max *func, String *str) + const override + { + Fbt_null tmp(func); + return tmp.is_null() || tmp.to_string(str) ? nullptr : str; + } + double Item_func_min_max_val_real(Item_func_min_max *) const override + { + return 0; + } + longlong Item_func_min_max_val_int(Item_func_min_max *) const override + { + return 0; + } + my_decimal *Item_func_min_max_val_decimal(Item_func_min_max *, + my_decimal *to) const override + { + my_decimal_set_zero(to); + return to; + } + bool Item_func_min_max_get_date(THD *thd, Item_func_min_max*, MYSQL_TIME *to, + date_mode_t fuzzydate) const override + { + set_zero_time(to, MYSQL_TIMESTAMP_TIME); + return false; + } - const Type_handler *aggregate_for_comparison(const Type_handler *a, - const Type_handler *b) - const override - { - if (const Type_handler *h= aggregate_common(a, b)) - return h; - static const Type_aggregator::Pair agg[]= - { - {type_handler_fbt(), &type_handler_null, type_handler_fbt()}, - {type_handler_fbt(), &type_handler_long_blob, type_handler_fbt()}, - {NULL,NULL,NULL} - }; - return Type_aggregator::find_handler_in_array(agg, a, b, true); - } + bool Item_func_between_fix_length_and_dec(Item_func_between *func) const override + { + return false; + } + longlong Item_func_between_val_int(Item_func_between *func) const override + { + return func->val_int_cmp_native(); + } - const Type_handler *aggregate_for_num_op(const Type_handler *a, - const Type_handler *b) + cmp_item *make_cmp_item(THD *thd, CHARSET_INFO *cs) const override + { + return new (thd->mem_root) cmp_item_fbt; + } + + in_vector *make_in_vector(THD *thd, const Item_func_in *func, + uint nargs) const override + { + return new (thd->mem_root) in_fbt(thd, nargs); + } + + bool Item_func_in_fix_comparator_compatible_types(THD *thd, + Item_func_in *func) + const override + { + if (func->compatible_types_scalar_bisection_possible()) + { + return func->value_list_convert_const_to_int(thd) || + func->fix_for_scalar_comparison_using_bisection(thd); + } + return + func->fix_for_scalar_comparison_using_cmp_items(thd, + 1U << (uint) STRING_RESULT); + } + bool Item_func_round_fix_length_and_dec(Item_func_round *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + bool Item_func_int_val_fix_length_and_dec(Item_func_int_val *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + + bool Item_func_abs_fix_length_and_dec(Item_func_abs *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + + bool Item_func_neg_fix_length_and_dec(Item_func_neg *func) const override + { + return Item_func_or_sum_illegal_param(func); + } + + bool Item_func_signed_fix_length_and_dec(Item_func_signed *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_func_unsigned_fix_length_and_dec(Item_func_unsigned *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_double_typecast_fix_length_and_dec(Item_double_typecast *item) + const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_float_typecast_fix_length_and_dec(Item_float_typecast *item) + const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_decimal_typecast_fix_length_and_dec(Item_decimal_typecast *item) + const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_char_typecast_fix_length_and_dec(Item_char_typecast *item) const override + { + if (item->cast_charset() == &my_charset_bin) { - return NULL; + static Item_char_typecast_func_handler_fbt_to_binary + item_char_typecast_func_handler_fbt_to_binary; + item->fix_length_and_dec_native_to_binary(FbtImpl::binary_length()); + item->set_func_handler(&item_char_typecast_func_handler_fbt_to_binary); + return false; } + item->fix_length_and_dec_str(); + return false; + } - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - if (type_handler_fbt()->name().eq(name)) - return type_handler_fbt(); - return NULL; - } - }; - static Type_handler_fbt *type_handler_fbt() + bool Item_time_typecast_fix_length_and_dec(Item_time_typecast *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_date_typecast_fix_length_and_dec(Item_date_typecast *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_datetime_typecast_fix_length_and_dec(Item_datetime_typecast *item) + const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_func_plus_fix_length_and_dec(Item_func_plus *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_func_minus_fix_length_and_dec(Item_func_minus *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_func_mul_fix_length_and_dec(Item_func_mul *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_func_div_fix_length_and_dec(Item_func_div *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + bool Item_func_mod_fix_length_and_dec(Item_func_mod *item) const override + { + return Item_func_or_sum_illegal_param(item); + } + + static Type_handler_fbt *singleton() { static Type_handler_fbt th; return &th; } }; +template +class Type_collection_fbt: public Type_collection +{ + const Type_handler *aggregate_common(const Type_handler *a, + const Type_handler *b) const + { + if (a == b) + return a; + return NULL; + } + const Type_handler *aggregate_if_string(const Type_handler *a, + const Type_handler *b) const + { + static const Type_aggregator::Pair agg[]= + { + {Type_handler_fbt::singleton(), &type_handler_null, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_varchar, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_string, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_tiny_blob, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_blob, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_medium_blob, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_long_blob, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_hex_hybrid, Type_handler_fbt::singleton()}, + {NULL,NULL,NULL} + }; + return Type_aggregator::find_handler_in_array(agg, a, b, true); + } +public: + const Type_handler *aggregate_for_result(const Type_handler *a, + const Type_handler *b) + const override + { + const Type_handler *h; + if ((h= aggregate_common(a, b)) || (h= aggregate_if_string(a, b))) + return h; + return NULL; + } + + const Type_handler *aggregate_for_min_max(const Type_handler *a, + const Type_handler *b) + const override + { + return aggregate_for_result(a, b); + } + + const Type_handler *aggregate_for_comparison(const Type_handler *a, + const Type_handler *b) + const override + { + if (const Type_handler *h= aggregate_common(a, b)) + return h; + static const Type_aggregator::Pair agg[]= + { + {Type_handler_fbt::singleton(), &type_handler_null, Type_handler_fbt::singleton()}, + {Type_handler_fbt::singleton(), &type_handler_long_blob, Type_handler_fbt::singleton()}, + {NULL,NULL,NULL} + }; + return Type_aggregator::find_handler_in_array(agg, a, b, true); + } + + const Type_handler *aggregate_for_num_op(const Type_handler *a, + const Type_handler *b) + const override + { + return NULL; + } + + static Type_collection_fbt *singleton() + { + static Type_collection_fbt tc; + return &tc; + } +}; + #endif /* SQL_TYPE_FIXEDBIN_H */ diff --git a/sql/sql_type_geom.cc b/sql/sql_type_geom.cc index 3bdc34b4d65..1bdcc34422c 100644 --- a/sql/sql_type_geom.cc +++ b/sql/sql_type_geom.cc @@ -67,7 +67,7 @@ Type_handler_geometry::type_handler_geom_by_type(uint type) const Type_handler * -Type_collection_geometry::handler_by_name(const LEX_CSTRING &name) const +Type_collection_geometry_handler_by_name(const LEX_CSTRING &name) { if (type_handler_point.name().eq(name)) return &type_handler_point; diff --git a/sql/sql_type_geom.h b/sql/sql_type_geom.h index db951297519..735e4605be1 100644 --- a/sql/sql_type_geom.h +++ b/sql/sql_type_geom.h @@ -296,7 +296,6 @@ class Type_collection_geometry: public Type_collection #endif public: bool init(Type_handler_data *data) override; - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override; const Type_handler *aggregate_for_result(const Type_handler *a, const Type_handler *b) const override; @@ -315,6 +314,8 @@ public: }; extern Type_collection_geometry type_collection_geometry; +const Type_handler * +Type_collection_geometry_handler_by_name(const LEX_CSTRING &name); #include "field.h" diff --git a/sql/sql_type_json.cc b/sql/sql_type_json.cc index c12b868e6b9..27072de2d55 100644 --- a/sql/sql_type_json.cc +++ b/sql/sql_type_json.cc @@ -233,20 +233,6 @@ public: */ return NULL; } - - const Type_handler *handler_by_name(const LEX_CSTRING &name) const override - { - /* - Name resolution is not needed yet. - JSON is not fully pluggable at the moment: - - It is parsed using a hard-coded rule in sql_yacc.yy - - It does not store extended data type information into - FRM file yet. JSON is detected by CHECK(JSON_VALID(col)) - and this detection is also hard-coded. - This will change in the future. - */ - return NULL; - } }; diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e85e6406f00..07cf1d61519 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -701,7 +701,7 @@ int mysql_update(THD *thd, */ if (thd->lex->describe) goto produce_explain_and_leave; - if (!(explain= query_plan.save_explain_update_data(query_plan.mem_root, thd))) + if (!(explain= query_plan.save_explain_update_data(thd, query_plan.mem_root))) goto err; ANALYZE_START_TRACKING(thd, &explain->command_tracker); @@ -1387,7 +1387,7 @@ produce_explain_and_leave: We come here for various "degenerate" query plans: impossible WHERE, no-partitions-used, impossible-range, etc. */ - if (unlikely(!query_plan.save_explain_update_data(query_plan.mem_root, thd))) + if (unlikely(!query_plan.save_explain_update_data(thd, query_plan.mem_root))) goto err; emit_explain_and_leave: diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index a98a3952726..ffa6eb9c79f 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -99,7 +99,6 @@ int yylex(void *yylval, void *yythd); #define MYSQL_YYABORT \ do \ { \ - LEX::cleanup_lex_after_parse_error(thd); \ YYABORT; \ } while (0) @@ -150,13 +149,6 @@ static Item* escape(THD *thd) static void yyerror(THD *thd, const char *s) { - /* - Restore the original LEX if it was replaced when parsing - a stored procedure. We must ensure that a parsing error - does not leave any side effects in the THD. - */ - LEX::cleanup_lex_after_parse_error(thd); - /* "parse error" changed into "syntax error" between bison 1.75 and 1.875 */ if (strcmp(s,"parse error") == 0 || strcmp(s,"syntax error") == 0) s= ER_THD(thd, ER_SYNTAX_ERROR); @@ -1321,6 +1313,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); sp_opt_label BIN_NUM TEXT_STRING_filesystem opt_constraint constraint opt_ident sp_block_label sp_control_label opt_place opt_db + udt_name %type IDENT_sys @@ -1554,6 +1547,19 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); %type expr_lex +%destructor +{ + /* + In case of a syntax/oom error let's free the sp_expr_lex + instance, but only if it has not been linked to any structures + such as sp_instr_jump_if_not::m_lex_keeper yet, e.g.: + IF f1() THEN1 + i.e. THEN1 came instead of the expected THEN causing a syntax error. + */ + if (!$$->sp_lex_in_use) + delete $$; +} + %type assignment_source_lex assignment_source_expr @@ -1563,6 +1569,21 @@ bool my_yyoverflow(short **a, YYSTYPE **b, size_t *yystacksize); cursor_actual_parameters opt_parenthesized_cursor_actual_parameters +%destructor +{ + if ($$) + { + sp_assignment_lex *elem; + List_iterator li(*$$); + while ((elem= li++)) + { + if (!elem->sp_lex_in_use) + delete elem; + } + } +} + + %type option_type opt_var_type opt_var_ident_type @@ -3861,7 +3882,6 @@ expr_lex: expr { $$= $1; - $$->sp_lex_in_use= true; $$->set_item($2); Lex->pop_select(); //min select if (Lex->check_cte_dependencies_and_resolve_references()) @@ -3893,7 +3913,6 @@ assignment_source_expr: { DBUG_ASSERT($1 == thd->lex); $$= $1; - $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, thd->free_list); thd->free_list= NULL; Lex->pop_select(); //min select @@ -3914,7 +3933,6 @@ for_loop_bound_expr: { DBUG_ASSERT($1 == thd->lex); $$= $1; - $$->sp_lex_in_use= true; $$->set_item_and_free_list($3, NULL); Lex->pop_select(); //main select if (unlikely($$->sphead->restore_lex(thd))) @@ -6027,23 +6045,19 @@ qualified_field_type: } ; +udt_name: + IDENT_sys { $$= $1; } + | reserved_keyword_udt { $$= $1; } + | non_reserved_keyword_udt { $$= $1; } + ; + field_type_all: field_type_numeric | field_type_temporal | field_type_string | field_type_lob | field_type_misc - | IDENT_sys float_options srid_option - { - if (Lex->set_field_type_udt(&$$, $1, $2)) - MYSQL_YYABORT; - } - | reserved_keyword_udt float_options srid_option - { - if (Lex->set_field_type_udt(&$$, $1, $2)) - MYSQL_YYABORT; - } - | non_reserved_keyword_udt float_options srid_option + | udt_name float_options srid_option { if (Lex->set_field_type_udt(&$$, $1, $2)) MYSQL_YYABORT; @@ -11190,17 +11204,7 @@ cast_type: } | cast_type_numeric { $$= $1; } | cast_type_temporal { $$= $1; } - | IDENT_sys - { - if (Lex->set_cast_type_udt(&$$, $1)) - MYSQL_YYABORT; - } - | reserved_keyword_udt - { - if (Lex->set_cast_type_udt(&$$, $1)) - MYSQL_YYABORT; - } - | non_reserved_keyword_udt + | udt_name { if (Lex->set_cast_type_udt(&$$, $1)) MYSQL_YYABORT; diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index 05c92dba8f0..7298872e95e 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -6586,8 +6586,9 @@ static Sys_var_ulong Sys_log_slow_rate_limit( SESSION_VAR(log_slow_rate_limit), CMD_LINE(REQUIRED_ARG), VALID_RANGE(1, UINT_MAX), DEFAULT(1), BLOCK_SIZE(1)); -static const char *log_slow_verbosity_names[]= { "innodb", "query_plan", - "explain", 0 }; +static const char *log_slow_verbosity_names[]= +{ "innodb", "query_plan", "explain", "engine", "full", 0}; + static Sys_var_set Sys_log_slow_verbosity( "log_slow_verbosity", "Verbosity level for the slow log", diff --git a/sql/table.cc b/sql/table.cc index 15a73275d02..86f06ea3a5b 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5695,6 +5695,12 @@ void TABLE::init(THD *thd, TABLE_LIST *tl) (*f_ptr)->cond_selectivity= 1.0; } + /* enable and clear or disable engine query statistics */ + if (thd->should_collect_handler_stats()) + file->ha_handler_stats_reset(); + else + file->ha_handler_stats_disable(); + notnull_cond= 0; DBUG_ASSERT(!file->keyread_enabled()); diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 8b66f3d3871..08be1991f02 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -218,9 +218,10 @@ ATTRIBUTE_COLD void btr_decryption_failed(const dict_index_t &index) @param[out] err error code @return block */ buf_block_t *btr_block_get(const dict_index_t &index, - uint32_t page, ulint mode, bool merge, + uint32_t page, rw_lock_type_t mode, bool merge, mtr_t *mtr, dberr_t *err) { + ut_ad(mode != RW_NO_LATCH); dberr_t local_err; if (!err) err= &local_err; @@ -281,11 +282,13 @@ btr_root_block_get( if (UNIV_LIKELY(block != nullptr)) { - if (!!page_is_comp(block->page.frame) != index->table->not_redundant() || - btr_page_get_index_id(block->page.frame) != index->id || - !fil_page_index_page_check(block->page.frame) || - index->is_spatial() != - (fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE)) + if (UNIV_UNLIKELY(mode == RW_NO_LATCH)); + else if (!!page_is_comp(block->page.frame) != + index->table->not_redundant() || + btr_page_get_index_id(block->page.frame) != index->id || + !fil_page_index_page_check(block->page.frame) || + index->is_spatial() != + (fil_page_get_type(block->page.frame) == FIL_PAGE_RTREE)) { *err= DB_PAGE_CORRUPTED; block= nullptr; @@ -515,18 +518,16 @@ static buf_block_t *btr_get_latched_root(const dict_index_t &index, mtr_t *mtr) mini-transaction. */ static buf_block_t * btr_block_reget(mtr_t *mtr, const dict_index_t &index, - const page_id_t id, rw_lock_type_t rw_latch, - dberr_t *err) + const page_id_t id, dberr_t *err) { - if (buf_block_t *block= - mtr->get_already_latched(id, mtr_memo_type_t(rw_latch))) + if (buf_block_t *block= mtr->get_already_latched(id, MTR_MEMO_PAGE_X_FIX)) { *err= DB_SUCCESS; return block; } ut_ad(mtr->memo_contains_flagged(&index.lock, MTR_MEMO_X_LOCK)); - return btr_block_get(index, id.page_no(), rw_latch, true, mtr, err); + return btr_block_get(index, id.page_no(), RW_X_LATCH, true, mtr, err); } /**************************************************************//** @@ -585,21 +586,15 @@ btr_page_alloc_low( if (UNIV_UNLIKELY(!root)) return root; - if (mtr->have_u_or_x_latch(*root)) - { + const bool have_latch= mtr->have_u_or_x_latch(*root); #ifdef BTR_CUR_HASH_ADAPT - ut_ad(!root->index || !root->index->freed()); + ut_ad(!have_latch || !root->index || !root->index->freed()); #endif - mtr->rollback_to_savepoint(savepoint); - } - else - { - mtr->lock_register(savepoint, MTR_MEMO_PAGE_SX_FIX); - root->page.lock.u_lock(); -#ifdef BTR_CUR_HASH_ADAPT - btr_search_drop_page_hash_index(root, true); -#endif - } + mtr->rollback_to_savepoint(savepoint); + + if (!have_latch && + UNIV_UNLIKELY(!(root= btr_root_block_get(index, RW_SX_LATCH, mtr, err)))) + return root; fseg_header_t *seg_header= root->page.frame + (level ? PAGE_HEADER + PAGE_BTR_SEG_TOP : PAGE_HEADER + PAGE_BTR_SEG_LEAF); @@ -696,26 +691,18 @@ dberr_t btr_page_free(dict_index_t* index, buf_block_t* block, mtr_t* mtr, const auto savepoint= mtr->get_savepoint(); if (buf_block_t *root= btr_root_block_get(index, RW_NO_LATCH, mtr, &err)) { - if (mtr->have_u_or_x_latch(*root)) - { + const bool have_latch= mtr->have_u_or_x_latch(*root); #ifdef BTR_CUR_HASH_ADAPT - ut_ad(!root->index || !root->index->freed()); + ut_ad(!have_latch || !root->index || !root->index->freed()); #endif - mtr->rollback_to_savepoint(savepoint); - } - else - { - mtr->lock_register(savepoint, MTR_MEMO_PAGE_SX_FIX); - root->page.lock.u_lock(); -#ifdef BTR_CUR_HASH_ADAPT - btr_search_drop_page_hash_index(root, true); -#endif - } - err= fseg_free_page(&root->page.frame[blob || - page_is_leaf(block->page.frame) - ? PAGE_HEADER + PAGE_BTR_SEG_LEAF - : PAGE_HEADER + PAGE_BTR_SEG_TOP], - space, page, mtr, space_latched); + mtr->rollback_to_savepoint(savepoint); + if (have_latch || + (root= btr_root_block_get(index, RW_SX_LATCH, mtr, &err))) + err= fseg_free_page(&root->page.frame[blob || + page_is_leaf(block->page.frame) + ? PAGE_HEADER + PAGE_BTR_SEG_LEAF + : PAGE_HEADER + PAGE_BTR_SEG_TOP], + space, page, mtr, space_latched); } if (err == DB_SUCCESS) buf_page_free(space, page, mtr); @@ -4295,7 +4282,7 @@ btr_discard_page( if (left_page_no != FIL_NULL) { merge_page_id.set_page_no(left_page_no); merge_block = btr_block_reget(mtr, *index, merge_page_id, - RW_X_LATCH, &err); + &err); if (UNIV_UNLIKELY(!merge_block)) { return err; } @@ -4321,7 +4308,7 @@ btr_discard_page( } else if (right_page_no != FIL_NULL) { merge_page_id.set_page_no(right_page_no); merge_block = btr_block_reget(mtr, *index, merge_page_id, - RW_X_LATCH, &err); + &err); if (UNIV_UNLIKELY(!merge_block)) { return err; } diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index bdea0c85a90..a4dd5061381 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -938,6 +938,76 @@ static inline page_cur_mode_t btr_cur_nonleaf_mode(page_cur_mode_t mode) return PAGE_CUR_LE; } +static MY_ATTRIBUTE((nonnull)) +/** Acquire a latch on the previous page without violating the latching order. +@param block index page +@param page_id page identifier with valid space identifier +@param zip_size ROW_FORMAT=COMPRESSED page size, or 0 +@param rw_latch the latch on block (RW_S_LATCH or RW_X_LATCH) +@param mtr mini-transaction +@param err error code +@retval 0 if an error occurred +@retval 1 if the page could be latched in the wrong order +@retval -1 if the latch on block was temporarily released */ +int btr_latch_prev(buf_block_t *block, page_id_t page_id, ulint zip_size, + rw_lock_type_t rw_latch, mtr_t *mtr, dberr_t *err) +{ + ut_ad(rw_latch == RW_S_LATCH || rw_latch == RW_X_LATCH); + ut_ad(page_id.space() == block->page.id().space()); + + const auto prev_savepoint= mtr->get_savepoint(); + ut_ad(block == mtr->at_savepoint(prev_savepoint - 1)); + + page_id.set_page_no(btr_page_get_prev(block->page.frame)); + buf_block_t *prev= buf_page_get_gen(page_id, zip_size, RW_NO_LATCH, nullptr, + BUF_GET, mtr, err, false); + if (UNIV_UNLIKELY(!prev)) + return 0; + + int ret= 1; + if (UNIV_UNLIKELY(rw_latch == RW_S_LATCH)) + { + if (UNIV_LIKELY(prev->page.lock.s_lock_try())) + { + mtr->lock_register(prev_savepoint, MTR_MEMO_PAGE_S_FIX); + goto prev_latched; + } + block->page.lock.s_unlock(); + } + else + { + if (UNIV_LIKELY(prev->page.lock.x_lock_try())) + { + mtr->lock_register(prev_savepoint, MTR_MEMO_PAGE_X_FIX); + goto prev_latched; + } + block->page.lock.x_unlock(); + } + + ret= -1; + mtr->lock_register(prev_savepoint - 1, MTR_MEMO_BUF_FIX); + mtr->rollback_to_savepoint(prev_savepoint); + prev= buf_page_get_gen(page_id, zip_size, rw_latch, prev, + BUF_GET, mtr, err, false); + if (UNIV_UNLIKELY(!prev)) + return 0; + mtr->upgrade_buffer_fix(prev_savepoint - 1, rw_latch); + + prev_latched: + if (memcmp_aligned<2>(FIL_PAGE_TYPE + prev->page.frame, + FIL_PAGE_TYPE + block->page.frame, 2) || + memcmp_aligned<2>(PAGE_HEADER + PAGE_INDEX_ID + prev->page.frame, + PAGE_HEADER + PAGE_INDEX_ID + block->page.frame, 8) || + page_is_comp(prev->page.frame) != page_is_comp(block->page.frame)) + { + ut_ad("corrupted" == 0); // FIXME: remove this + *err= DB_CORRUPTION; + ret= 0; + } + + return ret; +} + dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, btr_latch_mode latch_mode, mtr_t *mtr) { @@ -1193,11 +1263,12 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, page_cur.block= block; ut_ad(block == mtr->at_savepoint(block_savepoint)); + ut_ad(rw_latch != RW_NO_LATCH); #ifdef UNIV_ZIP_DEBUG - if (rw_latch == RW_NO_LATCH); - else if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block)) + if (const page_zip_des_t *page_zip= buf_block_get_page_zip(block)) ut_a(page_zip_validate(page_zip, block->page.frame, index())); #endif /* UNIV_ZIP_DEBUG */ + const uint32_t page_level= btr_page_get_level(block->page.frame); if (height == ULINT_UNDEFINED) @@ -1241,7 +1312,7 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, goto reached_index_root_and_leaf; goto reached_root_and_leaf; case RW_NO_LATCH: - ut_ad(mtr->memo_contains_flagged(&index()->lock, MTR_MEMO_X_LOCK)); + ut_ad(0); } goto reached_leaf; } @@ -1258,14 +1329,8 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, if (tree_height <= height + 2) /* Retain the root page latch. */ break; - goto release_parent_page; + /* fall through */ default: - if (rw_latch == RW_NO_LATCH) - { - ut_ad(!height); - break; - } - release_parent_page: ut_ad(block_savepoint > savepoint); mtr->rollback_to_savepoint(block_savepoint - 1, block_savepoint); block_savepoint--; @@ -1302,29 +1367,20 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode, static_assert(BTR_MODIFY_PREV & BTR_MODIFY_LEAF, ""); static_assert(BTR_SEARCH_PREV & BTR_SEARCH_LEAF, ""); ut_ad(!latch_by_caller); + ut_ad(rw_latch == + rw_lock_type_t(latch_mode & (RW_X_LATCH | RW_S_LATCH))); - if (rw_latch == RW_NO_LATCH) - { - /* latch also siblings from left to right */ - rw_latch= rw_lock_type_t(latch_mode & (RW_X_LATCH | RW_S_LATCH)); - if (page_has_prev(block->page.frame) && - !btr_block_get(*index(), btr_page_get_prev(block->page.frame), - rw_latch, false, mtr, &err)) - goto func_exit; - mtr->upgrade_buffer_fix(block_savepoint, rw_latch); - if (page_has_next(block->page.frame) && - !btr_block_get(*index(), btr_page_get_next(block->page.frame), - rw_latch, false, mtr, &err)) - goto func_exit; - } + /* latch also siblings from left to right */ + if (page_has_prev(block->page.frame) && + !btr_latch_prev(block, page_id, zip_size, rw_latch, mtr, &err)) + goto func_exit; + if (page_has_next(block->page.frame) && + !btr_block_get(*index(), btr_page_get_next(block->page.frame), + rw_latch, false, mtr, &err)) + goto func_exit; goto release_tree; case BTR_SEARCH_LEAF: case BTR_MODIFY_LEAF: - if (rw_latch == RW_NO_LATCH) - { - ut_ad(index()->is_ibuf()); - mtr->upgrade_buffer_fix(block_savepoint, rw_lock_type_t(latch_mode)); - } if (!latch_by_caller) { release_tree: @@ -1338,13 +1394,11 @@ release_tree: break; default: ut_ad(latch_mode == BTR_MODIFY_TREE); - ut_ad(rw_latch == RW_NO_LATCH); + ut_ad(rw_latch == RW_X_LATCH); /* x-latch also siblings from left to right */ if (page_has_prev(block->page.frame) && - !btr_block_get(*index(), btr_page_get_prev(block->page.frame), - RW_X_LATCH, false, mtr, &err)) + !btr_latch_prev(block, page_id, zip_size, rw_latch, mtr, &err)) goto func_exit; - mtr->upgrade_buffer_fix(block_savepoint, RW_X_LATCH); if (page_has_next(block->page.frame) && !btr_block_get(*index(), btr_page_get_next(block->page.frame), RW_X_LATCH, false, mtr, &err)) @@ -1492,25 +1546,15 @@ release_tree: page_rec_is_first(page_cur.rec, block->page.frame)) { ut_ad(block_savepoint + 1 == mtr->get_savepoint()); + /* Latch the previous page if the node pointer is the leftmost of the current page. */ - buf_block_t *left= btr_block_get(*index(), - btr_page_get_prev(block->page.frame), - RW_NO_LATCH, false, mtr, &err); - if (UNIV_UNLIKELY(!left)) + int ret= btr_latch_prev(block, page_id, zip_size, rw_latch, mtr, &err); + if (!ret) goto func_exit; ut_ad(block_savepoint + 2 == mtr->get_savepoint()); - if (UNIV_LIKELY(left->page.lock.s_lock_try())) - mtr->lock_register(block_savepoint + 1, MTR_MEMO_PAGE_S_FIX); - else + if (ret < 0) { - if (rw_latch == RW_S_LATCH) - block->page.lock.s_unlock(); - else - block->page.lock.x_unlock(); - mtr->upgrade_buffer_fix(block_savepoint + 1, RW_S_LATCH); - mtr->lock_register(block_savepoint, MTR_MEMO_BUF_FIX); - mtr->upgrade_buffer_fix(block_savepoint, RW_S_LATCH); /* While our latch on the level-2 page prevents splits or merges of this level-1 block, other threads may have modified it due to splitting or merging some level-0 (leaf) @@ -1525,13 +1569,12 @@ release_tree: offsets)); } } - goto leaf_with_no_latch; + rw_latch= rw_lock_type_t(latch_mode & (RW_X_LATCH | RW_S_LATCH)); + break; case BTR_MODIFY_LEAF: case BTR_SEARCH_LEAF: - if (index()->is_ibuf()) - goto leaf_with_no_latch; rw_latch= rw_lock_type_t(latch_mode); - if (btr_op != BTR_NO_OP && + if (btr_op != BTR_NO_OP && !index()->is_ibuf() && ibuf_should_try(index(), btr_op != BTR_INSERT_OP)) /* Try to buffer the operation if the leaf page is not in the buffer pool. */ @@ -1551,10 +1594,9 @@ release_tree: mtr->rollback_to_savepoint(block_savepoint); goto need_opposite_intention; } - /* fall through */ + break; default: - leaf_with_no_latch: - rw_latch= RW_NO_LATCH; + ut_ad(rw_latch == RW_X_LATCH); } } @@ -1579,8 +1621,8 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple, ut_ad(index()->is_btree() || index()->is_ibuf()); ut_ad(!index()->is_ibuf() || ibuf_inside(mtr)); - rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; - rec_offs* offsets = offsets_; + rec_offs offsets_[REC_OFFS_NORMAL_SIZE]; + rec_offs* offsets= offsets_; rec_offs_init(offsets_); ut_ad(flag == BTR_CUR_BINARY); @@ -1654,9 +1696,8 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple, /* Go to the child node */ page_id.set_page_no(btr_node_ptr_get_child_page_no(page_cur.rec, offsets)); - const auto block_savepoint= mtr->get_savepoint(); block= - buf_page_get_gen(page_id, block->zip_size(), RW_NO_LATCH, nullptr, BUF_GET, + buf_page_get_gen(page_id, block->zip_size(), RW_X_LATCH, nullptr, BUF_GET, mtr, &err, !--height && !index()->is_clust()); if (!block) @@ -1675,15 +1716,15 @@ dberr_t btr_cur_t::pessimistic_search_leaf(const dtuple_t *tuple, if (height != btr_page_get_level(block->page.frame)) goto corrupted; - if (page_has_prev(block->page.frame) && - !btr_block_get(*index(), btr_page_get_prev(block->page.frame), - RW_X_LATCH, false, mtr, &err)) - goto func_exit; - mtr->upgrade_buffer_fix(block_savepoint, RW_X_LATCH); #ifdef UNIV_ZIP_DEBUG const page_zip_des_t *page_zip= buf_block_get_page_zip(block); ut_a(!page_zip || page_zip_validate(page_zip, block->page.frame, index())); #endif /* UNIV_ZIP_DEBUG */ + + if (page_has_prev(block->page.frame) && + !btr_latch_prev(block, page_id, block->zip_size(), + RW_X_LATCH, mtr, &err)) + goto func_exit; if (page_has_next(block->page.frame) && !btr_block_get(*index(), btr_page_get_next(block->page.frame), RW_X_LATCH, false, mtr, &err)) @@ -1896,13 +1937,10 @@ index_locked: ut_ad(n_blocks < BTR_MAX_LEVELS); ut_ad(savepoint + n_blocks == mtr->get_savepoint()); - const rw_lock_type_t rw_latch= height && latch_mode != BTR_MODIFY_TREE - ? upper_rw_latch - : RW_NO_LATCH; buf_block_t* block= - btr_block_get(*index, page, rw_latch, !height && !index->is_clust(), mtr, - &err); - + btr_block_get(*index, page, + height ? upper_rw_latch : root_leaf_rw_latch, + !height, mtr, &err); ut_ad(!block == (err != DB_SUCCESS)); if (!block) @@ -1944,13 +1982,11 @@ index_locked: if (latch_mode == BTR_MODIFY_TREE) { - ut_ad(rw_latch == RW_NO_LATCH); /* x-latch also siblings from left to right */ if (page_has_prev(block->page.frame) && - !btr_block_get(*index, btr_page_get_prev(block->page.frame), - RW_X_LATCH, false, mtr, &err)) + !btr_latch_prev(block, block->page.id(), zip_size, RW_X_LATCH, + mtr, &err)) break; - mtr->upgrade_buffer_fix(leaf_savepoint - 1, RW_X_LATCH); if (page_has_next(block->page.frame) && !btr_block_get(*index, btr_page_get_next(block->page.frame), RW_X_LATCH, false, mtr, &err)) @@ -1965,10 +2001,6 @@ index_locked: } else { - if (rw_latch == RW_NO_LATCH) - mtr->upgrade_buffer_fix(leaf_savepoint - 1, - rw_lock_type_t(latch_mode & - (RW_X_LATCH | RW_S_LATCH))); if (latch_mode != BTR_CONT_MODIFY_TREE) { ut_ad(latch_mode == BTR_MODIFY_LEAF || @@ -2038,21 +2070,6 @@ index_locked: n_blocks= 1; } } - - if (!height) - { - if (page == index->page) - mtr->upgrade_buffer_fix(savepoint, RW_X_LATCH); - else - { - /* The U-latch protects BTR_SEG_HEAP, BTR_SEG_TOP. */ - mtr->upgrade_buffer_fix(savepoint, RW_SX_LATCH); - - /* Upgrade buffer-fix to exclusive latches on all remaining pages. */ - for (ulint i= 1; i <= n_blocks; i++) - mtr->upgrade_buffer_fix(savepoint + i, RW_X_LATCH); - } - } } /* Go to the child node */ diff --git a/storage/innobase/btr/btr0pcur.cc b/storage/innobase/btr/btr0pcur.cc index 1dd26f8c467..54dd15ac603 100644 --- a/storage/innobase/btr/btr0pcur.cc +++ b/storage/innobase/btr/btr0pcur.cc @@ -540,7 +540,8 @@ btr_pcur_move_to_next_page( dberr_t err; buf_block_t* next_block = btr_block_get( - *cursor->index(), next_page_no, cursor->latch_mode & ~12, + *cursor->index(), next_page_no, + rw_lock_type_t(cursor->latch_mode & (RW_X_LATCH | RW_S_LATCH)), page_is_leaf(page), mtr, &err); if (UNIV_UNLIKELY(!next_block)) { diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 64637b71632..2be74e73ff7 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -36,6 +36,7 @@ Created 11/5/1995 Heikki Tuuri #include "mach0data.h" #include "buf0buf.h" #include "buf0checksum.h" +#include "mariadb_stats.h" #include #ifdef UNIV_INNOCHECKSUM @@ -2166,6 +2167,7 @@ buf_page_t* buf_page_get_zip(const page_id_t page_id, ulint zip_size) ut_ad(zip_size); ut_ad(ut_is_2pow(zip_size)); ++buf_pool.stat.n_page_gets; + mariadb_increment_pages_accessed(); buf_pool_t::hash_chain &chain= buf_pool.page_hash.cell_get(page_id.fold()); page_hash_latch &hash_lock= buf_pool.page_hash.lock_get(chain); @@ -2261,6 +2263,7 @@ must_read_page: switch (dberr_t err= buf_read_page(page_id, zip_size)) { case DB_SUCCESS: case DB_SUCCESS_LOCKED_REC: + mariadb_increment_pages_read(); goto lookup; default: ib::error() << "Reading compressed page " << page_id @@ -2438,6 +2441,7 @@ buf_page_get_low( || ibuf_page_low(page_id, zip_size, FALSE, NULL)); ++buf_pool.stat.n_page_gets; + mariadb_increment_pages_accessed(); auto& chain= buf_pool.page_hash.cell_get(page_id.fold()); page_hash_latch& hash_lock = buf_pool.page_hash.lock_get(chain); @@ -2509,6 +2513,7 @@ loop: switch (dberr_t local_err = buf_read_page(page_id, zip_size)) { case DB_SUCCESS: case DB_SUCCESS_LOCKED_REC: + mariadb_increment_pages_read(); buf_read_ahead_random(page_id, zip_size, ibuf_inside(mtr)); break; default: @@ -3069,7 +3074,6 @@ bool buf_page_optimistic_get(ulint rw_latch, buf_block_t *block, ut_ad(~buf_page_t::LRU_MASK & state); ut_ad(block->page.frame); - ++buf_pool.stat.n_page_gets; return true; } @@ -3107,6 +3111,7 @@ buf_block_t *buf_page_try_get(const page_id_t page_id, mtr_t *mtr) ut_ad(block->page.id() == page_id); ++buf_pool.stat.n_page_gets; + mariadb_increment_pages_accessed(); return block; } diff --git a/storage/innobase/buf/buf0rea.cc b/storage/innobase/buf/buf0rea.cc index cf76a9bd93a..dae1527dde6 100644 --- a/storage/innobase/buf/buf0rea.cc +++ b/storage/innobase/buf/buf0rea.cc @@ -42,6 +42,7 @@ Created 11/5/1995 Heikki Tuuri #include "srv0start.h" #include "srv0srv.h" #include "log.h" +#include "mariadb_stats.h" /** If there are buf_pool.curr_size per the number below pending reads, then read-ahead is not done: this is to prevent flooding the buffer pool with @@ -295,9 +296,12 @@ buf_read_page_low( } ut_ad(bpage->in_file()); + ulonglong mariadb_timer= 0; if (sync) { thd_wait_begin(nullptr, THD_WAIT_DISKIO); + if (mariadb_stats_active()) + mariadb_timer= mariadb_measure(); } DBUG_LOG("ib_buf", @@ -322,6 +326,8 @@ buf_read_page_low( if (fio.err == DB_FAIL) { fio.err = DB_PAGE_CORRUPTED; } + if (mariadb_timer) + mariadb_increment_pages_read_time(mariadb_timer); } return fio.err; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 2e8d87dad9e..d22f7eb3272 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -514,15 +514,17 @@ static bool dict_stats_persistent_storage_check(bool dict_already_locked) dict_sys.unlock(); } - if (ret != DB_SUCCESS && ret != DB_STATS_DO_NOT_EXIST) { - ib::error() << errstr; - return(false); - } else if (ret == DB_STATS_DO_NOT_EXIST) { + switch (ret) { + case DB_SUCCESS: + return true; + default: + if (!opt_bootstrap) { + ib::error() << errstr; + } + /* fall through */ + case DB_STATS_DO_NOT_EXIST: return false; } - /* else */ - - return(true); } /** Executes a given SQL statement using the InnoDB internal SQL parser. diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index eb0fb3601a1..d7c810d69ff 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -362,8 +362,20 @@ static bool fil_node_open_file_low(fil_node_t *node) : OS_FILE_OPEN | OS_FILE_ON_ERROR_NO_EXIT, OS_FILE_AIO, type, srv_read_only_mode, &success); - if (success) + if (node->is_open()) + { + ut_ad(success); +#ifndef _WIN32 + if (!node->space->id && !srv_read_only_mode && my_disable_locking && + os_file_lock(node->handle, node->name)) + { + os_file_close(node->handle); + node->handle= OS_FILE_CLOSED; + return false; + } +#endif break; + } /* The following call prints an error message */ if (os_file_get_last_error(true) == EMFILE + 100 && diff --git a/storage/innobase/fsp/fsp0sysspace.cc b/storage/innobase/fsp/fsp0sysspace.cc index 9aef6f389ef..3016f71afad 100644 --- a/storage/innobase/fsp/fsp0sysspace.cc +++ b/storage/innobase/fsp/fsp0sysspace.cc @@ -393,11 +393,11 @@ SysTablespace::set_size( Datafile& file) { ut_ad(!srv_read_only_mode || m_ignore_read_only); + const ib::bytes_iec b{uint64_t{file.m_size} << srv_page_size_shift}; /* We created the data file and now write it full of zeros */ - ib::info() << "Setting file '" << file.filepath() << "' size to " - << ib::bytes_iec{file.m_size << srv_page_size_shift} << - ". Physically writing the file full; Please wait ..."; + ib::info() << "Setting file '" << file.filepath() << "' size to " << b + << ". Physically writing the file full; Please wait ..."; bool success = os_file_set_size( file.m_filepath, file.m_handle, @@ -405,7 +405,7 @@ SysTablespace::set_size( if (success) { ib::info() << "File '" << file.filepath() << "' size is now " - << ib::bytes_iec{file.m_size << srv_page_size_shift} + << b << "."; } else { ib::error() << "Could not set the file size of '" diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index d55e1b8ef44..0c00fef9272 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -112,6 +112,9 @@ this program; if not, write to the Free Software Foundation, Inc., #include "fil0pagecompress.h" #include "ut0mem.h" #include "row0ext.h" +#include "mariadb_stats.h" +thread_local ha_handler_stats mariadb_dummy_stats; +thread_local ha_handler_stats *mariadb_stats= &mariadb_dummy_stats; #include "lz4.h" #include "lzo/lzo1x.h" @@ -1001,8 +1004,8 @@ static SHOW_VAR innodb_status_variables[]= { {"row_lock_current_waits", &export_vars.innodb_row_lock_current_waits, SHOW_SIZE_T}, {"row_lock_time", &export_vars.innodb_row_lock_time, SHOW_LONGLONG}, - {"row_lock_time_avg", &export_vars.innodb_row_lock_time_avg, SHOW_SIZE_T}, - {"row_lock_time_max", &export_vars.innodb_row_lock_time_max, SHOW_SIZE_T}, + {"row_lock_time_avg", &export_vars.innodb_row_lock_time_avg, SHOW_ULONGLONG}, + {"row_lock_time_max", &export_vars.innodb_row_lock_time_max, SHOW_ULONGLONG}, {"row_lock_waits", &export_vars.innodb_row_lock_waits, SHOW_SIZE_T}, {"num_open_files", &fil_system.n_open, SHOW_SIZE_T}, {"truncated_status_writes", &truncated_status_writes, SHOW_SIZE_T}, @@ -7781,6 +7784,7 @@ ha_innobase::write_row( #endif int error_result = 0; bool auto_inc_used = false; + mariadb_set_stats set_stats_temporary(handler_stats); DBUG_ENTER("ha_innobase::write_row"); @@ -8541,6 +8545,7 @@ ha_innobase::update_row( dberr_t error; trx_t* trx = thd_to_trx(m_user_thd); + mariadb_set_stats set_stats_temporary(handler_stats); DBUG_ENTER("ha_innobase::update_row"); @@ -8720,6 +8725,7 @@ ha_innobase::delete_row( { dberr_t error; trx_t* trx = thd_to_trx(m_user_thd); + mariadb_set_stats set_stats_temporary(handler_stats); DBUG_ENTER("ha_innobase::delete_row"); @@ -8963,6 +8969,7 @@ ha_innobase::index_read( enum ha_rkey_function find_flag)/*!< in: search flags from my_base.h */ { DBUG_ENTER("index_read"); + mariadb_set_stats set_stats_temporary(handler_stats); DEBUG_SYNC_C("ha_innobase_index_read_begin"); ut_a(m_prebuilt->trx == thd_to_trx(m_user_thd)); @@ -9282,6 +9289,7 @@ ha_innobase::general_fetch( { DBUG_ENTER("general_fetch"); + mariadb_set_stats set_stats_temporary(handler_stats); const trx_t* trx = m_prebuilt->trx; ut_ad(trx == thd_to_trx(m_user_thd)); @@ -9482,7 +9490,6 @@ ha_innobase::rnd_next( in MySQL format */ { int error; - DBUG_ENTER("rnd_next"); if (m_start_of_scan) { @@ -9747,6 +9754,7 @@ ha_innobase::ft_read( uchar* buf) /*!< in/out: buf contain result row */ { row_prebuilt_t* ft_prebuilt; + mariadb_set_stats set_stats_temporary(handler_stats); ft_prebuilt = reinterpret_cast(ft_handler)->ft_prebuilt; @@ -13788,6 +13796,7 @@ static dberr_t innobase_rename_table(trx_t *trx, const char *from, @retval 0 on success */ int ha_innobase::truncate() { + mariadb_set_stats set_stats_temporary(handler_stats); DBUG_ENTER("ha_innobase::truncate"); update_thd(); @@ -14353,7 +14362,7 @@ ha_innobase::estimate_rows_upper_bound() const dict_index_t* index; ulonglong estimate; ulonglong local_data_file_length; - + mariadb_set_stats set_stats_temporary(handler_stats); DBUG_ENTER("estimate_rows_upper_bound"); /* We do not know if MySQL can call this function before calling @@ -16591,6 +16600,7 @@ ha_innobase::get_auto_increment( trx_t* trx; dberr_t error; ulonglong autoinc = 0; + mariadb_set_stats set_stats_temporary(handler_stats); /* Prepare m_prebuilt->trx in the table handle */ update_thd(ha_thd()); diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 7f071b2149c..1cffeb6230a 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -2156,8 +2156,7 @@ next_page: } next_page= false; - block= btr_block_get(*clust_index, next_page_no, BTR_SEARCH_LEAF, false, - &mtr); + block= btr_block_get(*clust_index, next_page_no, RW_S_LATCH, false, &mtr); if (!block) goto non_empty; page_cur_set_before_first(block, cur); diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 12557b08ebe..b9e94a67e37 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -243,21 +243,11 @@ mysql_mutex_t ibuf_mutex, ibuf_pessimistic_insert_mutex; /** The area in pages from which contract looks for page numbers for merge */ -const ulint IBUF_MERGE_AREA = 8; +constexpr ulint IBUF_MERGE_AREA = 8; -/** Inside the merge area, pages which have at most 1 per this number less -buffered entries compared to maximum volume that can buffered for a single -page are merged along with the page whose buffer became full */ -const ulint IBUF_MERGE_THRESHOLD = 4; - -/** In ibuf_contract at most this number of pages is read to memory in one -batch, in order to merge the entries for them in the insert buffer */ -const ulint IBUF_MAX_N_PAGES_MERGED = IBUF_MERGE_AREA; - -/** If the combined size of the ibuf trees exceeds ibuf.max_size by -this many pages, we start to contract it synchronous contract, but do -not insert */ -const ulint IBUF_CONTRACT_DO_NOT_INSERT = 10; +/** In ibuf_contract() at most this number of pages is read to memory in one +batch, in order to merge the entries for them in the change buffer */ +constexpr ulint IBUF_MAX_N_PAGES_MERGED = IBUF_MERGE_AREA; /* TODO: how to cope with drop table if there are records in the insert buffer for the indexes of the table? Is there actually any problem, @@ -2006,11 +1996,11 @@ ibuf_free_excess_pages(void) } #ifdef UNIV_DEBUG -# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,pages,n_stored) \ - ibuf_get_merge_page_nos_func(contract,rec,mtr,ids,pages,n_stored) +# define ibuf_get_merge_page_nos(rec,mtr,ids,pages,n_stored) \ + ibuf_get_merge_page_nos_func(rec,mtr,ids,pages,n_stored) #else /* UNIV_DEBUG */ -# define ibuf_get_merge_page_nos(contract,rec,mtr,ids,pages,n_stored) \ - ibuf_get_merge_page_nos_func(contract,rec,ids,pages,n_stored) +# define ibuf_get_merge_page_nos(rec,mtr,ids,pages,n_stored) \ + ibuf_get_merge_page_nos_func(rec,ids,pages,n_stored) #endif /* UNIV_DEBUG */ /*********************************************************************//** @@ -2021,10 +2011,6 @@ static ulint ibuf_get_merge_page_nos_func( /*=========================*/ - ibool contract,/*!< in: TRUE if this function is called to - contract the tree, FALSE if this is called - when a single page becomes full and we look - if it pays to read also nearby pages */ const rec_t* rec, /*!< in: insert buffer record */ #ifdef UNIV_DEBUG mtr_t* mtr, /*!< in: mini-transaction holding rec */ @@ -2155,22 +2141,10 @@ corruption: || rec_page_no != prev_page_no) && (prev_space_id != 0 || prev_page_no != 0)) { - if (contract - || (prev_page_no == first_page_no - && prev_space_id == first_space_id) - || (volume_for_page - > ((IBUF_MERGE_THRESHOLD - 1) - * 4U << srv_page_size_shift - / IBUF_PAGE_SIZE_PER_FREE_SPACE) - / IBUF_MERGE_THRESHOLD)) { - - space_ids[*n_stored] = prev_space_id; - page_nos[*n_stored] = prev_page_no; - - (*n_stored)++; - - sum_volumes += volume_for_page; - } + space_ids[*n_stored] = prev_space_id; + page_nos[*n_stored] = prev_page_no; + (*n_stored)++; + sum_volumes += volume_for_page; if (rec_space_id != first_space_id || rec_page_no / IBUF_MERGE_AREA @@ -2430,7 +2404,7 @@ tablespace_deleted: @return a lower limit for the combined size in bytes of entries which will be merged from ibuf trees to the pages read @retval 0 if ibuf.empty */ -ulint ibuf_contract() +ATTRIBUTE_COLD ulint ibuf_contract() { if (UNIV_UNLIKELY(!ibuf.index)) return 0; mtr_t mtr; @@ -2462,10 +2436,8 @@ ulint ibuf_contract() } ulint n_pages = 0; - sum_sizes = ibuf_get_merge_page_nos(TRUE, - btr_cur_get_rec(&cur), &mtr, - space_ids, - page_nos, &n_pages); + sum_sizes = ibuf_get_merge_page_nos(btr_cur_get_rec(&cur), &mtr, + space_ids, page_nos, &n_pages); ibuf_mtr_commit(&mtr); ibuf_read_merge_pages(space_ids, page_nos, n_pages); @@ -2555,30 +2527,6 @@ ibuf_merge_space( return(n_pages); } -/*********************************************************************//** -Contract insert buffer trees after insert if they are too big. */ -UNIV_INLINE -void -ibuf_contract_after_insert( -/*=======================*/ - ulint entry_size) /*!< in: size of a record which was inserted - into an ibuf tree */ -{ - /* dirty comparison, to avoid contention on ibuf_mutex */ - if (ibuf.size < ibuf.max_size) { - return; - } - - /* Contract at least entry_size many bytes */ - ulint sum_sizes = 0; - ulint size; - - do { - size = ibuf_contract(); - sum_sizes += size; - } while (size > 0 && sum_sizes < entry_size); -} - /** Determine if a change buffer record has been encountered already. @param rec change buffer record in the MySQL 5.5 format @param hash hash table of encountered records @@ -3177,10 +3125,6 @@ ibuf_insert_low( buf_block_t* block = NULL; page_t* root; dberr_t err; - ibool do_merge; - uint32_t space_ids[IBUF_MAX_N_PAGES_MERGED]; - uint32_t page_nos[IBUF_MAX_N_PAGES_MERGED]; - ulint n_stored; mtr_t mtr; mtr_t bitmap_mtr; @@ -3191,28 +3135,9 @@ ibuf_insert_low( ut_ad(page_id.space() == index->table->space_id); ut_a(op < IBUF_OP_COUNT); - do_merge = FALSE; - /* Perform dirty comparison of ibuf.max_size and ibuf.size to - reduce ibuf_mutex contention. This should be OK; at worst we - are doing some excessive ibuf_contract() or occasionally - skipping an ibuf_contract(). */ - const ulint max_size = ibuf.max_size; - - if (max_size == 0) { - return(DB_STRONG_FAIL); - } - - if (ibuf.size >= max_size + IBUF_CONTRACT_DO_NOT_INSERT) { - /* Insert buffer is now too big, contract it but do not try - to insert */ - - -#ifdef UNIV_IBUF_DEBUG - fputs("Ibuf too big\n", stderr); -#endif - ibuf_contract(); - + reduce ibuf_mutex contention. */ + if (ibuf.size >= ibuf.max_size) { return(DB_STRONG_FAIL); } @@ -3264,17 +3189,6 @@ func_exit: ibuf_mtr_commit(&mtr); ut_free(pcur.old_rec_buf); mem_heap_free(heap); - - if (err == DB_SUCCESS && mode == BTR_INSERT_TREE) { - ibuf_contract_after_insert(entry_size); - } - - if (do_merge) { -#ifdef UNIV_IBUF_DEBUG - ut_a(n_stored <= IBUF_MAX_N_PAGES_MERGED); -#endif - ibuf_read_merge_pages(space_ids, page_nos, n_stored); - } return err; } @@ -3364,15 +3278,6 @@ commit_exit: bits)) { /* Release the bitmap page latch early. */ ibuf_mtr_commit(&bitmap_mtr); - - /* It may not fit */ - do_merge = TRUE; - - ibuf_get_merge_page_nos(FALSE, - btr_pcur_get_rec(&pcur), &mtr, - space_ids, - page_nos, &n_stored); - goto fail_exit; } } diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index a56598d3620..5a0401fad85 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -91,7 +91,7 @@ ATTRIBUTE_COLD void btr_decryption_failed(const dict_index_t &index); @param[out] err error code @return block */ buf_block_t *btr_block_get(const dict_index_t &index, - uint32_t page, ulint mode, bool merge, + uint32_t page, rw_lock_type_t mode, bool merge, mtr_t *mtr, dberr_t *err= nullptr); /**************************************************************//** diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h index e8299bb1189..4c92984f2f6 100644 --- a/storage/innobase/include/lock0lock.h +++ b/storage/innobase/include/lock0lock.h @@ -755,9 +755,9 @@ private: /** waits and total number of lock waits; protected by wait_mutex */ uint64_t wait_count; /** Cumulative wait time; protected by wait_mutex */ - uint32_t wait_time; + uint64_t wait_time; /** Longest wait time; protected by wait_mutex */ - uint32_t wait_time_max; + uint64_t wait_time_max; public: /** number of deadlocks detected; protected by wait_mutex */ ulint deadlocks; @@ -916,9 +916,9 @@ public: ulint get_wait_cumulative() const { return static_cast(wait_count / WAIT_COUNT_STEP); } /** Cumulative wait time; protected by wait_mutex */ - ulint get_wait_time_cumulative() const { return wait_time; } + uint64_t get_wait_time_cumulative() const { return wait_time; } /** Longest wait time; protected by wait_mutex */ - ulint get_wait_time_max() const { return wait_time_max; } + uint64_t get_wait_time_max() const { return wait_time_max; } /** Get the lock hash table for a mode */ hash_table &hash_get(ulint mode) diff --git a/storage/innobase/include/mariadb_stats.h b/storage/innobase/include/mariadb_stats.h new file mode 100644 index 00000000000..e9051c0c08b --- /dev/null +++ b/storage/innobase/include/mariadb_stats.h @@ -0,0 +1,119 @@ +/***************************************************************************** + +Copyright (c) 2023, MariaDB Foundation + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; version 2 of the License. + +This program is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA + +*****************************************************************************/ + +#ifndef mariadb_stats_h +#define mariadb_stats_h + +/* Include file to handle mariadbd handler specific stats */ + +#include "ha_handler_stats.h" +#include "my_rdtsc.h" + +/* Not active threads are ponting to this structure */ +extern thread_local ha_handler_stats mariadb_dummy_stats; + +/* Points to either THD->handler_stats or mariad_dummy_stats */ +extern thread_local ha_handler_stats *mariadb_stats; + +/* + Returns 1 if MariaDB wants engine status +*/ + +inline bool mariadb_stats_active() +{ + return mariadb_stats->active != 0; +} + +inline bool mariadb_stats_active(ha_handler_stats *stats) +{ + return stats->active != 0; +} + +/* The following functions increment different engine status */ + +inline void mariadb_increment_pages_accessed() +{ + mariadb_stats->pages_accessed++; +} + +inline void mariadb_increment_pages_updated(ulonglong count) +{ + mariadb_stats->pages_updated+= count; +} + +inline void mariadb_increment_pages_read() +{ + mariadb_stats->pages_read_count++; +} + +inline void mariadb_increment_undo_records_read() +{ + mariadb_stats->undo_records_read++; +} + +/* + The following has to be identical code as measure() in sql_analyze_stmt.h + + One should only call this if mariadb_stats_active() is true. +*/ + +inline ulonglong mariadb_measure() +{ +#if (MY_TIMER_ROUTINE_CYCLES) + return my_timer_cycles(); +#else + return my_timer_microseconds(); +#endif +} + +/* + Call this only of start_time != 0 + See buf0rea.cc for an example of how to use it efficiently +*/ + +inline void mariadb_increment_pages_read_time(ulonglong start_time) +{ + ha_handler_stats *stats= mariadb_stats; + ulonglong end_time= mariadb_measure(); + /* Check that we only call this if active, see example! */ + DBUG_ASSERT(start_time); + DBUG_ASSERT(mariadb_stats_active(stats)); + + stats->pages_read_time+= (end_time - start_time); +} + + +/* + Helper class to set mariadb_stats temporarly for one call in handler.cc +*/ + +class mariadb_set_stats +{ +public: + uint flag; + mariadb_set_stats(ha_handler_stats *stats) + { + mariadb_stats= stats ? stats : &mariadb_dummy_stats; + } + ~mariadb_set_stats() + { + mariadb_stats= &mariadb_dummy_stats; + } +}; + +#endif /* mariadb_stats_h */ diff --git a/storage/innobase/include/row0mysql.h b/storage/innobase/include/row0mysql.h index a9f1c87d600..2e5bdceb677 100644 --- a/storage/innobase/include/row0mysql.h +++ b/storage/innobase/include/row0mysql.h @@ -39,6 +39,7 @@ Created 9/17/2000 Heikki Tuuri struct row_prebuilt_t; class ha_innobase; +class ha_handler_stats; /*******************************************************************//** Frees the blob heap in prebuilt when no longer needed. */ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index e14e6b1b1a6..c1cb3c5e71c 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -645,11 +645,9 @@ struct export_var_t{ ulint innodb_row_lock_current_waits; /*!< srv_n_lock_wait_current_count */ int64_t innodb_row_lock_time; /*!< srv_n_lock_wait_time / 1000 */ - ulint innodb_row_lock_time_avg; /*!< srv_n_lock_wait_time - / 1000 - / srv_n_lock_wait_count */ - ulint innodb_row_lock_time_max; /*!< srv_n_lock_max_wait_time - / 1000 */ + uint64_t innodb_row_lock_time_avg; /*!< srv_n_lock_wait_time + / srv_n_lock_wait_count */ + uint64_t innodb_row_lock_time_max; /*!< srv_n_lock_max_wait_time */ /** Number of undo tablespace truncation operations */ ulong innodb_undo_truncations; diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 08547f169f3..6a7e4a2843e 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -1648,8 +1648,8 @@ void lock_sys_t::wait_resume(THD *thd, my_hrtime_t start, my_hrtime_t now) wait_count--; if (now.val >= start.val) { - const uint32_t diff_time= - static_cast((now.val - start.val) / 1000); + const uint64_t diff_time= + static_cast((now.val - start.val) / 1000); wait_time+= diff_time; if (diff_time > wait_time_max) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 042e7981d73..8aba2981092 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1639,7 +1639,10 @@ static dberr_t recv_log_recover_10_5(lsn_t lsn_offset) if (lsn_offset < (log_sys.is_pmem() ? log_sys.file_size : 4096)) memcpy_aligned<512>(buf, &log_sys.buf[lsn_offset & ~511], 512); else - recv_sys.read(lsn_offset & ~lsn_t{511}, {buf, 512}); + { + recv_sys.read(lsn_offset & ~lsn_t{4095}, {buf, 4096}); + buf+= lsn_offset & 0xe00; + } if (!recv_check_log_block(buf)) { @@ -1757,7 +1760,7 @@ dberr_t recv_sys_t::find_checkpoint() if (dberr_t err= recv_log_recover_pre_10_2()) return err; upgrade: - memset_aligned<512>(const_cast(field_ref_zero), 0, 512); + memset_aligned<4096>(const_cast(field_ref_zero), 0, 4096); /* Mark the redo log for upgrading. */ log_sys.last_checkpoint_lsn= log_sys.next_checkpoint_lsn; log_sys.set_recovered_lsn(log_sys.next_checkpoint_lsn); diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index fb08511126a..3a3b6627451 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -34,6 +34,7 @@ Created 11/26/1995 Heikki Tuuri #endif #include "srv0start.h" #include "log.h" +#include "mariadb_stats.h" void mtr_memo_slot_t::release() const { @@ -327,10 +328,10 @@ void mtr_t::commit() ut_ad(!srv_read_only_mode); std::pair lsns{do_write()}; process_freed_pages(); + size_t modified= 0; if (m_made_dirty) { - size_t modified= 0; auto it= m_memo.rbegin(); mysql_mutex_lock(&buf_pool.flush_list_mutex); @@ -386,8 +387,6 @@ void mtr_t::commit() else log_sys.latch.rd_unlock(); - size_t modified= 0; - for (auto it= m_memo.rbegin(); it != m_memo.rend(); ) { const mtr_memo_slot_t &slot= *it++; @@ -446,6 +445,8 @@ void mtr_t::commit() m_memo.clear(); } + mariadb_increment_pages_updated(modified); + if (UNIV_UNLIKELY(lsns.second != PAGE_FLUSH_NO)) buf_flush_ahead(m_commit_lsn, lsns.second == PAGE_FLUSH_SYNC); } diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 766f5000a0d..a862edd786a 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -242,9 +242,11 @@ enum rec_leaf_format { REC_LEAF_INSTANT }; -#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 12 +#if defined __GNUC__ && !defined __clang__ # pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Wconversion" /* GCC 5 to 11 need this */ +# if __GNUC__ < 12 || defined WITH_UBSAN +# pragma GCC diagnostic ignored "-Wconversion" +# endif #endif /** Determine the offset to each field in a leaf-page record in ROW_FORMAT=COMPACT,DYNAMIC,COMPRESSED. @@ -1707,7 +1709,7 @@ rec_convert_dtuple_to_rec_new( REC_INFO_BITS_MASK, REC_INFO_BITS_SHIFT); return buf; } -#if defined __GNUC__ && !defined __clang__ && __GNUC__ < 11 +#if defined __GNUC__ && !defined __clang__ # pragma GCC diagnostic pop /* ignored "-Wconversion" */ #endif diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 1f46da67943..bdee0ed138b 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -3029,8 +3029,8 @@ row_ins_sec_index_entry_low( search_mode = btr_latch_mode( search_mode | (thr_get_trx(thr)->check_unique_secondary - ? BTR_INSERT | BTR_IGNORE_SEC_UNIQUE - : BTR_INSERT)); + ? BTR_INSERT + : BTR_INSERT | BTR_IGNORE_SEC_UNIQUE)); } err = cursor.search_leaf(entry, PAGE_CUR_LE, search_mode, diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc index 03b707e8a4e..1762f309fae 100644 --- a/storage/innobase/srv/srv0mon.cc +++ b/storage/innobase/srv/srv0mon.cc @@ -1513,21 +1513,20 @@ srv_mon_process_existing_counter( /* innodb_row_lock_time */ case MONITOR_OVLD_LOCK_WAIT_TIME: // dirty read without lock_sys.wait_mutex - value = lock_sys.get_wait_time_cumulative() / 1000; + value = lock_sys.get_wait_time_cumulative(); break; /* innodb_row_lock_time_max */ case MONITOR_OVLD_LOCK_MAX_WAIT_TIME: // dirty read without lock_sys.wait_mutex - value = lock_sys.get_wait_time_max() / 1000; + value = lock_sys.get_wait_time_max(); break; /* innodb_row_lock_time_avg */ case MONITOR_OVLD_LOCK_AVG_WAIT_TIME: mysql_mutex_lock(&lock_sys.wait_mutex); if (auto count = lock_sys.get_wait_cumulative()) { - value = lock_sys.get_wait_time_cumulative() / 1000 - / count; + value = lock_sys.get_wait_time_cumulative() / count; } else { value = 0; } diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 7770deb70e1..f3c23ea8abf 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -943,10 +943,9 @@ srv_export_innodb_status(void) export_vars.innodb_row_lock_current_waits= lock_sys.get_wait_pending(); - export_vars.innodb_row_lock_time = lock_sys.get_wait_time_cumulative() - / 1000; - export_vars.innodb_row_lock_time_max = lock_sys.get_wait_time_max() - / 1000; + export_vars.innodb_row_lock_time = lock_sys.get_wait_time_cumulative(); + export_vars.innodb_row_lock_time_max = lock_sys.get_wait_time_max(); + mysql_mutex_unlock(&lock_sys.wait_mutex); export_vars.innodb_row_lock_time_avg= export_vars.innodb_row_lock_waits diff --git a/storage/innobase/trx/trx0rec.cc b/storage/innobase/trx/trx0rec.cc index c1a7b08b717..843c2f66175 100644 --- a/storage/innobase/trx/trx0rec.cc +++ b/storage/innobase/trx/trx0rec.cc @@ -39,6 +39,7 @@ Created 3/26/1996 Heikki Tuuri #include "row0row.h" #include "row0mysql.h" #include "row0ins.h" +#include "mariadb_stats.h" /** The search tuple corresponding to TRX_UNDO_INSERT_METADATA. */ const dtuple_t trx_undo_metadata = { @@ -2182,6 +2183,7 @@ trx_undo_prev_version_build( return DB_SUCCESS; } + mariadb_increment_undo_records_read(); rec_trx_id = row_get_rec_trx_id(rec, index, offsets); ut_ad(!index->table->skip_alter_undo); diff --git a/storage/spider/mysql-test/spider/bugfix/r/self_reference_multi.result b/storage/spider/mysql-test/spider/bugfix/r/self_reference_multi.result index c4399ddf9d2..50db034c8cd 100644 --- a/storage/spider/mysql-test/spider/bugfix/r/self_reference_multi.result +++ b/storage/spider/mysql-test/spider/bugfix/r/self_reference_multi.result @@ -4,11 +4,11 @@ for child3 MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever -CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t2 (c int); -create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; -create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; -alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"'; +create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_self_reference_multi",TABLE "t2"'; +create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_self_reference_multi",TABLE "t1"'; +alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv_self_reference_multi",TABLE "t0"'; select * from t0; ERROR HY000: An infinite loop is detected when opening table test.t0 select * from t1; diff --git a/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test b/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test index 8b6f070d167..a3d561f3fae 100644 --- a/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test +++ b/storage/spider/mysql-test/spider/bugfix/t/self_reference_multi.test @@ -8,12 +8,12 @@ --echo MDEV-6268 SPIDER table with no COMMENT clause causes queries to wait forever --echo ---replace_regex /SOCKET ".*"/SOCKET "$MASTER_1_MYSOCK"/ -eval CREATE SERVER srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); +--let $srv=srv_self_reference_multi +evalp CREATE SERVER $srv FOREIGN DATA WRAPPER MYSQL OPTIONS (SOCKET "$MASTER_1_MYSOCK", DATABASE 'test',user 'root'); create table t2 (c int); -create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t2"'; -create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t1"'; -alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "srv",TABLE "t0"'; +eval create table t1 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t2"'; +eval create table t0 (c int) ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t1"'; +eval alter table t2 ENGINE=Spider COMMENT='WRAPPER "mysql", srv "$srv",TABLE "t0"'; --error 12719 select * from t0; --error 12719