diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md deleted file mode 100644 index 7a34e193b3548..0000000000000 --- a/.github/pull_request_template.md +++ /dev/null @@ -1,51 +0,0 @@ - - - -- [x] *The Jira issue number for this PR is: MDEV-______* - - -## Description -TODO: fill description here - -## Release Notes -TODO: What should the release notes say about this change? -Include any changed system variables, status variables or behaviour. Optionally list any https://mariadb.com/kb/ pages that need changing. - -## How can this PR be tested? - -TODO: modify the automated test suite to verify that the PR causes MariaDB to behave as intended. -Consult the documentation on ["Writing good test cases"](https://mariadb.org/get-involved/getting-started-for-developers/writing-good-test-cases-mariadb-server). - - -If the changes are not amenable to automated testing, please explain why not and carefully describe how to test manually. - - -## Basing the PR against the correct MariaDB version -- [ ] *This is a new feature or a refactoring, and the PR is based against the `main` branch.* -- [ ] *This is a bug fix, and the PR is based against the earliest maintained branch in which the bug can be reproduced.* - - -## PR quality check -- [ ] I checked the [CODING_STANDARDS.md](https://github.com/MariaDB/server/blob/-/CODING_STANDARDS.md) file and my PR conforms to this where appropriate. -- [ ] For any trivial modifications to the PR, I am ok with the reviewer making the changes themselves. diff --git a/.github/workflows/label_recent_prs.yaml b/.github/workflows/label_recent_prs.yaml new file mode 100644 index 0000000000000..b7c188f811a52 --- /dev/null +++ b/.github/workflows/label_recent_prs.yaml @@ -0,0 +1,78 @@ +name: Label recent pull requests + +on: + schedule: + - cron: "0 2 * * *" # 02:00 UTC daily + workflow_dispatch: # allow manual runs + +permissions: + contents: read + pull-requests: write + issues: write + +jobs: + label-prs: + runs-on: ubuntu-latest + + steps: + - name: Auto-label PRs + env: + REPO: ${{ github.repository }} + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + REPO=MariaDB/server + set -euo pipefail + + # List first 200 PRs lacking classification labels as JSON + gh pr list \ + --repo "$REPO" \ + --search 'is:pr AND -label:"External Contribution" AND -label:"MariaDB Foundation" AND -label:"MariaDB Corporation" AND -label:"Codership" AND created:>2025-11' \ + --limit 200 \ + -s all \ + --json number,author \ + --jq '.[]' | + while read -r pr; do + pr_number=$(echo "$pr" | jq -r '.number') + author=$(echo "$pr" | jq -r '.author.login') + + echo "Evaluating PR #$pr_number by $author" + + # Check if author is in the developers team + if gh api \ + -H "Accept: application/vnd.github+json" \ + "/orgs/MariaDB/teams/developers/members/$author" \ + >/dev/null 2>&1; then + echo "Author is in developers team" + is_developer=1 + else + is_developer=0 + echo "Author is not in developers team" + fi + # Check if author is in the staff team + if gh api \ + -H "Accept: application/vnd.github+json" \ + "/orgs/MariaDB/teams/staff/members/$author" \ + >/dev/null 2>&1; then + echo "Author is in staff team" + is_foundation=1 + else + is_foundation=0 + echo "Author is not in staff team" + fi + + if [[ "$is_foundation" -ne 0 ]]; then + label="MariaDB Foundation" + else + if [[ "$is_developer" -ne 0 ]]; then + label="MariaDB Corporation" + else + label="External Contribution" + fi + fi + + echo "Applying label [$label] to PR#[$pr_number] by [$author]" + + gh issue edit "$pr_number" \ + --repo "$REPO" \ + --add-label "$label" + done diff --git a/.github/workflows/windows-arm64.yml b/.github/workflows/windows-arm64.yml index 26c9154a728c9..a061849cc25b1 100644 --- a/.github/workflows/windows-arm64.yml +++ b/.github/workflows/windows-arm64.yml @@ -48,4 +48,10 @@ jobs: $env:PATH = "C:\Strawberry\perl\bin;$env:PATH;C:\Program Files (x86)\Windows Kits\10\Debuggers\arm64" #Calculate parallel as 4 * number of processors $parallel = 4 * [int]$env:NUMBER_OF_PROCESSORS - perl bld\mysql-test\mysql-test-run.pl --force --parallel=$parallel --suite=main --mysqld=--loose-innodb-flush-log-at-trx-commit=2 + # create case-sensitive directory to run tests in + $tmp = (Get-Item $env:TEMP).FullName + $tmp = $tmp -replace '\\','/' + $cidir = "$tmp/ci" + mkdir $cidir + fsutil file setCaseSensitiveInfo $cidir enable + perl bld\mysql-test\mysql-test-run.pl --force --parallel=$parallel --suite=main,innodb --vardir=$cidir/var --mysqld=--lower-case-table-names=0 --mysqld=--loose-innodb-flush-log-at-trx-commit=2 --mysqld=--debug-no-sync diff --git a/.gitignore b/.gitignore index 35700623da4ff..acc7d75c224ef 100644 --- a/.gitignore +++ b/.gitignore @@ -26,10 +26,12 @@ install_manifest*.txt CPackConfig.cmake CPackSourceConfig.cmake CTestTestfile.cmake +mariadb-plugin-columnstore.install.generated Docs/INFO_BIN Docs/INFO_SRC Makefile TAGS +mariadb-plugin-columnstore.install.generated Testing/ tmp/ VERSION.dep diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c0e0fd349626c..043a68970ac70 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -530,14 +530,12 @@ fedora upgrade-from: matrix: # Get latest versions of all major versions - UPGRADE_PATH: - - "10.6>11.4" - - "10.3" - - "10.4" - - "10.4.8" # Test unexpected table rebuilds as in https://jira.mariadb.org/browse/MDEV-28727 + - "10.6>11.8" - "10.5" - "10.6" - "10.11" - "11.4" + - "11.8" script: - | if [[ $UPGRADE_PATH == *">"* ]]; then diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index 5b02a8aaa24d7..3c4cf829b36e7 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -132,7 +132,7 @@ get_make_parallel_flag SSL_LIBRARY=--with-ssl=system if [ "x$warning_mode" = "xpedantic" ]; then - warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE" + warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -Wno-format-truncation -D_POSIX_SOURCE" c_warnings="$warnings" cxx_warnings="$warnings -std=c++98" # NOTE: warning mode should not influence optimize/debug mode. diff --git a/BUILD/compile-pentium64-asan-max b/BUILD/compile-pentium64-asan-max index cedf5254e59a6..f2ebc146b27c2 100755 --- a/BUILD/compile-pentium64-asan-max +++ b/BUILD/compile-pentium64-asan-max @@ -23,7 +23,7 @@ path=`dirname $0` # extra_flags="$pentium64_cflags $debug_cflags -lasan -O -g -fsanitize=address -USAFEMALLOC -UFORCE_INIT_OF_VARS -Wno-uninitialized -Wno-maybe-uninitialized -DMYSQL_SERVER_SUFFIX=-asan-max" -extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs $disable_asan_plugins" +extra_configs="$pentium_configs $debug_configs $valgrind_configs $max_configs $disable_asan_plugins --with-asan=ON" export LDFLAGS="-ldl" . "$path/FINISH.sh" diff --git a/BUILD/compile-pentium64-ubsan b/BUILD/compile-pentium64-ubsan index c5459a1b2fc43..d14b2f9911537 100755 --- a/BUILD/compile-pentium64-ubsan +++ b/BUILD/compile-pentium64-ubsan @@ -31,7 +31,7 @@ path=`dirname $0` # the destination # -extra_flags="$pentium64_cflags $debug_cflags -fsanitize=undefined -DWITH_UBSAN -Wno-conversion -Wno-uninitialized" +extra_flags="$pentium64_cflags $debug_cflags -fsanitize=undefined -DWITH_UBSAN -Wno-conversion -Wno-uninitialized -Wno-unused-parameter" extra_configs="$pentium_configs $debug_configs -DWITH_UBSAN=ON -DMYSQL_MAINTAINER_MODE=NO --without-spider" . "$path/FINISH.sh" diff --git a/CMakeLists.txt b/CMakeLists.txt index 560e7b87d33ed..e425ccd61d2e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -246,6 +246,10 @@ ENDIF() OPTION(WITH_MSAN "Enable memory sanitizer" OFF) IF (WITH_MSAN) MY_CHECK_AND_SET_COMPILER_FLAG("-fsanitize=memory -fsanitize-memory-track-origins -U_FORTIFY_SOURCE") + IF (CMAKE_CXX_COMPILER_VERSION VERSION_GREATER "20.0") + # workaround for https://github.com/llvm/llvm-project/issues/179605 + SET(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -O1") + ENDIF() IF(NOT (have_C__fsanitize_memory__fsanitize_memory_track_origins__U_FORTIFY_SOURCE AND have_CXX__fsanitize_memory__fsanitize_memory_track_origins__U_FORTIFY_SOURCE)) MESSAGE(FATAL_ERROR "Compiler doesn't support -fsanitize=memory flags") @@ -296,9 +300,13 @@ IF(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -D_GLIBCXX_DEBUG -D_GLIBCXX_ASSERTIONS") ENDIF() -OPTION(ENABLE_GCOV "Enable gcov (debug, Linux builds only)" OFF) +OPTION(ENABLE_GCOV "Enable gcov (debug, macOS and Linux builds only)" OFF) IF (ENABLE_GCOV) - MY_CHECK_AND_SET_COMPILER_FLAG("-DHAVE_gcov -fprofile-arcs -ftest-coverage -lgcov" DEBUG) + IF (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") + MY_CHECK_AND_SET_COMPILER_FLAG("--coverage" DEBUG) + ELSE() + MY_CHECK_AND_SET_COMPILER_FLAG("-DHAVE_gcov -fprofile-arcs -ftest-coverage -lgcov" DEBUG) + ENDIF() ENDIF() OPTION(WITHOUT_PACKED_SORT_KEYS "disable packed sort keys" OFF) @@ -553,32 +561,8 @@ IF(SOURCE_REVISION OR ${PROJECT_BINARY_DIR}/include/source_revision.h ) ENDIF() -CONFIGURE_FILE( - ${CMAKE_SOURCE_DIR}/cmake/info_macros.cmake.in - ${CMAKE_BINARY_DIR}/info_macros.cmake @ONLY) - -# Handle the "INFO_*" files. -INCLUDE(${CMAKE_BINARY_DIR}/info_macros.cmake) -# Source: This can be done during the cmake phase, all information is -# available, but should be repeated on each "make" just in case someone -# does "cmake ; make ; git pull ; make". -CREATE_INFO_SRC(${CMAKE_BINARY_DIR}/Docs) -ADD_CUSTOM_TARGET(INFO_SRC ALL - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/info_src.cmake - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} -) -# Build flags: This must be postponed to the make phase. -ADD_CUSTOM_TARGET(INFO_BIN ALL - COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/info_bin.cmake - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} -) - INSTALL_DOCUMENTATION(README.md CREDITS COPYING THIRDPARTY COMPONENT Readme) -# MDEV-6526 these files are not installed anymore -#INSTALL_DOCUMENTATION(${CMAKE_BINARY_DIR}/Docs/INFO_SRC -# ${CMAKE_BINARY_DIR}/Docs/INFO_BIN) - IF(UNIX) INSTALL_DOCUMENTATION(Docs/INSTALL-BINARY COMPONENT Readme) IF(WITH_WSREP) diff --git a/CODING_STANDARDS.md b/CODING_STANDARDS.md index 7c0b9e473c424..47c572408e01e 100644 --- a/CODING_STANDARDS.md +++ b/CODING_STANDARDS.md @@ -187,7 +187,7 @@ C file names use the `.c` extension, C++ files use the `.cc` extension and heade ### Language standards -For pure-C files we use C99 (starting with 10.4.25) and for C++ we use C++11 (starting with 11.8.1). +For pure-C files we use C99 (starting with 10.4.25) and for C++ we use C++17 (starting with 11.8.1). The code need to be able to compile on multiple platforms using different compilers (for example: Windows / Linux, x86_64 / ARM). ### Line lengths diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c6744bee19999..afceafb81729d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,15 +5,15 @@ MariaDB Server has a vibrant community contributing in a wide range of areas. Th ### Engage online with other community members --- - [MariaDB on Zulip](https://mariadb.zulipchat.com/) -- [maria-developers mailing list](http://launchpad.net/~maria-developers) -- [maria-discuss mailing list](http://launchpad.net/~maria-discuss) -- [maria-docs mailing list](http://launchpad.net/~maria-docs) -- The MariaDB Foundation and MariaDB Corporation have a presence on Reddit, Twitter and Facebook. See the [social media page](https://mariadb.com/kb/en/mariadb/social-media/). +- [maria-developers mailing list](https://lists.mariadb.org/postorius/lists/developers.lists.mariadb.org/) +- [maria-discuss mailing list](https://lists.mariadb.org/postorius/lists/discuss.lists.mariadb.org/) +- [maria-docs mailing list](https://lists.mariadb.org/postorius/lists/docs.lists.mariadb.org/) +- The MariaDB Foundation and MariaDB Corporation have a presence on Reddit, Twitter and Facebook. See the [social media page](https://mariadb.com/docs/general-resources/community/joining-the-community). ### Help document MariaDB ---- -- Contribute towards [documenting MariaDB Server](https://mariadb.com/kb/en/meta/writing-editing-library-articles/) and its ecosystem by adding new content or improving existing content. -- [Translate](https://mariadb.com/kb/en/meta/translating-library-articles/) existing documentation. +- Contribute towards [documenting MariaDB Server](https://mariadb.com/docs/general-resources/about/readme/contributing-documentation) and its ecosystem by adding new content or improving existing content. +- [Translate](https://mariadb.com/docs/general-resources/about/readme/contributing-documentation) existing documentation. ### Help debug and develop MariaDB ----- @@ -44,4 +44,4 @@ New contributors can ask questions any time, but we will provide immediate feedb ### Additional resources ---- - [MariaDB Foundation ](https://mariadb.org/) - - [Knowledge Base](https://mariadb.com/kb/en/) + - [MariaDB Documentation](https://mariadb.com/docs/) diff --git a/CREDITS b/CREDITS index 42f1697f992bf..9363b3d685897 100644 --- a/CREDITS +++ b/CREDITS @@ -66,7 +66,7 @@ following services to the MariaDB community: - Bug fixing in MariaDB (for bugs that affects a large part of the community) - Building the official MariaDB binaries - Maintaining https://mariadb.org -- Documenting MariaDB in the MariaDB Knowledge Base https://mariadb.com/kb +- Documenting MariaDB in the MariaDB Documentation https://mariadb.com/kb To be able to do the above we need help from corporations and individuals! diff --git a/Docs/mysql.info b/Docs/mysql.info deleted file mode 100644 index 02692f341d3a0..0000000000000 --- a/Docs/mysql.info +++ /dev/null @@ -1,11 +0,0 @@ -MariaDB is in most aspects identical to MySQL. - -Differences between MySQL and MariaDB can be found at: -https://mariadb.com/kb/en/mariadb-vs-mysql-features/ -https://mariadb.com/kb/en/mariadb-vs-mysql-compatibility/ - -The MariaDB manual can be found at: -https://mariadb.com/kb/ - -The MySQL Reference Manual is available in various formats on -http://dev.mysql.com/doc. diff --git a/Docs/replication/binlog.md b/Docs/replication/binlog.md new file mode 100644 index 0000000000000..cea6ac9e7e8b2 --- /dev/null +++ b/Docs/replication/binlog.md @@ -0,0 +1,151 @@ +# New binlog implementation + +This document describes the new binlog implementation that is enabled using +the `--binlog-storage-engine` option. + +The new binlog uses a more efficient on-disk format that is integrated with +the InnoDB write-ahead log. This provides two main benefits: + +1. The binlog will always be recovered into a consistent state after a crash. This makes it possible to use the options `--innodb-flush-log-at-trx-commit=0` or `--innodb-flush-log-at-trx-commit=2`, which can give a huge performance improvement depending on disk speed and transaction concurrency. +2. When using the option `--innodb-flush-log-at-trx-commit=1`, commits are more efficient since there is no expensive two-phase commit between the binlog and the InnoDB storage engine. + +## Using the new binlog + +To use the new binlog, configure the server with the following two options: +1. `log_bin` +2. `binlog_storage_engine=innodb` + +Note that the `log_bin` option must be specified like that, without any argument; the option is not an on-off-switch. + +Optionally, the directory in which to store binlog files can be specified with `binlog_directory=`. By default, the data directory is used. + +Note that using the new binlog is mutually exclusive with the traditional binlog format. Configuring an existing server to use the new binlog format will effectively ignore any old binlog files. This limitation may be relaxed in a future version of MariaDB. + +## Replicating with the new binlog + +Configuration of replication from a master using the new binlog is done in the usual way. Slaves must be configured to use Global Transaction ID (GTID) to connect to the master (this is the default). The old filename/offset-based replication position is not available when using the new binlog implementation on the master. + +## Working with the binlog files + +The binlog files will be written to the data directory (or to the directory configured with `--binlog-directory`). The files are named `binlog-000000.ibb`, `binlog-000001.ibb`, ... and so on. + +The size of each binlog file is determined by the value of `max_binlog_size` (by default 1 GB). The binlog files are pre-allocated, so they will always have the configured size, with the last one or two files being possibly partially empty. The exception is when the command `FLUSH BINARY LOGS` is used; then the last active binlog file will be truncated to the used part of it, and binlog writes will continue in the following file. + +The list of current binlog files can be obtained with the command `SHOW BINLOG EVENTS`. Note that there is no binlog index file (`.index`) like with the traditional binlog format, nor are there any GTID index files (`.idx`) or GTID state (`.state`) file (`.state`). + +Instead of the GTID index and state files, the new binlog periodically writes GTID *state records* into the binlog containing the equivalent information. When a slave connects to the master, as well as when the server starts up, the binlog will be scanned from the last GTID state record to find or recover the correct GTID position. The `--innodb-binlog-state-interval` configuration option controls the interval (in bytes) between writing a state record. Thus, this option can be increased to reduce the overhead of state records, or decreased to speed up finding the initial GTID position at slave connect. The overhead however is small either way, and normally there is little reason to change the default. The status variables `binlog_gtid_index_hit` and `binlog_gtid_index_miss` are not used with the new binlog implementation. + +Binlog files can be purged (removed) automatically after a configured time or disk space usage, provided they are no longer needed by active replication slaves or for possible crash recovery. This is configured using the options `binlog_expire_log_seconds`, `binlog_expire_log_days`, `max_binlog_total_size`, and `slave_connections_needed_for_purge`. + +The contents of binlog files can be inspected in two ways: +1. From within the server, using the command `SHOW BINLOG EVENTS`. +2. Independent of the server, using the `mariadb-binlog` command-line program. + +Unlike in the traditional binlog format, one binlog event can be stored in multiple different binlog files, and different parts of individual events can be interleaved with one another in each file. The `mariadb-binlog` program will coalesce the different parts of each event as necessary, so the output of the program is a consistent, non-interleaved stream of events. To obtain a correct seequnce of events across multiple binlog files, all binlog files should be passed to the `mariadb-binlog` program at once in correct order; this ensures that events that cross file boundaries are included in the output exactly once. + +When using the `--start-position` and `--stop-position` options of `mariadb-binlog`, it is recommended to use GTID positions. The event file offsets used in the tranditional binlog format are not used in the new binlog, and will mostly be reported as zero. + +The `--binlog-checksum` option is no longer used with the new binlog implementation. The binlog files are always checksummed, with a CRC32 at the end of each page. To have checksum of the data sent on the network between the master and the slave (in addition to the normal TCP checksums), use the `MASTER_SSL` option for `CHANGE MASTER` to make the connection use SSL. + +## Using the new binlog with mariadb-backup + +The `mariadb-backup` program will by default back up the binlog files together with the rest of the server data. This fixes a long-standing limitation of the old binlog that it is missing from backups made with `mariadb-backup`. + +The binlog files are backed up in a transactionally consistent way, just like other InnoDB data. This means that a restored backup can be used to setup a new slave simply by using the `MASTER_DEMOTE_TO_SLAVE=1` option of `CHANGE MASTER`. + +The server being backed up is not blocked during the copy of the binlog files; only `RESET MASTER`, `PURGE BINARY LOGS` and `FLUSH BINARY LOGS` are blocked by default. This blocking can be disabled with the option `--no-lock` option. + +To omit the binlog files from the backup (ie. to save space in the backup when the binlog files are known to be not needed), use the `--skip-binlog` option on both the `mariadb-backup --backup` and `mariadb-backup --prepare` step. Note that when binlog files are omitted from the backup, the restored server will behave as if `RESET MASTER` was run on it just at the point of the backup. Also note that any transactions that were prepared, but not yet committed, at the time of the backup will be rolled back when the restored server starts up for the first time. + +## `FLUSH BINARY LOGS` + +Binlog files are pre-allocated for efficiency. When binlog file N is filled up, any remainder event data continues in file N+1, and and empty file N+2 is pre-allocated in the background. This means that binlog files are always exactly `--max-binlog-size` bytes long; and if the server restarts, binlog writing continues at the point reached before shutdown. + +The exception is when the `FLUSH BINARY LOGS` command is run. This pads the current binlog file up to the next page boundary, truncates the file, and switches to the next file. This can thus leave the binlog file smaller than `--max-binlog-size` (but always a multiple of the binlog page size). + +The `FLUSH BINARY LOGS DELETE_DOMAIN_ID=N` can be used to remove an old domain id from the `@@gtid_binlog_pos`. This requires that the domain is not in use in any existing binlog files; a combination of running `FLUSH BINARY LOGS` and `PURGE BINARY LOGS TO` can help ensure this. If the domain id N is already deleted, a warning is issues but the `FLUSH BINARY LOGS` operation is still run (this is for consistency, but is different from the old binlog implementation, where the `FLUSH` is skipped if the domain id was already deleted. + +## Upgrading + +When switching an existing server to use the new binlog format, the old binlog files will not be available after the switch, as the two formats are mutually exclusive. + +If the old binlog files are not needed after the transition, no special actions are needed. Just stop the server and restart with the configuration `--log-bin --binlog-storage-engine=innodb`. The new binlog will start empty. The old binlog files can be removed manually afterwards. + +Optionally, note down the value of `@@binlog_gtid_state` and execute `SET GLOBAL binlog_gtid_state=` as the first thing after starting up, to preserve the GTID state. This can be used to migrate a replication setup. First stop all writes to the master, and let all slaves catch up. Then note down the value of `@@binlog_gtid_state`, restart the master with `--binlog-storage-engine=innodb`, and restore `@@binlog_gtid_state`. Then the slaves will be able to connect and continue from where they left off. + +Alternatively, live migration can be done by switching a slave first. Restart a slave with the new `binlog-storage-engine=innodb` option and let the slave replicate for a while until it has sufficient binlog data in the new binlog format. Then promote the slave as the new master. The other slaves can then be stopped, switched to the new binlog, and restarted, as convenient. + +When using the new binlog format for a new installation, nothing special is needed. Just configure `--binlog-storage-engine=innodb` on the new server installation. + +When the new binlog format is enabled on a master, the slaves should be upgraded to at least MariaDB version 12.3 first. The slave can be switched to the new binlog format without upgrading the master first. The master and slave can use the old or the new binlog format independently of one another. + +## Using the new binlog with 3rd-party programs + +The new binlog uses a different on-disk format than the traditional binlog. The format of individual replication events is the same; however the files stored on disk are page-based, and each page has some encapsulation of event data to support splitting events in multiple pieces etc. + +This means that existing 3rd-party programs that read the binlog files directly will need to be modified to support the new format. Until then, such programs will require using the traditional binlog format. + +The protocol for reading binlog data from a running server (eg. for a connecting slave) is however mostly unchanged. This means existing programs that read binlog events from a running server may be able to function unmodified with the new binlog. Similarly, `mariadb-binlog` with the `--read-from-remote-server` option works as usual. + +A difference is that file offsets and file bondaries are no longer meaningful and no longer reported to the connecting client. There are no rotate events at the end of a file to specify the name of the following file, nor is there a new format description event at the start of each new file. Effectively, the binlog appears as a single unbroken stream of events to clients. The position from which to start receiving binlog events from the server should be specified using a GTID position; specifying a filename and file offset is not available. + +### Documentation of the binlog file format + +A binlog file consists of a sequence of pages. The page size is currently fixed at 16kByte. The size of a binlog file is set with the `--max-binlog-size` option. Each page has a CRC32 in the last 4 bytes; all remaining bytes are used for data. + +Numbers are stored in little-endian format. Some numbers are stored as compressed integers. A compressed integer consists of 1-9 bytes. The lower 3 bits determine the number of bytes used. The number of bytes is one more than the value in the lower 3 bits, except that a value of 7 means that 9 bytes are used. The value of the number stored is the little-endian value of the used bytes, right-shifted by 3. + +The first page in each binlog file is a file header page, with the following format: + +| Offset | Size | Description | +| -----: | ---: | :---------- | +| 0 | 4 | 4-byte MAGIC value 0x010dfefe to identify the file as a binlog file. | +| 4 | 4 | The log-2 of the page size, currently fixed at 14 for a 16kByte page size. | +| 8 | 4 | Major file version, currently 1. A new major version is not readable by older server versions. | +| 12 | 4 | Minor file version, currently 0. New minor versions are backwards-compatible with older server versions. | +| 16 | 8 | The file number (same as the number in the `binlog-NNNNNN.ibb` file name), for consistency check. | +| 24 | 8 | The size of the file, in pages. | +| 32 | 8 | The InnoDB LSN corresponding to the start of the file, used for crash recovery. | +| 40 | 8 | The value of `--innodb-binlog-state-interval` used in the file. | +| 48 | 8 | The file number of the earliest file into which this file may contain references into (such references occur when a large event group is split into multiple pieces, called out-of-band or oob records, and are used to locate all the pieces of event data from the final commit record). Used to prevent purging binlog files that contain data that may still be needed. | +| 56 | 8 | The file number of the earliest file containing pending XA transactions that may still be active. | +| 64 | 448 | Unused. | +| 512 | 4 | Extra CRC32. This is used for future expansion to support configurable binlog page size. The header page can be read and checksummed as a 512-byte page, after which the real page size can be determined from the value at offset 4. | + +Remaining pages in the file are data pages. Data is structured as a sequence of *records*; each record consists of one or more chunks. A page contains one or more chunks; a record can span multiple pages, but a chunk always fits within one page. Chunks are a minumum of 4 bytes long; any remaining 1-3 bytes of data in a page are filled with the byte 0xff. Unused bytes in a page are set to 0x00. + +A chunk consists of a *type byte*, two *length bytes* (little endian), and the *data bytes*. The length bytes count only the data bytes, so if the length bytes are 0x0001, then the total size of the chunk is 4 bytes. + +The high two bits of the type byte are used to collect chunks into records: +- Bit 7 is clear for the first chunk in a record, and set for all following chunks in the record. +- Bit 6 is set for the last chunk in a record, and clear for any prior chunks. + +These are the chunk types used: + +| Type | Description | +| ---: | :---------- | +| 0 | (not a real type, 0 is an unused byte and denotes end-of-file in the current binlog file). | +| 1 | A commit record, containing binlog event data. First a compressed integer of the number of oob records referenced by the commit record, if any; then if non-zero, four more compressed integers of the file number and offset of the first and last such reference. This is followed by another similar 1 or 5 compressed integers, only used in the special case where transactional and non-transactional updates are mixed in a single event group. The remainder bytes are the payload data. | +| 2 | This is a GTID state record, written every `--innodb-binlog-state-interval` bytes. It consists of a sequence of compressed integers. The first is the number of GTIDs in the GTID state stored in the record. The second is one more than the earliest file number containing possibly still active XA transactions (used for crash recovery), or 0 for none. After this comes N*3 compressed integers, each representing a GTID in the GTID state. | +| 3 | This is an out-of-band (oob) data record. It is used to split large event groups into smaller pieces, organized as a forest of perfect binary trees. The record starts with 5 compressed integers: A node index (starts at 0 and increments for each oob record in an event group); the file number and offset of the left child oob node; and the file number and offset of the right child oob node. Remainder bytes are the payload event data. | +| 4 | This is a filler record, it is used to pad out the last page of a binlog file which is truncated due to `FLUSH BINARY LOGS`. | +| 5 | This is an XA PREPARE record, used for consistent crash recovery of user XA transactions. It starts with 1 byte counting the number of storage engines participating in the transaction. Then follows the XID (4 byte formatID; 1 byte gtrid length; 1 byte bqual length; and the characters of the XID name). Finally 5 compressed integers: the number of referenced oob nodes; the file number and offset of the first one; and the file number and offset of the last one. | +| 6 | This is an XA complete record, used for recovery purposes for internal 2-phase commit transactions and user XA. The first byte is a type byte, which is 0 for commit and 1 for XA rollback. Then follows 6-134 bytes of the XID, in the same format as for the XA PREPARE record. | + +## Not supported + +A few things are not supported with the new binlog implementation. Some of +these should be supported in a later version of MariaDB. Some of these are +legacy stuff that fundamentally works poorly or is otherwise undesirable, +and are intentionally removed in the new binlog implementation. + +- Old-style filename/offset replication positions are not available with the new binlog. Slaves must be configured to use GTID (this is the default). Event offsets are generally reported as zero. `MASTER_POS_WAIT()` is not available, `MASTER_GTID_WAIT()` should be used instead. Similarly, `BINLOG_GTID_POS()` is not available. +- Using savepoints inside triggers is not supported. This is because of bugs and inconsistencies like in MDEV38465. Now executing a `SAVEPOINT` or `ROLLBACK TO SAVEPOINT` statement in a trigger will consistently error and roll back the entire statement. +- Semi-synchronous replication is not supported in the first version. It will be supported as normal eventually using the `AFTER_COMMIT` option. The `AFTER_SYNC` option cannot be supported, as the expensive two-phase commit between binlog and engine is no longer needed (`AFTER_SYNC` waits for slave acknowledgement in the middle of the two-phase commit). Likewise, `--init-rpl-role` is not supported. +- The new binlog implementation cannot be used with Galera. +- In the initial version, only InnoDB is available as an engine for the binlog (`--binlog-storage-engine=innodb`). It the future, other transactional storage engines could implement storing the binlog themselves (performance is best when the binlog is implemented in the same engine as the tables that are updated). +- The `sync_binlog` option is no longer needed and is effectively ignored. Since the binlog files are now crash-safe without needing any syncing. The durability of commits is now controlled solely by the `--innodb-flush-log-at-trx-commit` option, which now applies to both binlog files and InnoDB table data. +- The command `RESET MASTER TO` is not available with the new binlog. +- The `--tc-heuristic-recover` option is not needed with the new binlog and cannot be used. Any pending prepared transactions will always be rolled back or committed to be consistent with the binlog. If the binlog is empty (ie. has been deleted manually), pending transactions will be rolled back. +- Binlog encryption is not available. It is suggested to use filesystem-level encryption facilities of the operating system instead, and/or use SSL for the slave's connection to the master. +- SHOW BINLOG EVENTS FROM will not give an error for a position that starts in the middle of an event group. Instead, it will start from the first GTID event following the position (or return empty, if the position is past the end). diff --git a/README.md b/README.md index f4fab1bd3a35a..7bbf3a3dadd97 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ ## MariaDB: The innovative open source database -MariaDB was designed as a drop-in replacement of MySQL(R) with more +MariaDB was designed as a drop-in replacement for MySQL(R) with more features, new storage engines, fewer bugs, and better performance. MariaDB is brought to you by the MariaDB Foundation and the MariaDB Corporation. diff --git a/VERSION b/VERSION index 16156243e5bfa..11568327cf958 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ -MYSQL_VERSION_MAJOR=12 +MYSQL_VERSION_MAJOR=13 MYSQL_VERSION_MINOR=0 -MYSQL_VERSION_PATCH=2 -SERVER_MATURITY=stable +MYSQL_VERSION_PATCH=0 +SERVER_MATURITY=alpha diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index 79e452f680137..1a56e55d5ac3c 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -64,8 +64,7 @@ TARGET_LINK_LIBRARIES(import_util PRIVATE pcre2-posix pcre2-8) TARGET_INCLUDE_DIRECTORIES(import_util PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) MYSQL_ADD_EXECUTABLE(mariadb-import mysqlimport.cc) -TARGET_INCLUDE_DIRECTORIES(mariadb-import PRIVATE ${CMAKE_SOURCE_DIR}/tpool) -TARGET_LINK_LIBRARIES(mariadb-import PRIVATE tpool ${CLIENT_LIB} import_util) +TARGET_LINK_LIBRARIES(mariadb-import PRIVATE tpool_min ${CLIENT_LIB} import_util) MYSQL_ADD_EXECUTABLE(mariadb-upgrade mysql_upgrade.c COMPONENT Server) @@ -78,7 +77,7 @@ TARGET_LINK_LIBRARIES(mariadb-show ${CLIENT_LIB}) MYSQL_ADD_EXECUTABLE(mariadb-plugin mysql_plugin.c) TARGET_LINK_LIBRARIES(mariadb-plugin ${CLIENT_LIB}) -MYSQL_ADD_EXECUTABLE(mariadb-binlog mysqlbinlog.cc) +MYSQL_ADD_EXECUTABLE(mariadb-binlog mysqlbinlog.cc mysqlbinlog-engine.cc) TARGET_LINK_LIBRARIES(mariadb-binlog ${CLIENT_LIB} mysys_ssl) MYSQL_ADD_EXECUTABLE(mariadb-admin mysqladmin.cc ../sql/password.c) diff --git a/client/my_readline.h b/client/my_readline.h index ec43d81f2c0a8..2ff5edcf31c58 100644 --- a/client/my_readline.h +++ b/client/my_readline.h @@ -34,9 +34,10 @@ typedef struct st_line_buffer bool truncated; } LINE_BUFFER; -extern LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file); extern LINE_BUFFER *batch_readline_command(LINE_BUFFER *buffer, char * str); extern char *batch_readline(LINE_BUFFER *buffer, bool binary_mode); extern void batch_readline_end(LINE_BUFFER *buffer); +extern bool init_line_buffer(LINE_BUFFER *buffer, File file, ulong size, + ulong max_size); #endif /* CLIENT_MY_READLINE_INCLUDED */ diff --git a/client/mysql.cc b/client/mysql.cc index 607773071be0f..3158d270ae7d5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1216,6 +1216,88 @@ inline int get_command_index(char cmd_char) return -1; } +static LINE_BUFFER *batch_readline_init(ulong max_size, const char *path) +{ + LINE_BUFFER *line_buff; + File file; + MY_STAT input_file_stat; + char buff[FN_REFLEN + 512]; + + if (path) + { + file= my_open(path, O_RDONLY | O_BINARY, MYF(0)); + if (file < 0 && my_errno == ENOENT && script_dir) + { + char full_path[FN_REFLEN]; + strxnmov(full_path, sizeof(full_path)-1, script_dir, "/", path, NULL); + file= my_open(full_path, O_RDONLY | O_BINARY, MYF(0)); + } + if (file < 0) + { +#ifdef _WIN32 + if (my_errno == EACCES && my_stat(path, &input_file_stat, MYF(0)) && + MY_S_ISDIR(input_file_stat.st_mode)) + my_snprintf(buff, sizeof(buff), "Can't read from a directory '%.*s'", + FN_REFLEN, path); + else +#endif + my_snprintf(buff, sizeof(buff), "Failed to open file '%.*s', error: %d", + FN_REFLEN, path, my_errno); + put_info(buff, INFO_ERROR, 0); + return 0; + } + } + else + { + file= my_fileno(stdin); + } + + if (my_fstat(file, &input_file_stat, MYF(0))) + { + my_snprintf(buff, sizeof(buff), "Failed to stat file '%.*s', error: %d", + FN_REFLEN, path ? path : "stdin", my_errno); + goto err1; + } + + if (MY_S_ISDIR(input_file_stat.st_mode)) + { + my_snprintf(buff, sizeof(buff), "Can't read from a directory '%.*s'", + FN_REFLEN, path ? path : "stdin"); + goto err1; + } + +#ifndef _WIN32 + if (MY_S_ISBLK(input_file_stat.st_mode)) + { + my_snprintf(buff, sizeof(buff), "Can't read from a block device '%.*s'", + FN_REFLEN, path ? path : "stdin"); + goto err1; + } +#endif + + if (!(line_buff= (LINE_BUFFER*) my_malloc(PSI_NOT_INSTRUMENTED, + sizeof(*line_buff), + MYF(MY_WME | MY_ZEROFILL)))) + { + goto err; + } + + if (init_line_buffer(line_buff, file, IO_SIZE, max_size)) + { + my_free(line_buff); + goto err; + } + + return line_buff; + +err1: + put_info(buff, INFO_ERROR, 0); +err: + if (path) + my_close(file, MYF(0)); + return 0; +} + static int delimiter_index= -1; static int charset_index= -1; static int sandbox_index= -1; @@ -1290,10 +1372,8 @@ int main(int argc,char *argv[]) } if (status.batch && !status.line_buff && - !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, stdin))) + !(status.line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, NULL))) { - put_info("Can't initialize batch_readline - may be the input source is " - "a directory or a block device.", INFO_ERROR, 0); free_defaults(defaults_argv); my_end(0); exit(1); @@ -1344,6 +1424,11 @@ int main(int argc,char *argv[]) mysql_thread_id(&mysql), server_version_string(&mysql)); put_info((char*) glob_buffer.ptr(),INFO_INFO); put_info(ORACLE_WELCOME_COPYRIGHT_NOTICE("2000"), INFO_INFO); +#if SERVER_MATURITY_LEVEL < MariaDB_PLUGIN_MATURITY_STABLE + put_info("Help others discover MariaDB." + " Star it on GitHub: https://github.com/MariaDB/server\n", + INFO_INFO); +#endif } #ifdef HAVE_READLINE @@ -1409,9 +1494,7 @@ int main(int argc,char *argv[]) if (opt_outfile) end_tee(); mysql_end(0); -#ifndef _lint - DBUG_RETURN(0); // Keep compiler happy -#endif + DBUG_RETURN(0); } sig_handler mysql_end(int sig) @@ -2691,7 +2774,7 @@ static bool add_line(String &buffer, char *line, size_t line_length, } buffer.length(0); } - else if (!*ml_comment && + else if (!*ml_comment && *ss_comment != SSC_HINT && (!*in_string && (inchar == '#' || (inchar == '-' && pos[1] == '-' && @@ -2912,7 +2995,9 @@ static void fix_history(String *final_command) ptr++; } if (total_lines > 1) - add_history(fixed_buffer.ptr()); + { + add_history(fixed_buffer.c_ptr()); + } } /* @@ -3235,6 +3320,12 @@ static int reconnect(void) } #ifndef EMBEDDED_LIBRARY +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wvarargs" +/* CONC-789 */ +#endif + static void status_info_cb(void *data, enum enum_mariadb_status_info type, ...) { va_list ap; @@ -3250,6 +3341,10 @@ static void status_info_cb(void *data, enum enum_mariadb_status_info type, ...) } va_end(ap); } + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif #else #define mysql_optionsv(A,B,C,D) do { } while(0) #endif @@ -3533,8 +3628,6 @@ static int com_go(String *buffer, char *) old_buffer.copy(); } - /* Remove garbage for nicer messages */ - LINT_INIT_STRUCT(buff[0]); remove_cntrl(*buffer); if (buffer->is_empty()) @@ -4734,11 +4827,9 @@ static int com_connect(String *buffer, char *line) static int com_source(String *, char *line) { char source_name[FN_REFLEN], *end, *param; - char full_path[FN_REFLEN]; LINE_BUFFER *line_buff; int error; STATUS old_status; - FILE *sql_file; my_bool save_ignore_errors; if (status.sandbox) @@ -4758,27 +4849,10 @@ static int com_source(String *, char *line) end--; end[0]=0; unpack_filename(source_name,source_name); - /* open file name */ - if (!(sql_file = my_fopen(source_name, O_RDONLY | O_BINARY,MYF(0)))) - { - if (script_dir) - { - snprintf(full_path, sizeof(full_path), "%s/%s", script_dir, source_name); - sql_file = my_fopen(full_path, O_RDONLY | O_BINARY, MYF(0)); - } - } - - if (!sql_file) - { - char buff[FN_REFLEN + 60]; - sprintf(buff, "Failed to open file '%s', error: %d", source_name, errno); - return put_info(buff, INFO_ERROR, 0); - } - if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, sql_file))) + if (!(line_buff= batch_readline_init(MAX_BATCH_BUFFER_SIZE, source_name))) { - my_fclose(sql_file,MYF(0)); - return put_info("Can't initialize batch_readline", INFO_ERROR, 0); + return ignore_errors ? -1 : 1; } /* Save old status */ @@ -4797,7 +4871,7 @@ static int com_source(String *, char *line) ignore_errors= save_ignore_errors; status=old_status; // Continue as before in_com_source= aborted= 0; - my_fclose(sql_file,MYF(0)); + my_close(line_buff->file, MYF(0)); batch_readline_end(line_buff); /* If we got an error during source operation, don't abort the client diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 304e26afa3b4f..ef04f3d2938b0 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -285,9 +285,7 @@ get_one_option(const struct my_option *opt, const char *argument, opt_verbose= 0; break; case OPT_CHARSETS_DIR: -#if MYSQL_VERSION_ID > 32300 charsets_dir = argument; -#endif break; case OPT_MYSQL_PROTOCOL: if ((opt_protocol= find_type_with_warning(argument, &sql_protocol_typelib, @@ -684,7 +682,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } if (maybe_disable_binlog(mysql)) return -1; - sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]); + snprintf(buff, sizeof(buff), "create database `%.*s`",FN_REFLEN,argv[1]); if (mysql_query(mysql,buff)) { my_printf_error(0,"CREATE DATABASE failed; error: '%-.200s'", @@ -725,7 +723,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) if (opt_shutdown_wait_for_slaves) { - sprintf(buff, "SHUTDOWN WAIT FOR ALL SLAVES"); + snprintf(buff, sizeof(buff), "SHUTDOWN WAIT FOR ALL SLAVES"); if (mysql_query(mysql, buff)) { my_printf_error(0, "%s failed; error: '%-.200s'", @@ -1128,7 +1126,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } else crypted_pw[0]=0; /* No password */ - sprintf(buff,"set password='%s',sql_log_off=0",crypted_pw); + snprintf(buff, sizeof(buff), "set password='%s',sql_log_off=0",crypted_pw); if (mysql_query(mysql,"set sql_log_off=1")) { @@ -1309,9 +1307,9 @@ static void usage(void) my_print_help(my_long_options); my_print_variables(my_long_options); puts("\nWhere command is a one or more of: (Commands may be shortened)\n\ - create databasename Create a new database\n\ - debug Instruct server to write debug information to log\n\ - drop databasename Delete a database and all its tables\n\ + create databasename Create a new database\n\ + debug Instruct server to write debug information to log\n\ + drop databasename Delete a database and all its tables\n\ extended-status Gives an extended status message from the server\n\ flush-all-statistics Flush all statistics tables\n\ flush-all-status Flush status and statistics\n\ @@ -1333,25 +1331,21 @@ static void usage(void) flush-threads Flush the thread cache\n\ flush-user-statistics Flush user statistics\n\ flush-user-resources Flush user resources\n\ - kill id,id,... Kill mysql threads"); -#if MYSQL_VERSION_ID >= 32200 - puts("\ + kill id,id,... Kill mysql threads\n\ password [new-password] Change old password to new-password in current format\n\ - old-password [new-password] Change old password to new-password in old format"); -#endif - puts("\ - ping Check if mysqld is alive\n\ - processlist Show list of active threads in server\n\ - reload Reload grant tables\n\ - refresh Flush all tables and close and open logfiles\n\ - shutdown Take server down\n\ - status Gives a short status message from the server\n\ - start-all-slaves Start all slaves\n\ - start-slave Start slave\n\ - stop-all-slaves Stop all slaves\n\ - stop-slave Stop slave\n\ + old-password [new-password] Change old password to new-password in old format\n\ + ping Check if mysqld is alive\n\ + processlist Show list of active threads in server\n\ + reload Reload grant tables\n\ + refresh Flush all tables and close and open logfiles\n\ + shutdown Take server down\n\ + status Gives a short status message from the server\n\ + start-all-slaves Start all slaves\n\ + start-slave Start slave\n\ + stop-all-slaves Stop all slaves\n\ + stop-slave Stop slave\n\ variables Prints variables available\n\ - version Get version info from server"); + version Get version info from server"); } @@ -1373,7 +1367,7 @@ static int drop_db(MYSQL *mysql, const char *db) return -1; } } - sprintf(name_buff,"drop database `%.*s`",FN_REFLEN,db); + snprintf(name_buff,sizeof(name_buff), "drop database `%.*s`",FN_REFLEN,db); if (mysql_query(mysql,name_buff)) { my_printf_error(0, "DROP DATABASE %s failed;\nerror: '%s'", error_flags, diff --git a/client/mysqlbinlog-engine.cc b/client/mysqlbinlog-engine.cc new file mode 100644 index 0000000000000..c67d5aa2d8a2b --- /dev/null +++ b/client/mysqlbinlog-engine.cc @@ -0,0 +1,1185 @@ +/* Copyright (c) 2025, Kristian Nielsen. + + 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 */ + +/* + Code for reading engine-implemented binlog from the mysqlbinlog client + program. +*/ + +#include +#include +#include +#include "client_priv.h" +#include "mysqlbinlog-engine.h" +#include "my_compr_int.h" +#include "my_dir.h" + + +const char *INNODB_BINLOG_MAGIC= "\xfe\xfe\x0d\x01"; +static constexpr uint32_t INNODB_BINLOG_FILE_VERS_MAJOR= 1; + +static uint32_t binlog_page_size; + +/* + Some code here is copied from storage/innobase/handler/innodb_binlog.cc and + storage/innodb_binlog/fsp/fsp_binlog.cc and modified for use in the + mysqlbinlog command-line client. + + Normally it is desirable to share code rather than copy/modify it, but + special considerations apply here: + + - Normally, it is desirable to share the code so that modifications to the + logic are automatically kept in sync between the two use cases. However + in the case of the binlog, non-backwards compatible changes are highly + undesirable, and having a separate reader implementation in mysqlbinlog + is actually useful to detect any unintended or non-desirable changes to + the format that prevent old code from reading it. The binlog files + should remain readable to old mysqlbinlog versions if at all possible, + as well as to any other 3rd-party readers. + + - The main purpose of the code inside InnoDB is to very efficiently allow + reading of binlog data concurrently with active writing threads and + concurrently with page fifo asynchroneous flushing. In contrast, the + purpose of the mysqlclient code is to have a simple stand-alone command + line reader of the files. These two use cases are sufficiently + different, and the code frameworks used for storage/innobase/ and + client/ likewise sufficiently different, that code-sharing seems more + troublesome than beneficial here. +*/ + +static constexpr uint32_t BINLOG_PAGE_SIZE_MAX= 65536; +#define BINLOG_PAGE_DATA 0 +#define BINLOG_PAGE_CHECKSUM 4 +#define BINLOG_PAGE_DATA_END BINLOG_PAGE_CHECKSUM + +#define BINLOG_NAME_BASE "binlog-" +#define BINLOG_NAME_EXT ".ibb" + +enum fsp_binlog_chunk_types { + /* Zero means no data, effectively EOF. */ + FSP_BINLOG_TYPE_EMPTY= 0, + /* A binlogged committed event group. */ + FSP_BINLOG_TYPE_COMMIT= 1, + /* A binlog GTID state record. */ + FSP_BINLOG_TYPE_GTID_STATE= 2, + /* Out-of-band event group data. */ + FSP_BINLOG_TYPE_OOB_DATA= 3, + /* Dummy record, use to fill remainder of page (eg. FLUSH BINARY LOGS). */ + FSP_BINLOG_TYPE_DUMMY= 4, + /* Must be one more than the last type. */ + FSP_BINLOG_TYPE_END, + + /* Padding data at end of page. */ + FSP_BINLOG_TYPE_FILLER= 0xff +}; +static constexpr uint32_t FSP_BINLOG_FLAG_BIT_CONT= 7; +static constexpr uint32_t FSP_BINLOG_FLAG_CONT= (1 << FSP_BINLOG_FLAG_BIT_CONT); +static constexpr uint32_t FSP_BINLOG_FLAG_BIT_LAST= 6; +static constexpr uint32_t FSP_BINLOG_FLAG_LAST= (1 << FSP_BINLOG_FLAG_BIT_LAST); +static constexpr uint32_t FSP_BINLOG_TYPE_MASK= + ~(FSP_BINLOG_FLAG_CONT | FSP_BINLOG_FLAG_LAST); +static constexpr uint64_t ALLOWED_NESTED_RECORDS= + /* GTID STATE at start of page can occur in the middle of other record. */ + ((uint64_t)1 << FSP_BINLOG_TYPE_GTID_STATE) | + /* DUMMY data at tablespace end can occur in the middle of other record. */ + ((uint64_t)1 << FSP_BINLOG_TYPE_DUMMY) + ; + + +static char binlog_dir[FN_REFLEN + 1]; + + +class chunk_reader_mysqlbinlog { +public: + enum chunk_reader_status { + CHUNK_READER_ERROR= -1, + CHUNK_READER_EOF= 0, + CHUNK_READER_FOUND= 1 + }; + + /* + Current state, can be obtained from save_pos() and later passed to + restore_pos(). + */ + struct saved_position { + /* Current position file. */ + uint64_t file_no; + /* Current position page. */ + uint32_t page_no; + /* Start of current chunk inside page. */ + uint32_t in_page_offset; + /* + The length of the current chunk, once the chunk type has been read. + If 0, it means the chunk type (and length) has not yet been read. + */ + uint32_t chunk_len; + /* The read position inside the current chunk. */ + uint32_t chunk_read_offset; + uchar chunk_type; + /* When set, read will skip the current chunk, if any. */ + bool skip_current; + /* Set while we are in the middle of reading a record. */ + bool in_record; + } s; + + /* Length of the currently open file, valid if cur_file_handle != -1. */ + uint64_t cur_file_length; + /* Buffer for reading a page from a binlog file. */ + uchar *page_buffer; + /* Open file handle to tablespace file_no, or -1. */ + File cur_file_handle; + /* + Flag used to skip the rest of any partial chunk we might be starting in + the middle of. + */ + bool skipping_partial; + /* If the s.file_no / s.page_no is loaded in the page buffer. */ + bool page_loaded; + + chunk_reader_mysqlbinlog(); + void set_page_buf(uchar *in_page_buf) { page_buffer= in_page_buf; } + ~chunk_reader_mysqlbinlog(); + + /* Current type, or FSP_BINLOG_TYPE_FILLER if between records. */ + uchar cur_type() { return (uchar)(s.chunk_type & FSP_BINLOG_TYPE_MASK); } + bool cur_is_cont() { return (s.chunk_type & FSP_BINLOG_FLAG_CONT) != 0; } + bool end_of_record() { return !s.in_record; } + bool is_end_of_page() noexcept + { + return s.in_page_offset >= binlog_page_size - (BINLOG_PAGE_DATA_END + 3); + } + bool is_end_of_file() noexcept + { + return current_pos() + (BINLOG_PAGE_DATA_END + 3) >= cur_file_length; + } + static int read_error_corruption(uint64_t file_no, uint64_t page_no, + const char *msg); + int read_error_corruption(const char *msg) + { + return read_error_corruption(s.file_no, s.page_no, msg); + } + enum chunk_reader_status fetch_current_page(); + /* + Try to read max_len bytes from a record into buffer. + + If multipage is true, will move across pages to read following + continuation chunks, if any, to try and read max_len total bytes. Only if + the record ends before max_len bytes is less amount of bytes returned. + + If multipage is false, will read as much is available on one page (up to + max of max_len), and then return. + + Returns number of bytes read, or -1 for error. + Returns 0 if the chunk_reader is pointing to start of a chunk at the end + of the current binlog (ie. end-of-file). + */ + int read_data(uchar *buffer, int max_len, bool multipage); + /* Read the file header of current file_no. */ + int parse_file_header(); + + /* Save current position, and restore it later. */ + void save_pos(saved_position *out_pos) { *out_pos= s; } + void restore_pos(saved_position *pos); + void seek(uint64_t file_no, uint64_t offset); + + /* + Make next read_data() skip any data from the current chunk (if any), and + start reading data only from the beginning of the next chunk. */ + void skip_current() { if (s.in_record) s.skip_current= true; } + /* + Used initially, after seeking potentially into the middle of a (commit) + record, to skip any continuation chunks until we reach the start of the + first real record. + */ + void skip_partial(bool skip) { skipping_partial= skip; } + uint64_t current_pos() { + return (s.page_no * binlog_page_size) + s.in_page_offset; + } + void set_fd(File fd); +}; + + +class oob_reader_mysqlbinlog { + enum oob_states { + /* The initial state, about to visit the node for the first time. */ + ST_initial, + /* State of leaf node while traversing the prior trees in the forest. */ + ST_traversing_prior_trees, + /* State of non-leaf node while traversing its left sub-tree. */ + ST_traversing_left_child, + /* State of non-leaf node while traversing its right sub-tree. */ + ST_traversing_right_child, + /* State of node while reading out its data. */ + ST_self + }; + + /* + Stack entry for one node currently taking part in post-order traversal. + We maintain a stack of pending nodes during the traversal, as the traversal + happens in a state machine rather than by recursion. + */ + struct stack_entry { + /* Saved position after reading header. */ + chunk_reader_mysqlbinlog::saved_position saved_pos; + /* The location of this node's OOB record. */ + uint64_t file_no; + uint64_t offset; + /* Right child, to be traversed after left child. */ + uint64_t right_file_no; + uint64_t right_offset; + /* Offset of real data in this node, after header. */ + uint32_t header_len; + /* Amount of data read into rd_buf, and amount used to parse header. */ + uint32_t rd_buf_len; + uint32_t rd_buf_sofar; + /* Current state in post-order traversal state machine. */ + enum oob_states state; + /* Buffer for reading header. */ + uchar rd_buf[5*COMPR_INT_MAX64]; + /* + True when the node is reached using only left child pointers, false + otherwise. Used to identify the left-most leaf in a tree which points to + a prior tree that must be traversed first. + */ + bool is_leftmost; + }; + std::vectorstack; + + /* State machine current state. */ + enum oob_states state; + +public: + oob_reader_mysqlbinlog(); + ~oob_reader_mysqlbinlog(); + + void start_traversal(uint64_t file_no, uint64_t offset); + bool oob_traversal_done() { return stack.empty(); } + int read_data(chunk_reader_mysqlbinlog *chunk_rd, uchar *buf, int max_len); + +private: + void push_state(enum oob_states state, uint64_t file_no, uint64_t offset, + bool is_leftmost); +}; + + +class binlog_reader_innodb : public handler_binlog_reader { + enum reader_states { + ST_read_next_event_group, ST_read_oob_data, ST_read_commit_record + }; + + chunk_reader_mysqlbinlog chunk_rd; + oob_reader_mysqlbinlog oob_reader; + chunk_reader_mysqlbinlog::saved_position saved_commit_pos; + + /* Out-of-band data to read after commit record, if any. */ + uint64_t oob_count; + uint64_t oob_last_file_no; + uint64_t oob_last_offset; + /* Any secondary out-of-band data to be also read. */ + uint64_t oob_count2; + uint64_t oob_last_file_no2; + uint64_t oob_last_offset2; + /* + The starting file_no. We stop once we've read the last record in this file + (which may span into the next file). + */ + uint64_t start_file_no; + /* Buffer to hold a page read directly from the binlog file. */ + uchar *page_buf; + /* Keep track of pending bytes in the rd_buf. */ + uint32_t rd_buf_len; + uint32_t rd_buf_sofar; + /* State for state machine reading chunks one by one. */ + enum reader_states state; + + /* Used to read the header of the commit record. */ + uchar rd_buf[5*COMPR_INT_MAX64]; +private: + int read_data(uchar *buf, uint32_t len); + +public: + binlog_reader_innodb(); + virtual ~binlog_reader_innodb(); + virtual int read_binlog_data(uchar *buf, uint32_t len) override; + virtual bool data_available() override; + virtual bool wait_available(THD *thd, const struct timespec *abstime) override; + virtual int init_gtid_pos(THD *thd, slave_connection_state *pos, + rpl_binlog_state_base *state) override; + virtual int init_legacy_pos(THD *thd, const char *filename, + ulonglong offset) override; + virtual void enable_single_file() override; + bool is_valid() { return page_buf != nullptr; } + bool init_from_fd_pos(File fd, ulonglong start_position); +}; + + +static int +read_page_mysqlbinlog(File fd, uchar *buf, uint32_t page_no) noexcept +{ + size_t read= my_pread(fd, buf, binlog_page_size, + (my_off_t)page_no * binlog_page_size, MYF(0)); + int res= 1; + if (likely(read == binlog_page_size)) + { + const uint32_t payload= (uint32_t)binlog_page_size - BINLOG_PAGE_CHECKSUM; + uint32_t crc32= uint4korr(buf + payload); + /* Allow a completely zero (empty) page as well. */ + if (unlikely(crc32 != my_crc32c(0, buf, payload)) && + (buf[0] != 0 || 0 != memcmp(buf, buf+1, binlog_page_size - 1))) + { + res= -1; + my_errno= EIO; + } + } + else if (read == (size_t)-1) + res= -1; + else + res= 0; + + return res; +} + + +chunk_reader_mysqlbinlog::chunk_reader_mysqlbinlog() + : s { 0, 0, 0, 0, 0, FSP_BINLOG_TYPE_FILLER, false, false }, + cur_file_length(0), + cur_file_handle((File)-1), + skipping_partial(false), page_loaded(false) +{ +} + + +chunk_reader_mysqlbinlog::~chunk_reader_mysqlbinlog() +{ + if (cur_file_handle >= (File)0) + my_close(cur_file_handle, MYF(0)); +} + + +int +chunk_reader_mysqlbinlog::read_error_corruption(uint64_t file_no, uint64_t page_no, + const char *msg) +{ + error("Corrupt InnoDB binlog found on page %" PRIu64 " in binlog number " + "%" PRIu64 ": %s", page_no, file_no, msg); + return -1; +} + + +int +chunk_reader_mysqlbinlog::read_data(uchar *buffer, int max_len, bool multipage) +{ + uint32_t size; + int sofar= 0; + +read_more_data: + if (max_len == 0) + return sofar; + + if (!page_loaded) + { + enum chunk_reader_status res= fetch_current_page(); + if (res == CHUNK_READER_EOF) + return 0; + if (res == CHUNK_READER_ERROR) + return -1; + } + + if (s.chunk_len == 0) + { + uchar type; + /* + This code gives warning "comparison of unsigned expression in ‘< 0’ is + always false" when BINLOG_PAGE_DATA is 0. + + So use a static assert for now; if it ever triggers, replace it with this + code: + + if (s.in_page_offset < BINLOG_PAGE_DATA) + s.in_page_offset= BINLOG_PAGE_DATA; + */ + if (0) + static_assert(BINLOG_PAGE_DATA == 0, + "Replace static_assert with code from above comment"); + + /* Check for end-of-file. */ + if ((s.page_no * binlog_page_size) + s.in_page_offset >= cur_file_length) + return sofar; + + if (s.in_page_offset >= binlog_page_size - (BINLOG_PAGE_DATA_END + 3) || + page_buffer[s.in_page_offset] == FSP_BINLOG_TYPE_FILLER) + { + DBUG_ASSERT(s.in_page_offset >= binlog_page_size - BINLOG_PAGE_DATA_END || + page_buffer[s.in_page_offset] == FSP_BINLOG_TYPE_FILLER); + goto go_next_page; + } + + type= page_buffer[s.in_page_offset]; + if (type == 0) + return 0; + + /* + Consistency check on the chunks. A record must consist in a sequence of + chunks of the same type, all but the first must have the + FSP_BINLOG_FLAG_BIT_CONT bit set, and the final one must have the + FSP_BINLOG_FLAG_BIT_LAST bit set. + */ + if (!s.in_record) + { + if (type & FSP_BINLOG_FLAG_CONT && !s.skip_current) + { + if (skipping_partial) + { + s.chunk_len= page_buffer[s.in_page_offset + 1] | + ((uint32_t)page_buffer[s.in_page_offset + 2] << 8); + s.skip_current= true; + goto skip_chunk; + } + else + return read_error_corruption(s.file_no, s.page_no, "Binlog record " + "starts with continuation chunk"); + } + } + else + { + if ((type ^ s.chunk_type) & FSP_BINLOG_TYPE_MASK) + { + /* + As a special case, we must allow a GTID state to appear in the + middle of a record. + */ + if (((uint64_t)1 << (type & FSP_BINLOG_TYPE_MASK)) & + ALLOWED_NESTED_RECORDS) + { + s.chunk_len= page_buffer[s.in_page_offset + 1] | + ((uint32_t)page_buffer[s.in_page_offset + 2] << 8); + goto skip_chunk; + } + /* Chunk type changed in the middle. */ + return read_error_corruption(s.file_no, s.page_no, "Binlog record missing " + "end chunk"); + } + if (!(type & FSP_BINLOG_FLAG_CONT)) + { + /* START chunk without END chunk. */ + return read_error_corruption(s.file_no, s.page_no, "Binlog record missing " + "end chunk"); + } + } + + s.skip_current= false; + s.chunk_type= type; + s.in_record= true; + s.chunk_len= page_buffer[s.in_page_offset + 1] | + ((uint32_t)page_buffer[s.in_page_offset + 2] << 8); + s.chunk_read_offset= 0; + } + + /* Now we have a chunk available to read data from. */ + DBUG_ASSERT(s.chunk_read_offset < s.chunk_len); + if (s.skip_current && + (s.chunk_read_offset > 0 || (s.chunk_type & FSP_BINLOG_FLAG_CONT))) + { + /* + Skip initial continuation chunks. + Used to be able to start reading potentially in the middle of a record, + ie. at a GTID state point. + */ + s.chunk_read_offset= s.chunk_len; + } + else + { + size= std::min((uint32_t)max_len, s.chunk_len - s.chunk_read_offset); + memcpy(buffer, page_buffer + s.in_page_offset + 3 + s.chunk_read_offset, size); + buffer+= size; + s.chunk_read_offset+= size; + max_len-= size; + sofar+= size; + } + + if (s.chunk_len > s.chunk_read_offset) + { + DBUG_ASSERT(max_len == 0 /* otherwise would have read more */); + return sofar; + } + + /* We have read all of the chunk. Move to next chunk or end of the record. */ +skip_chunk: + s.in_page_offset+= 3 + s.chunk_len; + s.chunk_len= 0; + s.chunk_read_offset= 0; + + if (s.chunk_type & FSP_BINLOG_FLAG_LAST) + { + s.in_record= false; /* End of record. */ + s.skip_current= false; + } + + if (s.in_page_offset >= binlog_page_size - (BINLOG_PAGE_DATA_END + 3) && + (s.page_no * binlog_page_size) + s.in_page_offset < cur_file_length) + { +go_next_page: + /* End of page reached, move to the next page. */ + ++s.page_no; + page_loaded= false; + s.in_page_offset= 0; + + if (cur_file_handle >= (File)0 && + (s.page_no * binlog_page_size) >= cur_file_length) + { + /* Move to the next file. */ + my_close(cur_file_handle, MYF(0)); + cur_file_handle= (File)-1; + cur_file_length= ~(uint64_t)0; + ++s.file_no; + s.page_no= 1; /* Skip the header page. */ + } + } + + if (sofar > 0 && (!multipage || !s.in_record)) + return sofar; + + goto read_more_data; +} + + +oob_reader_mysqlbinlog::oob_reader_mysqlbinlog() +{ + /* Nothing. */ +} + + +oob_reader_mysqlbinlog::~oob_reader_mysqlbinlog() +{ + /* Nothing. */ +} + + +void +oob_reader_mysqlbinlog::push_state(enum oob_states state, uint64_t file_no, + uint64_t offset, bool is_leftmost) +{ + stack_entry new_entry; + new_entry.state= state; + new_entry.file_no= file_no; + new_entry.offset= offset; + new_entry.is_leftmost= is_leftmost; + stack.emplace_back(std::move(new_entry)); +} + + +void +oob_reader_mysqlbinlog::start_traversal(uint64_t file_no, uint64_t offset) +{ + stack.clear(); + push_state(ST_initial, file_no, offset, true); +} + + +/* + Read from out-of-band event group data. + + Does a state-machine incremental traversal of the forest of perfect binary + trees of oob records in the event group. May read just the data available + on one page, thus returning less than the requested number of bytes (this + is to prefer to inspect each page only once, returning data page-by-page as + long as reader asks for at least a full page worth of data). +*/ +int +oob_reader_mysqlbinlog::read_data(chunk_reader_mysqlbinlog *chunk_rd, + uchar *buf, int len) +{ + stack_entry *e; + uint64_t chunk_idx; + uint64_t left_file_no; + uint64_t left_offset; + int res; + const uchar *p_end; + const uchar *p; + std::pair v_and_p; + int size; + + if (stack.empty()) + { + DBUG_ASSERT(0 /* Should not call when no more oob data to read. */); + return 0; + } + +again: + e= &(stack[stack.size() - 1]); + switch (e->state) + { + case ST_initial: + chunk_rd->seek(e->file_no, e->offset); + static_assert(sizeof(e->rd_buf) == 5*COMPR_INT_MAX64, + "rd_buf size must match code using it"); + res= chunk_rd->read_data(e->rd_buf, 5*COMPR_INT_MAX64, true); + if (res < 0) + return -1; + if (chunk_rd->cur_type() != FSP_BINLOG_TYPE_OOB_DATA) + return chunk_rd->read_error_corruption("Wrong chunk type"); + if (res == 0) + return chunk_rd->read_error_corruption("Unexpected EOF, expected " + "oob chunk"); + e->rd_buf_len= res; + p_end= e->rd_buf + res; + v_and_p= compr_int_read(e->rd_buf); + p= v_and_p.second; + if (p > p_end) + return chunk_rd->read_error_corruption("Short chunk"); + chunk_idx= v_and_p.first; + (void)chunk_idx; + + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd->read_error_corruption("Short chunk"); + left_file_no= v_and_p.first; + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd->read_error_corruption("Short chunk"); + left_offset= v_and_p.first; + + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd->read_error_corruption("Short chunk"); + e->right_file_no= v_and_p.first; + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd->read_error_corruption("Short chunk"); + e->right_offset= v_and_p.first; + e->rd_buf_sofar= (uint32_t)(p - e->rd_buf); + if (left_file_no == 0 && left_offset == 0) + { + /* Leaf node. */ + if (e->is_leftmost && !(e->right_file_no == 0 && e->right_offset == 0)) + { + /* Traverse the prior tree(s) in the forst. */ + e->state= ST_traversing_prior_trees; + chunk_rd->save_pos(&e->saved_pos); + push_state(ST_initial, e->right_file_no, e->right_offset, true); + } + else + e->state= ST_self; + } + else + { + e->state= ST_traversing_left_child; + chunk_rd->save_pos(&e->saved_pos); + push_state(ST_initial, left_file_no, left_offset, e->is_leftmost); + } + goto again; + + case ST_traversing_prior_trees: + chunk_rd->restore_pos(&e->saved_pos); + e->state= ST_self; + goto again; + + case ST_traversing_left_child: + e->state= ST_traversing_right_child; + push_state(ST_initial, e->right_file_no, e->right_offset, false); + goto again; + + case ST_traversing_right_child: + chunk_rd->restore_pos(&e->saved_pos); + e->state= ST_self; + goto again; + + case ST_self: + size= 0; + if (e->rd_buf_len > e->rd_buf_sofar) + { + /* Use any excess data from when the header was read. */ + size= std::min((int)(e->rd_buf_len - e->rd_buf_sofar), len); + memcpy(buf, e->rd_buf + e->rd_buf_sofar, size); + e->rd_buf_sofar+= size; + len-= size; + buf+= size; + } + + if (len > 0 && !chunk_rd->end_of_record()) + { + res= chunk_rd->read_data(buf, len, false); + if (res < 0) + return -1; + size+= res; + } + + if (chunk_rd->end_of_record()) + { + /* This oob record done, pop the state. */ + DBUG_ASSERT(!stack.empty()); + stack.erase(stack.end() - 1, stack.end()); + } + return size; + + default: + DBUG_ASSERT(0); + return -1; + } +} + + +binlog_reader_innodb::binlog_reader_innodb() + : oob_count(0), oob_last_file_no(0), oob_last_offset(0), + oob_count2(0), oob_last_file_no2(0), oob_last_offset2(0), + start_file_no(~(uint64_t)0), + rd_buf_len(0), rd_buf_sofar(0), state(ST_read_next_event_group) +{ + page_buf= (uchar *) + my_malloc(PSI_NOT_INSTRUMENTED, BINLOG_PAGE_SIZE_MAX, MYF(MY_WME)); + chunk_rd.set_page_buf(page_buf); +} + + +binlog_reader_innodb::~binlog_reader_innodb() +{ + my_free(page_buf); +} + + +void +chunk_reader_mysqlbinlog::set_fd(File fd) +{ + if (cur_file_handle != (File)-1) + { + my_close(cur_file_handle, MYF(0)); + cur_file_length= ~(uint64_t)0; + page_loaded= false; + } + cur_file_handle= fd; + my_off_t old_pos= my_tell(fd, MYF(0)); + if (old_pos != (my_off_t)-1) + { + /* Will be ~0 if we cannot seek the file. */ + cur_file_length= my_seek(fd, 0, SEEK_END, MYF(0)); + my_seek(fd, old_pos, SEEK_SET, MYF(0)); + } +} + + +bool +binlog_reader_innodb::data_available() +{ + DBUG_ASSERT(0 /* Should not be used in mysqlbinlog. */); + return true; +} + + +bool +binlog_reader_innodb::wait_available(THD *thd, const struct timespec *abstime) +{ + DBUG_ASSERT(0 /* Should not be used in mysqlbinlog. */); + return true; +} + + +int +binlog_reader_innodb::init_gtid_pos(THD *thd, slave_connection_state *pos, + rpl_binlog_state_base *state) +{ + DBUG_ASSERT(0 /* Should not be used in mysqlbinlog. */); + return 1; +} + + +int +binlog_reader_innodb::init_legacy_pos(THD *thd, const char *filename, + ulonglong offset) +{ + DBUG_ASSERT(0 /* Should not be used in mysqlbinlog. */); + return 1; +} + + +void +binlog_reader_innodb::enable_single_file() +{ + DBUG_ASSERT(0 /* Should not be used in mysqlbinlog. */); +} + + +int +binlog_reader_innodb::read_binlog_data(uchar *buf, uint32_t len) +{ + int res= read_data(buf, len); + return res; +} + + +bool +binlog_reader_innodb::init_from_fd_pos(File fd, ulonglong start_position) +{ + chunk_rd.set_fd(fd); + if (chunk_rd.parse_file_header()) + return true; + uint64_t prev_start_file_no= start_file_no; + start_file_no= chunk_rd.s.file_no; + if (prev_start_file_no != ~(uint64_t)0 && + prev_start_file_no + 1 == chunk_rd.s.file_no) + { + /* Continuing in the file following the previous one. */ + } + else + { + if (start_position < binlog_page_size) + start_position= binlog_page_size; + chunk_rd.seek(chunk_rd.s.file_no, (uint64_t)start_position); + chunk_rd.skip_partial(true); + } + return false; +} + + +int binlog_reader_innodb::read_data(uchar *buf, uint32_t len) +{ + int res; + const uchar *p_end; + const uchar *p; + std::pair v_and_p; + int sofar= 0; + +again: + switch (state) + { + case ST_read_next_event_group: + if (chunk_rd.s.file_no > start_file_no || + (chunk_rd.s.file_no == start_file_no && chunk_rd.is_end_of_file())) + { + /* + We have read the entire file, return EOF. + If the user specified to read the following file also, we may + continue where we left in that file later. + */ + return sofar; + } + static_assert(sizeof(rd_buf) == 5*COMPR_INT_MAX64, + "rd_buf size must match code using it"); + res= chunk_rd.read_data(rd_buf, 5*COMPR_INT_MAX64, true); + if (res < 0) + return res; + if (res == 0) + return sofar; + if (chunk_rd.cur_type() != FSP_BINLOG_TYPE_COMMIT) + { + chunk_rd.skip_current(); + goto again; + } + /* Found the start of a commit record. */ + chunk_rd.skip_partial(false); + + /* Read the header of the commit record to see if there's any oob data. */ + rd_buf_len= res; + p_end= rd_buf + res; + v_and_p= compr_int_read(rd_buf); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + oob_count= v_and_p.first; + oob_count2= 0; + + if (oob_count > 0) + { + /* Skip the pointer to first chunk. */ + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + oob_last_file_no= v_and_p.first; + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + oob_last_offset= v_and_p.first; + + /* Check for any secondary oob data. */ + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + oob_count2= v_and_p.first; + + if (oob_count2 > 0) + { + /* Skip the pointer to first chunk. */ + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + oob_last_file_no2= v_and_p.first; + v_and_p= compr_int_read(p); + p= v_and_p.second; + if (p > p_end) + return chunk_rd.read_error_corruption("Short chunk"); + oob_last_offset2= v_and_p.first; + } + } + + rd_buf_sofar= (uint32_t)(p - rd_buf); + state= ST_read_commit_record; + goto again; + + case ST_read_commit_record: + if (rd_buf_len > rd_buf_sofar) + { + /* Use any excess data from when the header was read. */ + int size= std::min((int)(rd_buf_len - rd_buf_sofar), (int)len); + memcpy(buf, rd_buf + rd_buf_sofar, size); + rd_buf_sofar+= size; + len-= size; + buf+= size; + sofar+= size; + } + + if (len > 0 && !chunk_rd.end_of_record()) + { + res= chunk_rd.read_data(buf, len, false); + if (res < 0) + return -1; + len-= res; + buf+= res; + sofar+= res; + } + + if (rd_buf_sofar == rd_buf_len && chunk_rd.end_of_record()) + { + if (oob_count == 0) + { + state= ST_read_next_event_group; + if (len > 0 && !chunk_rd.is_end_of_page()) + { + /* + Let us try to read more data from this page. The goal is to read + from each page only once, as long as caller passes in a buffer at + least as big as our page size. Though commit record header that + spans a page boundary or oob records can break this property. + */ + goto again; + } + } + else + { + oob_reader.start_traversal(oob_last_file_no, oob_last_offset); + chunk_rd.save_pos(&saved_commit_pos); + state= ST_read_oob_data; + } + if (sofar == 0) + goto again; + } + + return sofar; + + case ST_read_oob_data: + res= oob_reader.read_data(&chunk_rd, buf, len); + if (res < 0) + return -1; + if (oob_reader.oob_traversal_done()) + { + if (oob_count2 > 0) + { + /* Switch over to secondary oob data. */ + oob_count= oob_count2; + oob_count2= 0; + oob_last_file_no= oob_last_file_no2; + oob_last_offset= oob_last_offset2; + oob_reader.start_traversal(oob_last_file_no, oob_last_offset); + state= ST_read_oob_data; + } + else + { + chunk_rd.restore_pos(&saved_commit_pos); + state= ST_read_next_event_group; + } + } + if (res == 0) + { + DBUG_ASSERT(0 /* Should have had oob_traversal_done() last time then. */); + if (sofar == 0) + goto again; + } + return sofar + res; + + default: + DBUG_ASSERT(0); + return -1; + } +} + + +int +chunk_reader_mysqlbinlog::parse_file_header() +{ + binlog_page_size= BINLOG_HEADER_PAGE_SIZE; // Until we get the real page size + if (read_page_mysqlbinlog(cur_file_handle, page_buffer, 0) <= 0) + { + error("Cannot read first page of InnoDB binlog file"); + return -1; + } + const uint32_t payload= BINLOG_HEADER_PAGE_SIZE - BINLOG_PAGE_CHECKSUM; + uint32_t crc32= uint4korr(page_buffer + payload); + if (crc32 != my_crc32c(0, page_buffer, payload)) + { + error("Invalid checksum on first page, cannot read binlog file"); + return -1; + } + uint32_t vers_major= uint4korr(page_buffer + 8); + if (vers_major > INNODB_BINLOG_FILE_VERS_MAJOR) + { + error("Unsupported version of InnoDB binlog file, cannot read"); + return -1; + } + binlog_page_size= 1 << uint4korr(page_buffer + 4); + s.file_no= uint8korr(page_buffer + 16); + return 0; +} + + +enum chunk_reader_mysqlbinlog::chunk_reader_status +chunk_reader_mysqlbinlog::fetch_current_page() +{ + uint64_t offset; + page_loaded= false; + for (;;) + { + if (cur_file_handle < (File)0) + { + char filename[FN_REFLEN + 1]; + MY_STAT stat_buf; + + snprintf(filename, FN_REFLEN, + "%s/" BINLOG_NAME_BASE "%06" PRIu64 BINLOG_NAME_EXT, + binlog_dir, s.file_no); + cur_file_handle= my_open(filename, O_RDONLY | O_BINARY, MYF(MY_WME)); + if (cur_file_handle < (File)0) { + cur_file_handle= (File)-1; + cur_file_length= ~(uint64_t)0; + /* + For mysqlbinlog where the user specifies the file, treat a missing + file as EOF, on the idea that we read as much as possible from what + the user supplied. But still use MY_WME in the my_open() to give + some indication that we stopped due to a missing file. + */ + return errno == ENOENT ? CHUNK_READER_EOF : CHUNK_READER_ERROR; + } + if (my_fstat(cur_file_handle, &stat_buf, MYF(0))) { + error("Cannot stat() file '%s', errno: %d", filename, errno); + my_close(cur_file_handle, MYF(0)); + cur_file_handle= (File)-1; + cur_file_length= ~(uint64_t)0; + return CHUNK_READER_ERROR; + } + cur_file_length= stat_buf.st_size; + } + + offset= (s.page_no * binlog_page_size) | s.in_page_offset; + if (offset >= cur_file_length) { + /* End of this file, move to the next one. */ + goto_next_file: + if (cur_file_handle >= (File)0) + { + my_close(cur_file_handle, MYF(0)); + cur_file_handle= (File)-1; + cur_file_length= ~(uint64_t)0; + } + ++s.file_no; + s.page_no= 1; /* Skip the header page. */ + continue; + } + break; + } + + int res= read_page_mysqlbinlog(cur_file_handle, page_buffer, s.page_no); + if (res < 0) + return CHUNK_READER_ERROR; + if (res == 0) + goto goto_next_file; + page_loaded= true; + return CHUNK_READER_FOUND; +} + + +void +chunk_reader_mysqlbinlog::restore_pos(chunk_reader_mysqlbinlog::saved_position *pos) +{ + if (cur_file_handle != (File)-1 && pos->file_no != s.file_no) + { + /* Seek to a different file than currently open, close it. */ + my_close(cur_file_handle, MYF(0)); + cur_file_handle= (File)-1; + cur_file_length= ~(uint64_t)0; + } + s= *pos; + page_loaded= false; +} + + +void +chunk_reader_mysqlbinlog::seek(uint64_t file_no, uint64_t offset) +{ + saved_position pos { + file_no, (uint32_t)(offset / binlog_page_size), + (uint32_t)(offset % binlog_page_size), + 0, 0, FSP_BINLOG_TYPE_FILLER, false, false }; + restore_pos(&pos); +} + + +bool +open_engine_binlog(handler_binlog_reader *generic_reader, + ulonglong start_position, + const char *filename, IO_CACHE *opened_cache) +{ + binlog_reader_innodb *reader= (binlog_reader_innodb *)generic_reader; + if (!reader->is_valid()) + { + error("Out of memory allocating page buffer"); + return true; + } + static_assert(sizeof(binlog_dir) >= FN_REFLEN + 1, + "dirname_part() needs up to FN_REFLEN char buffer"); + size_t dummy; + dirname_part(binlog_dir, filename, &dummy); + if (!strlen(binlog_dir)) + strncpy(binlog_dir, ".", sizeof(binlog_dir) - 1); + return reader->init_from_fd_pos(dup(opened_cache->file), start_position); +} + + +handler_binlog_reader * +get_binlog_reader_innodb() +{ + return new binlog_reader_innodb(); +} diff --git a/client/mysqlbinlog-engine.h b/client/mysqlbinlog-engine.h new file mode 100644 index 0000000000000..1438abeb48069 --- /dev/null +++ b/client/mysqlbinlog-engine.h @@ -0,0 +1,32 @@ +/* Copyright (c) 2025, Kristian Nielsen. + + 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 */ + +#include +#include + +#include "handler_binlog_reader.h" + + +static constexpr uint32_t BINLOG_HEADER_PAGE_SIZE= 512; +extern const char *INNODB_BINLOG_MAGIC; + +extern handler_binlog_reader *get_binlog_reader_innodb(); +extern bool open_engine_binlog(handler_binlog_reader *reader, + ulonglong start_position, + const char *filename, IO_CACHE *opened_cache); + + +/* Shared functions defined in mysqlbinlog.cc */ +extern void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 634ea945c1803..5393bd98e6f83 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -43,6 +43,8 @@ #include "sql_priv.h" #include "sql_basic_types.h" #include +#include "handler_binlog_reader.h" +#include "mysqlbinlog-engine.h" #include "log_event.h" #include "compat56.h" #include "sql_common.h" @@ -70,7 +72,6 @@ extern "C" unsigned char *mysql_net_store_length(unsigned char *packet, size_t l Rpl_filter *binlog_filter= 0; -#define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) /* Needed for Rpl_filter */ @@ -109,7 +110,7 @@ static const char *load_groups[]= { "mysqlbinlog", "mariadb-binlog", "client", "client-server", "client-mariadb", 0 }; -static void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); +void error(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static void warning(const char *format, ...) ATTRIBUTE_FORMAT(printf, 1, 2); static bool one_database=0, one_table=0, to_last_remote_log= 0, disable_log_bin= 0; @@ -203,6 +204,14 @@ enum Exit_status { OK_EOF, }; + +static enum Binlog_format { + ORIGINAL_BINLOG_FORMAT, INNODB_BINLOG_FORMAT +} binlog_format= ORIGINAL_BINLOG_FORMAT; + +static handler_binlog_reader *engine_binlog_reader; + + /** Pointer to the last read Annotate_rows_log_event. Having read an Annotate_rows event, we should not print it immediately because all @@ -221,8 +230,17 @@ static void free_annotate_event() } } -Log_event* read_remote_annotate_event(uchar* net_buf, ulong event_len, - const char **error_msg) +/** + The typical logic for an event read from a remote server is to register the + temp_buf of the net object to the event, such that each event will re-use + this same buffer. However, some events are re-referenced later, and their + memory/data is still needed. For example, Table_map_log_events are needed + for Partial_rows_log_events, as they are re-output for the last event in + the group. +*/ +Log_event *read_self_managing_buffer_event_from_net(uchar *net_buf, + ulong event_len, + const char **error_msg) { uchar *event_buf; Log_event* event; @@ -309,17 +327,18 @@ class Load_log_processor filename. The numerical suffix will be written to this position. Note that there must be a least five bytes of allocated memory after file_name_end. + @param[in] file_name_end_size Size of the memory area pointed to file_name_end. @retval -1 Error (can't find new filename). @retval >=0 Found file. */ - File create_unique_file(char *filename, char *file_name_end) + File create_unique_file(char *filename, char *file_name_end, size_t file_name_end_size) { File res; /* If we have to try more than 1000 times, something is seriously wrong */ for (uint version= 0; version<1000; version++) { - sprintf(file_name_end,"-%x",version); + snprintf(file_name_end, file_name_end_size,"-%x",version); if ((res= my_create(filename,0, O_CREAT|O_EXCL|O_BINARY|O_WRONLY,MYF(0)))!=-1) return res; @@ -441,9 +460,9 @@ Exit_status Load_log_processor::process_first_event(const char *bname, ptr= fname + target_dir_name_len; memcpy(ptr,bname,blen); ptr+= blen; - ptr+= sprintf(ptr, "-%x", file_id); + ptr+= snprintf(ptr, full_len - (ptr - fname), "-%x", file_id); - if ((file= create_unique_file(fname,ptr)) < 0) + if ((file= create_unique_file(fname,ptr,full_len - (ptr - fname))) < 0) { error("Could not construct local filename %s%s.", target_dir_name,bname); @@ -690,13 +709,15 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev) { /* These events must be printed in base64 format, if printed. + In the original binlog format (no --binlog-storage-engine), base64 format requires a FD event to be safe, so if no FD event has been printed, we give an error. Except if user passed --short-form, because --short-form disables printing row events. */ - if (!print_event_info->printed_fd_event && !short_form && + if (binlog_format == ORIGINAL_BINLOG_FORMAT && + !print_event_info->printed_fd_event && !short_form && opt_base64_output_mode != BASE64_OUTPUT_DECODE_ROWS && opt_base64_output_mode != BASE64_OUTPUT_NEVER) { @@ -712,6 +733,66 @@ static bool print_base64(PRINT_EVENT_INFO *print_event_info, Log_event *ev) return ev->print(result_file, print_event_info); } +static bool print_partial_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev) +{ + bool result= 0; + Partial_rows_log_event *prle= static_cast(ev); + if (prle->seq_no == 1) + { + /* + First Partial_row_event in the group, we can get our Rows_log_event + header info here for filtering. + */ + const uchar *rows_data_begin= prle->ev_buffer_base + prle->start_offset; + Log_event_type event_type= (Log_event_type)(uchar)rows_data_begin[EVENT_TYPE_OFFSET]; + uint8 const post_header_len= glob_description_event->post_header_len[event_type-1]; + const uchar *table_id_ptr= rows_data_begin + + print_event_info->common_header_len + + RW_MAPID_OFFSET; + + ulonglong table_id; + if (post_header_len == 6) + table_id= uint4korr(table_id_ptr); + else + table_id= (ulonglong) uint6korr(table_id_ptr); + + /* + Cache the flags of the Rows_log_event to use it for the last + Partial_rows_log_event in the group + */ + uint32 rows_ev_flags= + uint2korr(rows_data_begin + print_event_info->common_header_len + + post_header_len + RW_MAPID_OFFSET + RW_FLAGS_OFFSET); + print_event_info->partial_rows_rows_ev_flags= rows_ev_flags; + + if (print_event_info->m_table_map_ignored.get_table(table_id)) + print_event_info->deactivate_current_partial_rows_ev_group(); + } + + if (print_event_info->is_partial_rows_ev_group_active()) + result= prle->print(result_file, print_event_info); + + /* Last fragment */ + if (prle->seq_no == prle->total_fragments) + { + /* + If this is the last Partial_rows_log_event in the group and the + underlying Rows_log_event is the last in the transaction, then it is safe + to clear the table_maps because they won't be used again. + */ + if (print_event_info->partial_rows_rows_ev_flags & + Rows_log_event::STMT_END_F) + print_event_info->m_table_map_ignored.clear_tables(); + + /* + Active the next Partial_rows_log_event group as default + */ + print_event_info->activate_current_partial_rows_ev_group(); + } + + return result; +} + static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, ulonglong table_id, bool is_stmt_end) @@ -755,6 +836,10 @@ static bool print_row_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, /* Now is safe to clear ignored map (clear_tables will also delete original table map events stored in the map). + + Note print_event_info->m_table_map is not cleared here because it is used + when printing the number of events in the Rows_log_event. Instead, this + map is cleared when a new transaction is started. */ if (print_event_info->m_table_map_ignored.count() > 0) print_event_info->m_table_map_ignored.clear_tables(); @@ -897,7 +982,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, /* Run time estimation of the output window configuration. - Do not validate GLLE information is start position is provided as a file + Do not validate GLLE information if start position is provided as a file offset. */ if (ev_type == GTID_LIST_EVENT && ev->when) @@ -969,6 +1054,13 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print_event_info->deactivate_current_event_group(); } + /* + Start a new GTID event with a fresh table map state. This is because + table maps are cached for each transaction, e.g. for + Partial_rows_log_event printing. + */ + print_event_info->m_table_map.clear_tables(); + /* Where we always ensure the initial binlog state is valid, we only continually monitor the GTID stream for validity if we are in GTID @@ -1187,13 +1279,22 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case TABLE_MAP_EVENT: { Table_map_log_event *map= ((Table_map_log_event *)ev); + destroy_evt= FALSE; + if (shall_skip_database(map->get_db_name()) || shall_skip_table(map->get_table_name())) { print_event_info->m_table_map_ignored.set_table(map->get_table_id(), map); - destroy_evt= FALSE; goto end; } + + /* + Always keep the Table_map_log_event around in case a group of + Partial_rows_log_events is seen, where we will write the content of + the Table_map_log_event for the last fragment so it can be re-applied. + */ + print_event_info->m_table_map.set_table(map->get_table_id(), map); + #ifdef WHEN_FLASHBACK_REVIEW_READY /* Create review table for Flashback */ if (opt_flashback_review) @@ -1360,6 +1461,12 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, destroy_evt= FALSE; break; } + case PARTIAL_ROW_DATA_EVENT: + { + if (print_partial_row_event(print_event_info, ev)) + goto err; + break; + } case START_ENCRYPTION_EVENT: glob_description_event->start_decryption((Start_encryption_log_event*)ev); /* fall through */ @@ -1755,7 +1862,7 @@ static void error_or_warning(const char *format, va_list args, const char *msg) @param format Printf-style format string, followed by printf varargs. */ -static void error(const char *format,...) +void error(const char *format,...) { va_list args; va_start(args, format); @@ -1851,6 +1958,7 @@ static void cleanup() delete_dynamic(&binlog_events); delete_dynamic(&events_in_stmt); } + delete engine_binlog_reader; DBUG_VOID_RETURN; } @@ -2458,6 +2566,8 @@ static Exit_status dump_log_entries(const char* logname) rc= (remote_opt ? dump_remote_log_entries(&print_event_info, logname) : dump_local_log_entries(&print_event_info, logname)); + print_event_info.m_table_map.clear_tables(); + if (rc == ERROR_STOP) return rc; @@ -2533,6 +2643,7 @@ static Exit_status check_master_version() if (position_gtid_filter && position_gtid_filter->get_num_start_gtids() > 0) { + to_last_remote_log= TRUE; char str_buf[256]; String query_str(str_buf, sizeof(str_buf), system_charset_info); query_str.length(0); @@ -2547,7 +2658,7 @@ static Exit_status check_master_version() char buf[256]; rpl_gtid *start_gtid= &start_gtids[gtid_idx]; - sprintf(buf, "%u-%u-%llu", + snprintf(buf, sizeof(buf), "%u-%u-%llu", start_gtid->domain_id, start_gtid->server_id, start_gtid->seq_no); query_str.append(buf, strlen(buf)); @@ -2573,6 +2684,7 @@ static Exit_status check_master_version() case 10: case 11: case 12: + case 13: glob_description_event= new Format_description_log_event(4); break; default: @@ -2605,12 +2717,15 @@ static Exit_status handle_event_text_mode(PRINT_EVENT_INFO *print_event_info, NET *net= &mysql->net; DBUG_ENTER("handle_event_text_mode"); - if (net->read_pos[5] == ANNOTATE_ROWS_EVENT) + if (net->read_pos[5] == ANNOTATE_ROWS_EVENT || + net->read_pos[5] == TABLE_MAP_EVENT) { - if (!(ev= read_remote_annotate_event(net->read_pos + 1, *len - 1, - &error_msg))) + if (!(ev= read_self_managing_buffer_event_from_net(net->read_pos + 1, + *len - 1, &error_msg))) { - error("Could not construct annotate event object: %s", error_msg); + error("Could not construct %s event object: %s", + net->read_pos[5] == ANNOTATE_ROWS_EVENT ? "annotate" : "table_map", + error_msg); DBUG_RETURN(ERROR_STOP); } } @@ -2988,7 +3103,35 @@ static Exit_status check_header(IO_CACHE* file, error("Failed reading header; probably an empty file."); return ERROR_STOP; } - if (memcmp(header, BINLOG_MAGIC, sizeof(header))) + if (0 == memcmp(header, INNODB_BINLOG_MAGIC, sizeof(header))) + { + binlog_format= INNODB_BINLOG_FORMAT; + if (!engine_binlog_reader) + { + engine_binlog_reader= get_binlog_reader_innodb(); + if (!engine_binlog_reader) + { + error("Out of memory setting up reader for InnoDB-implemented binlog."); + return ERROR_STOP; + } + } + /* + New engine-implemented binlog always does checksum verification on the + page level. + */ + opt_verify_binlog_checksum= 0; + /* + New engine-implemented binlog does not contain format description + events. + */ + goto end; + } + else if (header[0] == '\0' && !memcmp(header, header+1, sizeof(header)-1)) + { + /* This is an empty InnoDB binlog file, pre-allocated but not yet used. */ + return OK_EOF; + } + else if (memcmp(header, BINLOG_MAGIC, sizeof(header))) { error("File is not a binary log file."); return ERROR_STOP; @@ -3098,6 +3241,7 @@ static Exit_status check_header(IO_CACHE* file, break; } } +end: my_b_seek(file, pos); return OK_CONTINUE; } @@ -3135,8 +3279,19 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, my_close(fd, MYF(MY_WME)); return ERROR_STOP; } - if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE) + retval= check_header(file, print_event_info, logname); + if (retval != OK_CONTINUE) + { + if (retval == OK_EOF) + { + /* + Empty InnoDB-implemented binlog file. Just skip it (but still + continue with any following files user specified). + */ + retval= OK_CONTINUE; + } goto end; + } } else { @@ -3162,8 +3317,13 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, error("Failed to init IO cache."); return ERROR_STOP; } - if ((retval= check_header(file, print_event_info, logname)) != OK_CONTINUE) + retval= check_header(file, print_event_info, logname); + if (retval != OK_CONTINUE) + { + if (retval == OK_EOF) + retval= OK_CONTINUE; goto end; + } if (start_position) { /* skip 'start_position' characters from stdin */ @@ -3192,15 +3352,56 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, error("Failed reading from file."); goto err; } + if (binlog_format == INNODB_BINLOG_FORMAT) + { + if (open_engine_binlog(engine_binlog_reader, start_position, logname, file)) + goto err; + } for (;;) { char llbuff[21]; my_off_t old_off = my_b_tell(file); int read_error; + Log_event* ev; - Log_event* ev = Log_event::read_log_event(file, &read_error, - glob_description_event, - opt_verify_binlog_checksum); + if (binlog_format == INNODB_BINLOG_FORMAT) + { + String packet; + int res= engine_binlog_reader->read_log_event(&packet, 0, MAX_MAX_ALLOWED_PACKET); + if (res == LOG_READ_EOF) + { + ev= nullptr; + read_error= 0; + } + else if (res < 0) + { + ev= nullptr; + read_error= -1; + } + else + { + const char *errmsg= nullptr; + ev= Log_event::read_log_event((uchar *)packet.ptr(), packet.length(), + &errmsg, glob_description_event, + FALSE, FALSE); + if (!ev) + { + error("Error reading event: %s", errmsg); + read_error= -1; + } + else + { + ev->register_temp_buf((uchar *)packet.release(), true); + read_error= 0; + } + } + } + else + { + ev= Log_event::read_log_event(file, &read_error, + glob_description_event, + opt_verify_binlog_checksum); + } if (!ev) { /* @@ -3226,6 +3427,7 @@ static Exit_status dump_local_log_entries(PRINT_EVENT_INFO *print_event_info, the size of the event, unless the event is encrypted. */ DBUG_ASSERT( + binlog_format == INNODB_BINLOG_FORMAT || ((ev->get_type_code() == UNKNOWN_EVENT && ((Unknown_log_event *) ev)->what == Unknown_log_event::ENCRYPTED)) || old_off + ev->data_written == my_b_tell(file)); diff --git a/client/mysqldump.cc b/client/mysqldump.cc index 183ef09b30652..d86eda1a43e66 100644 --- a/client/mysqldump.cc +++ b/client/mysqldump.cc @@ -133,7 +133,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m opt_events= 0, opt_comments_used= 0, opt_alltspcs=0, opt_notspcs= 0, opt_logging, opt_header=0, opt_update_history= 0, - opt_drop_trigger= 0, opt_dump_history= 0; + opt_drop_trigger= 0, opt_dump_history= 0, opt_wildcards= 0; #define OPT_SYSTEM_ALL 1 #define OPT_SYSTEM_USERS 2 #define OPT_SYSTEM_PLUGINS 4 @@ -142,7 +142,7 @@ static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, opt_no_data_m #define OPT_SYSTEM_STATS 32 #define OPT_SYSTEM_TIMEZONES 64 static const char *opt_system_type_values[]= - {"all", "users", "plugins", "udfs", "servers", "stats", "timezones"}; + {"all", "users", "plugins", "udfs", "servers", "stats", "timezones", NullS}; static TYPELIB opt_system_types=CREATE_TYPELIB_FOR(opt_system_type_values); static ulonglong opt_system= 0ULL; static my_bool insert_pat_inited= 0, debug_info_flag= 0, debug_check_flag= 0, @@ -327,8 +327,14 @@ static struct my_option my_long_options[] = "Include all MariaDB specific create options.", &create_options, &create_options, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"databases", 'B', - "Dump several databases. Note the difference in usage; in this case no tables are given. All name arguments are regarded as database names. 'USE db_name;' will be included in the output.", + "Dump several databases. Note the difference in usage; in this case no " + "tables are given. All name arguments are regarded as database names. " + "'USE db_name;' will be included in the output.", &opt_databases, &opt_databases, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"wildcards", 'L', "Usage of wildcards in the table/database name. Without " + "option \"databases\" wildcards are only recognized in table names. " + "With the \"databases\" option - in databases names.", + &opt_wildcards, &opt_wildcards, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, #ifdef DBUG_OFF {"debug", '#', "This is a non-debug version. Catch this and exit.", 0,0, 0, GET_DISABLED, OPT_ARG, 0, 0, 0, 0, 0, 0}, @@ -441,7 +447,7 @@ static struct my_option my_long_options[] = {"ignore-database", OPT_IGNORE_DATABASE, "Do not dump the specified database. To specify more than one database to ignore, " "use the directive multiple times, once for each database. Only takes effect " - "when used together with --all-databases|-A", + "when used together with --all-databases or --wildcards --databases.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, {"ignore-table-data", OPT_IGNORE_DATA, "Do not dump the specified table data. To specify more than one table " @@ -492,7 +498,7 @@ static struct my_option my_long_options[] = {"max_allowed_packet", 0, "The maximum packet length to send to or receive from server.", &opt_max_allowed_packet, &opt_max_allowed_packet, 0, - GET_ULONG, REQUIRED_ARG, 24*1024*1024, 4096, + GET_ULONG, REQUIRED_ARG, 1024LL*1024*1024, 4096, (longlong) 2L*1024L*1024L*1024L, 0, 1024, 0}, {"max-statement-time", 0, "Max statement execution time. If unset, overrides server default with 0.", @@ -1344,10 +1350,11 @@ static int get_options(int *argc, char ***argv) my_progname_short); return(EX_USAGE); } - if (ignore_database.records && !opt_alldbs) + if (ignore_database.records && !opt_alldbs && !(opt_wildcards && opt_databases)) { fprintf(stderr, - "%s: --ignore-database can only be used together with --all-databases.\n", + "%s: --ignore-database can only be used together with --all-databases" + " or --wildcards --databases.\n", my_progname_short); return(EX_USAGE); } @@ -1942,6 +1949,40 @@ static char *cover_definer_clause(const char *stmt_str, return query_str; } + +static char *format_fs_safe_filename(const char *from, char *to, size_t to_size) +{ + if (check_if_legal_tablename(from)) + strxnmov(to, to_size - 1, from , "@@@", NULL); + else + { + uint errors, len; + len= my_convert(to, (uint32)(to_size - 1), &my_charset_filename, + from, (uint32) strlen(from), charset_info, &errors); + to[len]= 0; + } + return to; +} + +static void format_fs_safe_output_dir(const char *db, char *out_dir, size_t out_size) +{ + DBUG_ASSERT(opt_dir); + char fs_safe_db[FN_REFLEN]; + format_fs_safe_filename(db, fs_safe_db, sizeof(fs_safe_db)); + my_snprintf(out_dir, out_size, "%s/%s", opt_dir, fs_safe_db); +} + +static const char* build_path_for_table(char *to, const char *dir, + const char *table, const char *ext) +{ + char filename[FN_REFLEN], tmp_path[FN_REFLEN]; + convert_dirname(tmp_path, dir, NULL); + my_load_path(tmp_path, tmp_path, NULL); + format_fs_safe_filename(table, filename, sizeof(filename)); + return fn_format(to, filename, tmp_path, ext, MYF(MY_UNPACK_FILENAME)); +} + + /* Open a new .sql file to dump the table or view into @@ -1957,18 +1998,17 @@ static char *cover_definer_clause(const char *stmt_str, static FILE* open_sql_file_for_table(const char *db, const char* table, int flags) { FILE* res; - char filename[FN_REFLEN], tmp_path[FN_REFLEN]; + char filename[FN_REFLEN]; char out_dir_buf[FN_REFLEN]; char *out_dir= path; if (opt_dir) { out_dir= out_dir_buf; - my_snprintf(out_dir_buf, sizeof(out_dir_buf), "%s/%s", opt_dir, db); + format_fs_safe_output_dir(db, out_dir_buf, sizeof(out_dir_buf)); } - convert_dirname(tmp_path, out_dir, NullS); - res= my_fopen(fn_format(filename, table, tmp_path, ".sql", 4), + res= my_fopen(build_path_for_table(filename, out_dir, table, ".sql"), flags, MYF(MY_WME)); return res; } @@ -2155,11 +2195,9 @@ static void unescape(FILE *file,char *pos, size_t length) static my_bool test_if_special_chars(const char *str) { -#if MYSQL_VERSION_ID >= 32300 for ( ; *str ; str++) if (!my_isvar(charset_info,*str) && *str != '$') return 1; -#endif return 0; } /* test_if_special_chars */ @@ -4290,12 +4328,12 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, if (multi_file_output) { - char filename[FN_REFLEN], tmp_path[FN_REFLEN]; + char filename[FN_REFLEN]; char out_dir_buf[FN_REFLEN]; char *out_dir= path; if (!out_dir) { - my_snprintf(out_dir_buf, sizeof(out_dir_buf), "%s/%s", opt_dir, db); + format_fs_safe_output_dir(db, out_dir_buf, sizeof(out_dir_buf)); out_dir= out_dir_buf; } @@ -4303,9 +4341,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, Convert the path to native os format and resolve to the full filepath. */ - convert_dirname(tmp_path,out_dir,NullS); - my_load_path(tmp_path, tmp_path, NULL); - fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME)); + build_path_for_table(filename, out_dir, table, ".txt"); /* Must delete the file that 'INTO OUTFILE' will write to */ my_delete(filename, MYF(0)); @@ -4314,7 +4350,6 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, to_unix_path(filename); /* now build the query string */ - dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ "); dynstr_append_checked(&query_string, select_field_names.str); dynstr_append_checked(&query_string, " INTO OUTFILE '"); @@ -4459,6 +4494,11 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, fprintf(md_result_file,"/*M!101100 SET @old_system_versioning_insert_history=@@session.system_versioning_insert_history, @@session.system_versioning_insert_history=1 */;\n"); check_io(md_result_file); } + if (no_autocommit) + { + fprintf(md_result_file, "SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0;\n"); + check_io(md_result_file); + } if (opt_lock) { fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table); @@ -4479,11 +4519,6 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, if (opt_xml) print_xml_tag(md_result_file, "\t", "\n", "table_data", "name=", table, NullS); - if (no_autocommit) - { - fprintf(md_result_file, "set autocommit=0;\n"); - check_io(md_result_file); - } while ((row= mysql_fetch_row(res))) { @@ -4755,7 +4790,7 @@ static void dump_table(const char *table, const char *db, const uchar *hash_key, } if (no_autocommit) { - fprintf(md_result_file, "commit;\n"); + fprintf(md_result_file, "COMMIT;\nSET AUTOCOMMIT=@OLD_AUTOCOMMIT;\n"); check_io(md_result_file); } if (versioned && !opt_xml && opt_dump_history) @@ -5532,6 +5567,29 @@ static my_bool include_database(const char *hash_key) } +/* check database name if it's INFORMATION_SCHEMA or PERFORMANCE_SCHEMA. */ +static bool is_IS_or_PS(const char *schema_name) +{ + if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !cmp_database(schema_name, INFORMATION_SCHEMA_DB_NAME)) + return TRUE; + + if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !cmp_database(schema_name, PERFORMANCE_SCHEMA_DB_NAME)) + return TRUE; + + return FALSE; +} + + +/* check database name if it's SYS_SCHEMA. */ +static bool is_SyS(const char *schema_name) +{ + return (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && + !cmp_database(schema_name, SYS_SCHEMA_DB_NAME)); +} + + static int dump_all_databases() { MYSQL_ROW row; @@ -5542,18 +5600,9 @@ static int dump_all_databases() return 1; while ((row= mysql_fetch_row(tableres))) { - if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && - !cmp_database(row[0], INFORMATION_SCHEMA_DB_NAME)) - continue; - - if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !cmp_database(row[0], PERFORMANCE_SCHEMA_DB_NAME)) + if (is_IS_or_PS(row[0]) || is_SyS(row[0])) continue; - if (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && - !cmp_database(row[0], SYS_SCHEMA_DB_NAME)) - continue; - if (include_database(row[0])) if (dump_all_tables_in_db(row[0])) result=1; @@ -5570,16 +5619,7 @@ static int dump_all_databases() } while ((row= mysql_fetch_row(tableres))) { - if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && - !cmp_database(row[0], INFORMATION_SCHEMA_DB_NAME)) - continue; - - if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !cmp_database(row[0], PERFORMANCE_SCHEMA_DB_NAME)) - continue; - - if (mysql_get_server_version(mysql) >= FIRST_SYS_SCHEMA_VERSION && - !cmp_database(row[0], SYS_SCHEMA_DB_NAME)) + if (is_IS_or_PS(row[0]) || is_SyS(row[0])) continue; if (include_database(row[0])) @@ -6187,11 +6227,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) end= pos; /* Can't LOCK TABLES in I_S / P_S, so don't try. */ - if (lock_tables && - !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && - !cmp_database(db, INFORMATION_SCHEMA_DB_NAME)) && - !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && - !cmp_database(db, PERFORMANCE_SCHEMA_DB_NAME))) + if (lock_tables && !is_IS_or_PS(db)) { if (mysql_real_query(mysql, lock_tables_query.str, (ulong)lock_tables_query.length-1)) @@ -6328,7 +6364,7 @@ const char fmt_gtid_pos[]= "%sSET GLOBAL gtid_slave_pos='%s';\n"; static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos, int have_mariadb_gtid, int use_gtid, - char *set_gtid_pos) + char *set_gtid_pos, size_t set_gtid_pos_size) { MYSQL_ROW row; MYSQL_RES *UNINIT_VAR(master); @@ -6403,7 +6439,7 @@ static int do_show_master_status(MYSQL *mysql_con, int consistent_binlog_pos, "CHANGE-MASTER settings to the slave gtid state is printed " "later in the file.\n"); } - sprintf(set_gtid_pos, fmt_gtid_pos, + snprintf(set_gtid_pos, set_gtid_pos_size, fmt_gtid_pos, (!use_gtid ? "-- " : comment_prefix), gtid_pos); } @@ -6455,7 +6491,7 @@ static int do_stop_slave_sql(MYSQL *mysql_con) { char query[160]; if (multi_source) - sprintf(query, "STOP SLAVE '%.80s' SQL_THREAD", row[0]); + snprintf(query, sizeof(query), "STOP SLAVE '%.80s' SQL_THREAD", row[0]); else strmov(query, "STOP SLAVE SQL_THREAD"); @@ -6494,7 +6530,8 @@ static int add_slave_statements(void) } static int do_show_slave_status(MYSQL *mysql_con, int have_mariadb_gtid, - int use_gtid, char* set_gtid_pos) + int use_gtid, char* set_gtid_pos, + size_t set_gtid_pos_size) { MYSQL_RES *UNINIT_VAR(slave); MYSQL_ROW row; @@ -6539,7 +6576,8 @@ static int do_show_slave_status(MYSQL *mysql_con, int have_mariadb_gtid, "\n-- A corresponding to the below dump-slave " "CHANGE-MASTER settings to the slave gtid state is printed " "later in the file.\n"); - sprintf(set_gtid_pos, fmt_gtid_pos, gtid_comment_prefix, gtid_pos); + snprintf(set_gtid_pos, set_gtid_pos_size, + fmt_gtid_pos, gtid_comment_prefix, gtid_pos); } if (use_gtid) print_comment(md_result_file, 0, @@ -6615,7 +6653,8 @@ static int do_start_slave_sql(MYSQL *mysql_con) { char query[160]; if (multi_source) - sprintf(query, "START SLAVE '%.80s' SQL_THREAD", row[0]); + snprintf(query, sizeof(query), + "START SLAVE '%.80s' SQL_THREAD", row[0]); else strmov(query, "START SLAVE SQL_THREAD"); @@ -7287,6 +7326,85 @@ static void init_connection_pool(uint n_connections) connection_pool.init(conn, n_connections); } +/* + Fix permissions and ownership of given directory to be the same + as the root output directory. + + The function is used for newly created database directories, + together with --dir option + + This function is not thread-safe, nor does it need to be, because + it is called from the main thread only. + + chmod/chown errors are ignored after the first one, with a warning printed, + so it is really the best effort attempt. We might see an error later + if the server can't write into the directory, and this will be the + real error. + + On Windows, this function does nothing, because the permissions are + inherited from the parent directory anyway. + + @param dirpath Directory path +*/ +static void fix_permissions_and_owner(const char *dirpath) +{ +#ifndef _WIN32 + // Permissions and ownership of output directory (--dir) + static struct stat st_out_dir; + + static bool fix_perms= true; // Try fixing permission bits + static bool fix_ownership_uid= true; // Try fixing user+group ownership + static bool fix_ownership_gid= false; // Try fixing group ownership only + + static bool first_time= true; + if (first_time) + { + /* Find out permissions and ownership of output directory */ + first_time= false; + if (stat(opt_dir, &st_out_dir) != 0) + { + die(EX_CONSCHECK, "Error: cannot stat output directory %s, errno %d", + opt_dir, errno); + } + } + + /* Change permissions to be the same as for the output directory*/ + if (fix_perms && + chmod(dirpath, st_out_dir.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO))) + { + fprintf(stderr, + "Warning: cannot set permissions on directory %s, errno %d\n", + dirpath, errno); + fix_perms= false; + } + + /* + Change ownership to be the same as backup root dir. + If user can't be changed, try changing owner group only. + */ + if (fix_ownership_uid && + chown(dirpath, st_out_dir.st_uid, st_out_dir.st_gid)) + { + // No warning, error is expected, unless current user is root. + fix_ownership_uid= false; + fix_ownership_gid= true; + } + + if (fix_ownership_gid && chown(dirpath, -1, st_out_dir.st_gid)) + { + if (!(st_out_dir.st_mode & S_IWOTH)) + { + /* Only warn if directory is not world-writable (group ownership + matters more in this case), to avoid spamming stderr.*/ + fprintf(stderr, + "Warning: cannot set group ownership on directory %s, errno %d\n", + dirpath, errno); + } + fix_ownership_gid= false; + } +#endif +} + /* If --dir option is in use, ensure that output directory for given db exists. @@ -7295,7 +7413,7 @@ static void ensure_out_dir_exists(const char *db) { DBUG_ASSERT(opt_dir); char outdir[FN_REFLEN]; - my_snprintf(outdir, sizeof(outdir), "%s/%s", opt_dir, db); + format_fs_safe_output_dir(db, outdir, sizeof(outdir)); struct stat st; if (stat(outdir, &st) == 0) { @@ -7306,6 +7424,7 @@ static void ensure_out_dir_exists(const char *db) } if (my_mkdir(outdir, 0777, MYF(MY_WME))) die(EX_MYSQLERR, "Error creating directory %s", outdir); + fix_permissions_and_owner(outdir); } @@ -7338,6 +7457,175 @@ static void do_print_set_gtid_slave_pos(const char *set_gtid_pos, fprintf(md_result_file, "%s", set_gtid_pos); } +void dump_tables_for_database_wild(const char *db, + int n_patterns, char **patterns) +{ + int num; + int number_of_tables= 0; + MYSQL_ROW row; + char *buff, quoted_buf[NAME_LEN*2+3]; + MYSQL_RES *dbinfo; + char **tables_to_dump; + /* dbcopy - unquoted db; */ + char dbcopy[2 * NAME_LEN + 30]; + char hash_key[2*NAME_LEN+2]; /* "db.tablename" */ + char *afterdot; + size_t len; + size_t buff_size= 108 + (NAME_LEN + 30)*n_patterns; + + DBUG_ENTER("dump_tables_for_database_wild"); + DBUG_ASSERT(n_patterns > 0); + + + if (*db == '`') + { + len= strlen(db); + memcpy(dbcopy, db + 1, len - 2); + dbcopy[len - 2] = 0; + } + else + { + strncpy(dbcopy, db, NAME_LEN + 1); + } + + afterdot= strmov(hash_key, dbcopy); + *afterdot++= '.'; + + if (!(buff=(char*) my_malloc(PSI_NOT_INSTRUMENTED, buff_size, MYF(MY_WME)))) + die(EX_MYSQLERR, "Couldn't allocate memory"); + + len= my_snprintf(buff, buff_size, + "SELECT table_name FROM INFORMATION_SCHEMA.TABLES" + " WHERE table_schema=%s", quote_for_equal(dbcopy, quoted_buf)); + + mysql_real_escape_string(mysql, quoted_buf, + patterns[0], (ulong)strlen(patterns[0])); + + len+= my_snprintf(buff+len, buff_size, + " AND (table_name LIKE '%s'", quoted_buf); + + for (num=1; numrow_count + (int) 1) * sizeof(char *), MYF(MY_WME)))) + die(EX_MYSQLERR, "Couldn't allocate memory"); + while ((row= mysql_fetch_row(dbinfo))) + { + char *end= strmov(afterdot, row[0]); + if (include_table((uchar*) hash_key,end - hash_key)) + { + tables_to_dump[number_of_tables++]= row[0]; + } + } + tables_to_dump[number_of_tables]= NULL; + if (number_of_tables > 0) + { + if (!opt_alltspcs && !opt_notspcs) + dump_tablespaces_for_tables(dbcopy, tables_to_dump, number_of_tables); + dump_selected_tables(dbcopy, tables_to_dump, number_of_tables); + } + mysql_free_result(dbinfo); + my_free(tables_to_dump); + +free_buf_and_exit: + my_free(buff); + DBUG_VOID_RETURN; +} + + +/* pattern should be unquoted */ +void dump_databases_wild(int n_patterns, char **db_patterns) +{ + MYSQL_RES *dbinfo; + char *qwe_buff; + size_t qwe_buff_size= (NAME_LEN + 30)*n_patterns + 40; + size_t qwe_len; + MYSQL_ROW row; + int i; + char **databases_to_dump; + DBUG_ENTER("dump_databases_wild"); + DBUG_ASSERT(n_patterns > 0); + + if (!(qwe_buff= (char *) my_malloc(PSI_NOT_INSTRUMENTED, + qwe_buff_size, MYF(MY_WME)))) + die(EX_MYSQLERR, "Couldn't allocate memory"); + + + qwe_len= my_snprintf(qwe_buff, qwe_buff_size, + "SHOW DATABASES WHERE Database LIKE '%s'", db_patterns[0]); + for (i=1; irow_count + (int) 1) * sizeof(char *), MYF(MY_WME)))) + die(EX_MYSQLERR, "Couldn't allocate memory"); + + i= 0; + while ((row= mysql_fetch_row(dbinfo))) + { + if (is_IS_or_PS(row[0]) || is_SyS(row[0]) || !include_database(row[0])) + continue; + + databases_to_dump[i++]= row[0]; + } + + if (i == 0) /* No database found to dump. */ + { + fprintf(stderr, "%s: Error: no databases matching the ", my_progname_short); + + if (n_patterns > 1) + { + fprintf(stderr, "patterns ['%s'", db_patterns[0]); + for (i=1; i 1 && !opt_databases) + if (opt_wildcards &&(opt_databases || argc > 1)) { - /* Only one database and selected table(s) */ - if (!opt_alltspcs && !opt_notspcs) - dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1)); - dump_selected_tables(*argv, (argv + 1), (argc - 1)); + if (argc > 1 && !opt_databases) + /* One database, tables matching the wildcard. */ + dump_tables_for_database_wild(argv[0], argc-1, argv+1); + else if (argc > 0) + /* Databases matching the wildcards. */ + dump_databases_wild(argc, argv); + else + die(EX_CONSCHECK, + "Incorrect usage of patterns \n"); } - else if (argc > 0) + else { - /* One or more databases, all tables */ - if (!opt_alltspcs && !opt_notspcs) - dump_tablespaces_for_databases(argv); - dump_databases(argv); + if (argc > 1 && !opt_databases) + { + /* Only one database and selected table(s) */ + if (!opt_alltspcs && !opt_notspcs) + dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1)); + dump_selected_tables(*argv, (argv + 1), (argc - 1)); + } + else if (argc > 0) + { + /* One or more databases, all tables */ + if (!opt_alltspcs && !opt_notspcs) + dump_tablespaces_for_databases(argv); + dump_databases(argv); + } } } diff --git a/client/mysqlimport.cc b/client/mysqlimport.cc index 01259e95ef8a8..c6af8d5091cb6 100644 --- a/client/mysqlimport.cc +++ b/client/mysqlimport.cc @@ -50,7 +50,7 @@ static std::vector all_tp_connections; std::atomic aborting{false}; static void kill_tp_connections(MYSQL *mysql); -static void db_error_with_table(MYSQL *mysql, char *table); +static void db_error_with_table(MYSQL *mysql, const char *table); static void db_error(MYSQL *mysql); static char *field_escape(char *to,const char *from,uint length); static char *add_load_option(char *ptr,const char *object, @@ -82,12 +82,36 @@ static char **argv_to_free; static void safe_exit(int error, MYSQL *mysql); static void set_exitcode(int code); +/* + Try to convert from filesystem-safe name escaping to string + in default character set. + + @param name Name to unescape + @param buf Buffer to store result + @param sz Size of buffer + @return length of result string, or 0 on error or decodin + not needed +*/ +static uint decode_fs_safe_name(const char *name, char *buf, size_t sz) +{ + if (!strchr(name, '@')) + return 0; + uint errors, len; + len= my_convert(buf, (uint32)(sz - 1), default_charset_info, name, (uint32) strlen(name), + &my_charset_filename, &errors); + if (errors || !len) + return 0; + buf[len]= 0; + return len; +} + struct table_load_params { std::string data_file; /* name of the file to load with LOAD DATA INFILE */ std::string sql_file; /* name of the file that contains CREATE TABLE or CREATE VIEW */ std::string dbname; /* name of the database */ + std::string tablename; /* name of the table */ bool tz_utc= false; /* true if the script sets the timezone to UTC */ bool is_view= false; /* true if the script is for a VIEW */ std::vector triggers; /* CREATE TRIGGER statements */ @@ -98,12 +122,21 @@ struct table_load_params table_load_params(const char* dfile, const char* sqlfile, const char* db, ulonglong data_size) : data_file(dfile), sql_file(sqlfile), - dbname(db), triggers(), + triggers(), size(data_size), sql_text(parse_sql_script(sqlfile, &tz_utc, &triggers)), ddl_info(sql_text) { is_view= ddl_info.table_name.empty(); + /* Convert dbname from FS safe encoding if needed. */ + char decoded_name[FN_REFLEN]; + uint len= decode_fs_safe_name(db, decoded_name, sizeof(decoded_name)); + dbname= len ? std::string(decoded_name, len) : std::string(db); + + char raw_tblname[FN_REFLEN]; + fn_format(raw_tblname, dfile, "", "", MY_REPLACE_DIR | MY_REPLACE_EXT); + len= decode_fs_safe_name(raw_tblname, decoded_name, sizeof(decoded_name)); + tablename= len ? std::string(decoded_name, len) : std::string(raw_tblname); } int create_table_or_view(MYSQL *); int load_data(MYSQL *); @@ -646,7 +679,7 @@ int table_load_params::create_table_or_view(MYSQL* mysql) int table_load_params::load_data(MYSQL *mysql) { - char tablename[FN_REFLEN], hard_path[FN_REFLEN], + char hard_path[FN_REFLEN], escaped_name[FN_REFLEN * 2 + 1], sql_statement[FN_REFLEN*16+256], *end; DBUG_ENTER("table_load_params::load"); @@ -666,13 +699,10 @@ int table_load_params::load_data(MYSQL *mysql) } const char *filename= data_file.c_str(); - - fn_format(tablename, filename, "", "", 1 | 2); /* removes path & ext. */ - const char *db= current_db ? current_db : dbname.c_str(); std::string full_tablename= quote_identifier(db); full_tablename+= "."; - full_tablename+= quote_identifier(tablename); + full_tablename+= quote_identifier(tablename.c_str()); if (tz_utc && exec_sql(mysql, "SET TIME_ZONE='+00:00';")) DBUG_RETURN(1); @@ -688,7 +718,7 @@ int table_load_params::load_data(MYSQL *mysql) if (opt_delete) { if (verbose) - fprintf(stdout, "Deleting the old data from table %s\n", tablename); + fprintf(stdout, "Deleting the old data from table %s\n", tablename.c_str()); snprintf(sql_statement, FN_REFLEN * 16 + 256, "DELETE FROM %s", full_tablename.c_str()); if (exec_sql(mysql, sql_statement)) @@ -713,11 +743,12 @@ int table_load_params::load_data(MYSQL *mysql) if (verbose) { fprintf(stdout, "Loading data from %s file: %s into %s\n", - (opt_local_file) ? "LOCAL" : "SERVER", hard_path, tablename); + (opt_local_file) ? "LOCAL" : "SERVER", hard_path, tablename.c_str()); } mysql_real_escape_string(mysql, escaped_name, hard_path, (unsigned long) strlen(hard_path)); - sprintf(sql_statement, "LOAD DATA %s %s INFILE '%s'", + snprintf(sql_statement, sizeof(sql_statement), + "LOAD DATA %s %s INFILE '%s'", opt_low_priority ? "LOW_PRIORITY" : "", opt_local_file ? "LOCAL" : "", escaped_name); @@ -747,14 +778,14 @@ int table_load_params::load_data(MYSQL *mysql) if (mysql_query(mysql, sql_statement)) { - db_error_with_table(mysql, tablename); + db_error_with_table(mysql, tablename.c_str()); DBUG_RETURN(1); } if (!silent) { const char *info= mysql_info(mysql); if (info) /* If NULL-pointer, print nothing */ - fprintf(stdout, "%s.%s: %s\n", db, tablename, info); + fprintf(stdout, "%s.%s: %s\n", db, tablename.c_str(), info); } @@ -869,10 +900,7 @@ static MYSQL *db_connect(char *host, char *database, if (opt_default_auth && *opt_default_auth) mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); - if (!strcmp(default_charset,MYSQL_AUTODETECT_CHARSET_NAME)) - default_charset= (char *)my_default_csname(); - my_set_console_cp(default_charset); - mysql_options(mysql, MYSQL_SET_CHARSET_NAME, my_default_csname()); + mysql_options(mysql, MYSQL_SET_CHARSET_NAME, default_charset); mysql_options(mysql, MYSQL_OPT_CONNECT_ATTR_RESET, 0); mysql_options4(mysql, MYSQL_OPT_CONNECT_ATTR_ADD, "program_name", "mysqlimport"); @@ -961,7 +989,7 @@ static void safe_exit(int error, MYSQL *mysql) -static void db_error_with_table(MYSQL *mysql, char *table) +static void db_error_with_table(MYSQL *mysql, const char *table) { if (aborting) return; @@ -1263,6 +1291,12 @@ int main(int argc, char **argv) free_defaults(argv_to_free); return(1); } + + if (!strcmp(default_charset, MYSQL_AUTODETECT_CHARSET_NAME)) + default_charset= (char *) my_default_csname(); + my_set_console_cp(default_charset); + default_charset_info= get_charset_by_csname(default_charset, MY_CS_PRIMARY, 0); + if (opt_use_threads > MAX_THREADS) { fatal_error("Too many connections, max value for --parallel is %d\n", diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 637f48c559eb4..b54bdcf4c78dc 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -55,6 +55,7 @@ #endif #include #include +#include #include // ORACLE_WELCOME_COPYRIGHT_NOTICE @@ -78,7 +79,7 @@ static my_bool non_blocking_api_enabled= 0; #define MAX_DELIMITER_LENGTH 16 #define DEFAULT_MAX_CONN 64 -#define DIE_BUFF_SIZE 15*1024 +#define DIE_BUFF_SIZE 64*1024 #define RESULT_STRING_INIT_MEM 2048 #define RESULT_STRING_INCREMENT_MEM 2048 @@ -308,6 +309,7 @@ struct Parser struct MasterPos { char file[FN_REFLEN]; + char gtid[256]; ulong pos; } master_pos; @@ -697,6 +699,320 @@ void display_optimizer_trace(struct st_connection *con, static void append_session_track_info(DYNAMIC_STRING *ds, MYSQL *mysql); + +/* + ======================================================================== + EXPRESSION PARSER AND EVALUATOR FOR MYSQLTEST + ======================================================================== + + DESCRIPTION + This module implements a complete recursive descent parser for mathematical + and logical expressions used in mysqltest scripts. The parser supports: + + OPERATOR PRECEDENCE (from highest to lowest): + - Primary expressions (parentheses, literals, functions) + - Unary operators (!, -, ~) + - Bitwise XOR (^) + - Multiplication/Division (*, /, %) + - Arithmetic (+, -) + - Bitwise Shift (<<, >>) + - Bitwise AND (&) + - Bitwise OR (|) + - Comparison (<, <=, >, >=) + - Equality (==, !=) + - Logical AND (&&) + - Logical OR (||) + + SUPPORTED DATA TYPES: + - Integers (decimal, hexadecimal (0x), binary (0b)) + - Booleans + - Strings + - NULL values + + BUILT-IN FUNCTIONS: + String functions: substr/substring, locate, length, hex, oct, bin, + ltrim, rtrim, trim, upper/ucase, lower/lcase, + reverse, replace, concat, concat_ws, repeat, + insert, instr, lpad, rpad, substring_index + Regex functions: regexp_instr, regexp_replace, regexp_substr + Numeric functions: abs, conv + Comparison functions: greatest, least + Conditional: ifnull, nullif, coalesce + + SYNTAX: + Expressions are enclosed in $() and can contain: + - Variables: $var_name + - Literals: numbers, strings, booleans, null + - Operators: all standard mathematical and logical operators + - Functions: built-in function calls with arguments + - Parentheses for grouping + + EXAMPLES: + $(1 + 2 * 3) # Arithmetic + $($var1 > $var2) # Comparison + $(substr("hello", 1, 3)) # Function call + $($flag && ($count > 0)) # Logical operations + $(1 << 2 | 3) # Bitwise operations + + let $x = $(10 + 2); + echo $(1 + 2); + if ($($x > 10)) + { + echo "x is greater than 10"; + } + while ($($x < 20)) + { + echo $($x); + let $x = $($x + 1); + } + + ENTRY POINT: + Main parsing starts with expr() function which is called from do_eval(). + + ERROR HANDLING: + Parser dies with descriptive error messages on syntax errors or + type mismatches. All errors are fatal to ensure test reliability. +*/ + +typedef String My_string; + +enum Expression_value_type +{ + EXPR_INT, + EXPR_STRING, + EXPR_NULL +}; + + +/* + Expression value container for mysqltest expression parser + This structure holds the result of parsed expressions and provides + type conversion methods. It supports multiple data types with + the ability to convert between them. +*/ + +struct Expression_value +{ + Expression_value_type type; + unsigned long long int_val; + bool is_numeric; + bool is_unsigned; + My_string str_val; + + + Expression_value() + { + type= EXPR_NULL; + is_numeric= false; + is_unsigned= false; + } + + + void set_int(long long value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= false; + int_val= value; + } + + + void set_uint(unsigned long long value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= true; + int_val= value; + } + + + void set_string(const char *value, size_t len) + { + type= EXPR_STRING; + is_numeric= false; + str_val.copy(value, len, charset_info); + } + + + void set_bool(bool value) + { + type= EXPR_INT; + is_numeric= true; + is_unsigned= false; + int_val= value ? 1 : 0; + } + + + long long to_int() const + { + if (is_numeric) + return (long long)int_val; + errno= 0; + long long val= strtoll(str_val.ptr(), NULL, 10); + if (errno == ERANGE) + die("Range error: %.*s value out of range for Integer type", + (int)str_val.length(), str_val.ptr()); + return val; + } + + + unsigned long long to_uint() const + { + if (is_numeric) + return int_val; + errno= 0; + unsigned long long val= strtoull(str_val.ptr(), NULL, 10); + if (errno == ERANGE) + die("Range error: %.*s value out of range for Integer type", + (int)str_val.length(), str_val.ptr()); + return val; + } + + + bool to_bool() const + { + return (bool)to_int(); + } + + + My_string to_string() const + { + My_string buffer; + + if (type == EXPR_NULL) + { + buffer.set("", 0, charset_info); + return buffer; + } + + if (is_numeric) + { + buffer.set_int(int_val, is_unsigned, charset_info); + return buffer; + } + + if (type == EXPR_STRING) + { + buffer.copy(str_val); + return buffer; + } + + buffer.set("", 0, charset_info); + return buffer; + } + + + Expression_value& operator=(const Expression_value& other) + { + if (this != &other) + { + type= other.type; + int_val= other.int_val; + is_numeric= other.is_numeric; + is_unsigned= other.is_unsigned; + if (other.type == EXPR_STRING) + { + str_val.copy(other.str_val); + } + } + return *this; + } + + + void reset() + { + // My_string memory is kept allocated for reuse + type= EXPR_NULL; + is_numeric= false; + is_unsigned= false; + } + + +/** + Parses a token string and initializes the Expression_value with the + appropriate type and value. + + Type selection logic: + - Hex/binary numbers, or values > LLONG_MAX → unsigned integer + - Decimal numbers ≤ LLONG_MAX → signed integer + - Boolean literals → boolean type + - "null" → null type + - Everything else → string type +*/ + + void init(const char* token_start, size_t token_len) + { + char *endptr; + unsigned long long parsed_int; + int base= 10; + + // Check for boolean literals (case insensitive) + if (token_len == 4 && strncasecmp(token_start, "true", 4) == 0) + { + set_bool(true); + return; + } + + if (token_len == 5 && strncasecmp(token_start, "false", 5) == 0) + { + set_bool(false); + return; + } + + if(token_len == 4 && strncasecmp(token_start, "null", 4) == 0) + { + reset(); + return; + } + + // Check for special prefixes (0x, 0b) + if (token_len >= 3 && token_start[0] == '0') + { + if (token_start[1] == 'x') + { + base= 16; + } + else if (token_start[1] == 'b') + { + base= 2; + token_start+= 2; // Skip "0b" prefix for strtol + token_len-= 2; + } + } + + errno= 0; + parsed_int= strtoull(token_start, &endptr, base); + if (errno == ERANGE) + die("Range error: %.*s value out of range for Integer type", + (int)token_len, token_start); + + // If the entire token was parsed as an integer, set the type to integer + if (endptr == token_start + token_len) + { + if (base == 16 || base == 2 || parsed_int > LLONG_MAX) + set_uint(parsed_int); + else + set_int((long long)parsed_int); + return; + } + + set_string(token_start, token_len); + } +}; + + +/* Core expression parsing functions */ +static void expr(Expression_value *result, const char **s); +static void logical_or(Expression_value *result, const char **s); +static void logical_and(Expression_value *result, const char **s); +static void equality(Expression_value *result, const char **s); +static void comparison(Expression_value *result, const char **s); +static void term(Expression_value *result, const char **s); +static void factor(Expression_value *result, const char **s); +static void unary(Expression_value *result, const char **s); +static void primary(Expression_value *result, const char **s); + + class LogFile { FILE* m_file; char m_file_name[FN_REFLEN]; @@ -1172,6 +1488,60 @@ void do_eval(DYNAMIC_STRING *query_eval, const char *query, escaped= 0; dynstr_append_mem(query_eval, p, 1); } + else if (p < query_end && *(p + 1) == '(') + { + const char* expr_start= p + 2; + int paren_level= 1; + const char* expr_end= expr_start; + char in_quote= 0; + bool escaped= false; + + // Find the matching closing parenthesis + while (*expr_end && paren_level > 0) + { + if (!in_quote) + { + // Not inside quotes - handle parentheses normally + if (*expr_end == '(') paren_level++; + else if (*expr_end == ')') paren_level--; + else if (*expr_end == '\'' || *expr_end == '"') + in_quote= *expr_end; // Start of quoted string + } + else + { + // Inside quotes - only look for closing quote + if (!escaped && *expr_end == in_quote) + in_quote= 0; // End of quoted string + } + escaped= (!escaped && *expr_end == '\\'); + expr_end++; + } + + if (paren_level != 0) + die("Unmatched parenthesis in expression starting at '%.*s'", 10, p); + expr_end--; // Go back to the ')' + + // Recursively evaluate the content of the expression + DYNAMIC_STRING sub_expr_eval; + init_dynamic_string(&sub_expr_eval, "", 256, 1024); + do_eval(&sub_expr_eval, expr_start, expr_end, FALSE); + + const char* eval_ptr= sub_expr_eval.str; + Expression_value result_val; + expr(&result_val, &eval_ptr); + + while(*eval_ptr && my_isspace(charset_info, *eval_ptr)) + eval_ptr++; + + if (*eval_ptr != '\0') + die("Syntax error in sub-expression '%.*s'", (int)sub_expr_eval.length, sub_expr_eval.str); + + My_string result_buf= result_val.to_string(); + dynstr_append_mem(query_eval, result_buf.c_ptr(), result_buf.length()); + + dynstr_free(&sub_expr_eval); + p= expr_end; + } else { if (!(v= var_get(p, &p, 0, 0))) @@ -1631,6 +2001,8 @@ static void make_error_message(char *buf, size_t len, const char *fmt, va_list a s+= my_snprintf(s, end -s, "\n"); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + static void die(const char *fmt, ...) { char buff[DIE_BUFF_SIZE]; @@ -1642,6 +2014,8 @@ static void die(const char *fmt, ...) really_die(buff); } +PRAGMA_REENABLE_CHECK_STACK_FRAME + static void really_die(const char *msg) { static int dying= 0; @@ -1670,6 +2044,8 @@ static void really_die(const char *msg) cleanup_and_exit(1, 1); } +PRAGMA_DISABLE_CHECK_STACK_FRAME + void report_or_die(const char *fmt, ...) { va_list args; @@ -1724,6 +2100,7 @@ void abort_not_supported_test(const char *fmt, ...) cleanup_and_exit(62, 0); } +PRAGMA_REENABLE_CHECK_STACK_FRAME void abort_not_in_this_version() { @@ -4663,6 +5040,24 @@ void do_change_user(struct st_command *command) dynstr_set(&ds_db, mysql->db); } + /* Connection logging if enabled */ + if (!disable_query_log) + { + DYNAMIC_STRING *ds= &ds_res; + + dynstr_append_mem(ds, STRING_WITH_LEN("change_user ")); + replace_dynstr_append(ds, ds_user.str); + dynstr_append_mem(ds, STRING_WITH_LEN(",")); + + if (ds_passwd.length) + replace_dynstr_append(ds, ds_passwd.str); + dynstr_append_mem(ds, STRING_WITH_LEN(",")); + + if (ds_db.length) + replace_dynstr_append(ds, ds_db.str); + dynstr_append_mem(ds, STRING_WITH_LEN(";\n")); + } + DBUG_PRINT("info",("connection: '%s' user: '%s' password: '%s' database: '%s'", cur_con->name, ds_user.str, ds_passwd.str, ds_db.str)); @@ -4865,161 +5260,2552 @@ void do_wait_for_slave_to_stop(struct st_command *c __attribute__((unused))) break; my_sleep(SLAVE_POLL_INTERVAL); } - return; + return; +} + +static const char *get_col_value(MYSQL_RES *res, MYSQL_ROW row, const char *name) +{ + uint num_fields= mysql_num_fields(res); + MYSQL_FIELD *fields= mysql_fetch_fields(res); + + for (uint i= 0; i < num_fields; i++) + { + if (strcmp(fields[i].name, name) == 0) + return row[i]; + } + return "NULL"; +} + + +void do_sync_with_master2(struct st_command *command, long offset, + const char *connection_name) +{ + MYSQL_RES *res; + MYSQL_ROW row; + MYSQL *mysql= cur_con->mysql; + char query_buf[FN_REFLEN+128], query_buf2[256]; + int timeout= opt_wait_for_pos_timeout; + + if (!master_pos.file[0]) + die("Calling 'sync_with_master' without calling 'save_master_pos'"); + + sprintf(query_buf, "select master_pos_wait('%s', %ld, %d, '%s')", + master_pos.file, master_pos.pos + offset, timeout, + connection_name); + + if (mysql_query(mysql, query_buf)) + die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql), + mysql_error(mysql)); + + if (!(res= mysql_store_result(mysql))) + die("mysql_store_result() returned NULL for '%s'", query_buf); + if (!(row= mysql_fetch_row(res))) + { + mysql_free_result(res); + die("empty result in %s", query_buf); + } + + int result= -99; + const char* result_str= row[0]; + if (result_str) + result= atoi(result_str); + + mysql_free_result(res); + + if (!result_str || result < 0) + { + /* master_pos_wait returned NULL or < 0 */ + fprintf(stderr, "analyze: sync_with_master\n"); + + snprintf(query_buf2, sizeof(query_buf2)-1, + "select Relay_Master_Log_File, Read_Master_Log_Pos, Gtid_IO_Pos, " + "Gtid_Slave_Pos from information_schema.slave_status where " + "Connection_name='%.64s'", connection_name); + + /* purify begin tested */ + if (!mysql_query(mysql, query_buf2)) + { + if ((res= mysql_store_result(mysql))) + { + if ((row= mysql_fetch_row(res))) + { + fprintf(stderr, "Slave position: file: %s position: %s " + "Gtid_Slave_Pos: %s Gtid_IO_Pos: %s\n", + get_col_value(res, row, "Relay_Master_Log_File"), + get_col_value(res, row, "Read_Master_Log_Pos"), + get_col_value(res, row, "Gtid_Slave_Pos"), + get_col_value(res, row, "Gtid_IO_Pos")); + fprintf(stderr, "Master position: file: %s position: %lld " + "Gtid_Master_Pos: %s\n", + master_pos.file, (longlong) (master_pos.pos + offset), + master_pos.gtid); + } + mysql_free_result(res); + } + } + /* purify end tested */ + + if (!result_str) + { + /* + master_pos_wait returned NULL. This indicates that + slave SQL thread is not started, the slave's master + information is not initialized, the arguments are + incorrect, or an error has occurred + */ + die("%.*sB failed: '%s' returned NULL " \ + "indicating slave SQL thread failure", + command->first_word_len, command->query, query_buf); + } + + if (result == -1) + die("%.*sB failed: '%s' returned -1 " \ + "indicating timeout after %d seconds", + command->first_word_len, command->query, query_buf, timeout); + else + die("%.*sB failed: '%s' returned unknown result :%d", + command->first_word_len, command->query, query_buf, result); + } + + return; +} + +void do_sync_with_master(struct st_command *command) +{ + long offset= 0; + char *p= command->first_argument; + const char *offset_start= p; + char *start, *buff= 0; + start= const_cast(""); + + if (*offset_start) + { + for (; my_isdigit(charset_info, *p); p++) + offset = offset * 10 + *p - '0'; + + if (*p && !my_isspace(charset_info, *p) && *p != ',') + die("Invalid integer argument \"%s\"", offset_start); + + while (*p && my_isspace(charset_info, *p)) + p++; + if (*p == ',') + { + p++; + while (*p && my_isspace(charset_info, *p)) + p++; + start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(p)+1, + MYF(MY_WME|MY_FAE)); + get_string(&buff, &p, command); + } + command->last_argument= p; + } + do_sync_with_master2(command, offset, start); + if (buff) + my_free(start); + return; +} + + +int do_save_master_pos() +{ + MYSQL_RES *res; + MYSQL_ROW row; + MYSQL *mysql = cur_con->mysql; + const char *query; + DBUG_ENTER("do_save_master_pos"); + + if (mysql_query(mysql, query= "show master status")) + die("failed in 'show master status': %d %s", + mysql_errno(mysql), mysql_error(mysql)); + + if (!(res = mysql_store_result(mysql))) + die("mysql_store_result() returned NULL for '%s'", query); + if (!(row = mysql_fetch_row(res))) + die("empty result in show master status"); + strmake(master_pos.file, row[0], sizeof(master_pos.file)-1); + master_pos.pos= strtoul(row[1], (char**) 0, 10); + strmake(master_pos.gtid, row[4], sizeof(master_pos.gtid)-1); + mysql_free_result(res); + DBUG_RETURN(0); +} + + +/* Built-in functions available in expressions */ +enum func_type +{ + // Numeric functions + FUNC_ABS, + FUNC_BIN, + FUNC_CONV, + FUNC_HEX, + FUNC_OCT, + // String functions + FUNC_CONCAT, + FUNC_CONCAT_WS, + FUNC_GREATEST, + FUNC_INSERT, + FUNC_INSTR, + FUNC_LPAD, + FUNC_LEAST, + FUNC_LENGTH, + FUNC_LOCATE, + FUNC_LOWER, + FUNC_LTRIM, + FUNC_REPEAT, + FUNC_REPLACE, + FUNC_REVERSE, + FUNC_RPAD, + FUNC_RTRIM, + FUNC_SUBSTR, + FUNC_SUBSTR_IDX, + FUNC_TRIM, + FUNC_UPPER, + // Regexp functions + FUNC_REGEXP_INSTR, + FUNC_REGEXP_REPLACE, + FUNC_REGEXP_SUBSTR, + // Null functions + FUNC_COALESCE, + FUNC_IFNULL, + FUNC_NULLIF, + + FUNC_UNKNOWN +}; + + +enum func_type get_expr_function_type(const char *name, size_t len); +void handle_expr_function_call(enum func_type func_type, + Expression_value *result, const char **s); + + +static int match(const char **s, const char *op) +{ + while (my_isspace(charset_info, **s)) (*s)++; + size_t len= strlen(op); + if (strncmp(*s, op, len) == 0) + { + // check for ambiguous operators (e.g., distinguish | from ||) + if (len == 1 && strchr("&|", **s)) + { + char next_char= *(*s + 1); + if (next_char == op[0]) + return 0; // don't match single & or | when && or || follows + } + *s += len; + return 1; + } + return 0; +} + + +/** + @brief Check if character is an operator + @param[in] c Character to check + + @details + Used to separate tokens during parsing of unquoted string literals. + Operator characters: ! * % / + - < > = & | ^ ~ ( ) , + + @return + TRUE if character is an operator + FALSE otherwise +*/ + +static bool is_operator_char(char c) +{ + return strchr("!*%/+-<>=&|^~(),", c) != NULL; +} + + +/** + @brief Compare two Expression_value operands numerically + @param[in] left Left operand + @param[in] right Right operand + + @details + Compares two numeric Expression_value objects handling signed vs unsigned + comparison correctly. Handles the edge cases where comparing signed negative + values with unsigned values. + + @return + -1 left < right + 0 left == right + 1 left > right + -2 left or right is null +*/ + +static int cmp_numeric(const Expression_value &left, const Expression_value &right) +{ + // Handle null values first + if (left.type == EXPR_NULL || right.type == EXPR_NULL) + return -2; + + if (!left.is_numeric || !right.is_numeric) + die("Evaluation error: cmp_numeric called with non-numeric operands"); + + // Both unsigned + if (left.is_unsigned && right.is_unsigned) + return (left.to_uint() > right.to_uint()) - (left.to_uint() < right.to_uint()); + + // Both signed + if (!left.is_unsigned && !right.is_unsigned) + return (left.to_int() > right.to_int()) - (left.to_int() < right.to_int()); + + // Mixed signed/unsigned + if (left.is_unsigned) + { + // left is unsigned, right is signed + long long right_val= right.to_int(); + if (right_val < 0) + return 1; // unsigned > negative + else + { + unsigned long long left_val= left.to_uint(); + unsigned long long right_unsigned= (unsigned long long)right_val; + return (left_val > right_unsigned) - (left_val < right_unsigned); + } + } + else + { + // left is signed, right is unsigned + long long left_val= left.to_int(); + if (left_val < 0) + return -1; // negative < unsigned + else + { + unsigned long long left_unsigned= (unsigned long long)left_val; + unsigned long long right_val= right.to_uint(); + return (left_unsigned > right_val) - (left_unsigned < right_val); + } + } +} + + +/** + @brief Parse primary expressions (literals, functions) + @param[out] result Expression_value to store result + @param[in] s Pointer to string pointer containing the expression to parse + + @details + Handles the lowest level of expression parsing: + - String literals: 'text' or "text" + - Function calls: func_name(args...) + - Numeric literals: integers in decimal/hex/binary format + - Boolean literals: true/false (case-insensitive) + - Null literal: null (case-insensitive) + - Unquoted string tokens (treated as strings) as long as they are not operators, + literals, or function calls. + + For function calls, validates function name against function_table[] + and delegates to handle_expr_function_call(). + + @note Dies on syntax errors or unknown functions +*/ + +static void primary(Expression_value *result, const char **s) +{ + while (my_isspace(charset_info, **s)) (*s)++; + + if (match(s, "(")) + { + expr(result, s); + if (!match(s, ")")) + die("Syntax error: Expected ')' in expression"); + return; + } + + const char *start= *s; + const char *end= start; + char quote_char= 0; + + // check if this is a quoted string literal + if (*start == '\'' || *start == '"') + { + quote_char= *start; + start++; + end= start; + while (*end) + { + if (*end == '\\' && *(end + 1)) + end++; + else if (*end == quote_char) + break; + end++; + } + + if (*end != quote_char) + die("Syntax error: Unmatched quote in expression"); + + result->set_string(start, end - start); + *s= end + 1; + return; + } + + /* + function name is a sequence of alphanumeric characters or underscores + followed by a '(' + */ + while (*end && (my_isalnum(charset_info, *end) || *end == '_')) + end++; + + if (*end == '(') + { + enum func_type func_type= get_expr_function_type(start, + end - start); + if (func_type == FUNC_UNKNOWN) + die("Syntax error: Unknown function"); + + *s= end + 1; // skip '(' + handle_expr_function_call(func_type, result, s); + } + else + { + // treat unquoted string literals as strings + end= start; + while (*end && !is_operator_char(*end)) + end++; + + while (start < end && my_isspace(charset_info, *(end - 1))) + end--; + + if (end == start) + die("Syntax error: invalid expression"); + + result->init(start, end - start); + *s= end; + } +} + + +static void unary(Expression_value *result, const char **s) +{ + if (match(s, "!")) + { + unary(result, s); + if (!result->is_numeric) + die("Type error: logical NOT requires an integer operand"); + result->set_bool(!result->to_int()); + return; + } + if (match(s, "-")) + { + unary(result, s); + if (!result->is_numeric) + die("Type error: unary minus requires an integer operand"); + result->set_int(-result->to_int()); + return; + } + if (match(s, "~")) + { + unary(result, s); + if (!result->is_numeric) + die("Type error: bitwise NOT requires an integer operand"); + result->set_uint(~result->to_uint()); + return; + } + primary(result, s); +} + + +static void bitwise_xor(Expression_value *result, const char **s) +{ + Expression_value rhs; + + unary(result, s); + while (true) + { + if (match(s, "^")) + { + rhs.reset(); + unary(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '^' requires integer operands"); + result->set_uint(result->to_uint() ^ rhs.to_uint()); + } + else + break; + } +} + + +static void factor(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_xor(result, s); + while (true) + { + if (match(s, "*")) + { + rhs.reset(); + bitwise_xor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '*' requires integer operands"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() * rhs.to_uint()); + else + result->set_int(result->to_int() * rhs.to_int()); + } + else if (match(s, "/")) + { + rhs.reset(); + bitwise_xor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '/' requires integer operands"); + if (rhs.to_int() == 0) + die("Evaluation error: Division by zero"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() / rhs.to_uint()); + else + { + long long nominator= result->to_int(); + long long denominator= rhs.to_int(); + // Prevent fatal integer overflow from LLONG_MIN / -1, which causes a crash + if (nominator == LLONG_MIN && denominator == -1) + result->set_int(nominator); + else + result->set_int(nominator / denominator); + } + } + else if (match(s, "%")) + { + rhs.reset(); + bitwise_xor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '%%' requires integer operands"); + if (rhs.to_int() == 0) + die("Evaluation error: Modulo by zero"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() % rhs.to_uint()); + else + { + long long nominator= result->to_int(); + long long denominator= rhs.to_int(); + // Prevent fatal integer overflow from LLONG_MIN % -1, which causes a crash + if (nominator == LLONG_MIN && denominator == -1) + result->set_int(0); + else + result->set_int(nominator % denominator); + } + } + else + break; + } +} + + +static void term(Expression_value *result, const char **s) +{ + Expression_value rhs; + + factor(result, s); + while (true) + { + if (match(s, "+")) + { + rhs.reset(); + factor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '+' requires integer operands"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() + rhs.to_uint()); + else + result->set_int(result->to_int() + rhs.to_int()); + } + else if (match(s, "-")) + { + rhs.reset(); + factor(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '-' requires integer operands"); + if (result->is_unsigned || rhs.is_unsigned) + result->set_uint(result->to_uint() - rhs.to_uint()); + else + result->set_int(result->to_int() - rhs.to_int()); + } + else + break; + } +} + + +static void bitwise_shift(Expression_value *result, const char **s) +{ + Expression_value rhs; + + term(result, s); + while (true) + { + if (match(s, "<<")) + { + rhs.reset(); + term(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '<<' requires integer operands"); + if (rhs.to_int() < 0 || rhs.to_int() >= 64) + die("Evaluation error: Invalid shift amount"); + result->set_uint(result->to_uint() << rhs.to_int()); + } + else if (match(s, ">>")) + { + rhs.reset(); + term(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '>>' requires integer operands"); + if (rhs.to_int() < 0 || rhs.to_int() >= 64) + die("Evaluation error: Invalid shift amount"); + result->set_uint(result->to_uint() >> rhs.to_int()); + } + else + break; + } +} + + +static void bitwise_and(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_shift(result, s); + while (true) + { + if (match(s, "&") && !match(s, "&&")) + { + rhs.reset(); + bitwise_shift(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '&' requires integer operands"); + result->set_uint(result->to_uint() & rhs.to_uint()); + } + else + break; + } +} + + +static void bitwise_or(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_and(result, s); + while (true) + { + if (match(s, "|") && !match(s, "||")) + { + rhs.reset(); + bitwise_and(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '|' requires integer operands"); + result->set_uint(result->to_uint() | rhs.to_uint()); + } + else + break; + } +} + + +static void comparison(Expression_value *result, const char **s) +{ + Expression_value rhs; + + bitwise_or(result, s); + while (true) + { + if (match(s, "<=")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '<=' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) <= 0); + } + else if (match(s, ">=")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '>=' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) >= 0); + } + else if (match(s, "<")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '<' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) < 0); + } + else if (match(s, ">")) + { + rhs.reset(); + bitwise_or(&rhs, s); + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + result->reset(); + else if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '>' requires integer operands"); + else + result->set_bool(cmp_numeric(*result, rhs) > 0); + } + else + break; + } +} + + +static void equality(Expression_value *result, const char **s) +{ + Expression_value rhs; + + comparison(result, s); + while (true) + { + if (match(s, "==")) + { + rhs.reset(); + comparison(&rhs, s); + + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + { + result->reset(); + } + else if (result->is_numeric && rhs.is_numeric) + { + result->set_bool(cmp_numeric(*result, rhs) == 0); + } + else if (result->type == EXPR_STRING && rhs.type == EXPR_STRING) + { + result->set_bool(!strcmp(result->str_val.c_ptr(), rhs.str_val.c_ptr())); + } + else + { + result->set_bool(false); // different types are not equal + } + } + else if (match(s, "!=")) + { + rhs.reset(); + comparison(&rhs, s); + + if (result->type == EXPR_NULL || rhs.type == EXPR_NULL) + { + result->reset(); + } + else if (result->is_numeric && rhs.is_numeric) + { + result->set_bool(cmp_numeric(*result, rhs) != 0); + } + else if (result->type == EXPR_STRING && rhs.type == EXPR_STRING) + { + result->set_bool(strcmp(result->str_val.c_ptr(), rhs.str_val.c_ptr()) != 0); + } + else + { + result->set_bool(true); // different types are not equal + } + } + else + break; + } +} + + +static void logical_and(Expression_value *result, const char **s) +{ + Expression_value rhs; + + equality(result, s); + while (match(s, "&&")) + { + rhs.reset(); + equality(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '&&' requires integer operands"); + result->set_bool(result->to_int() && rhs.to_int()); + } +} + + +static void logical_or(Expression_value *result, const char **s) +{ + Expression_value rhs; + + logical_and(result, s); + while (match(s, "||")) + { + rhs.reset(); + logical_and(&rhs, s); + if (!result->is_numeric || !rhs.is_numeric) + die("Type error: operator '||' requires integer operands"); + result->set_bool(result->to_int() || rhs.to_int()); + } +} + + +/** + @brief Parse and evaluate a mathematical/logical expression + @param[out] result Pointer to Expression_value structure to store the result + @param[in] s Pointer to string pointer containing the expression to parse + + @details + This is the main entry point for the recursive descent expression parser. + It parses expressions with the following grammar hierarchy (by precedence): + + expr -> logical_or + logical_or -> logical_and (||) + logical_and -> equality (&&) + equality -> comparison (==, !=) + comparison -> bitwise_or (<, >, <=, >=) + bitwise_or -> bitwise_and (|) + bitwise_and -> bitwise_shift (&) + bitwise_shift -> term (<<, >>) + term -> factor (+, -) + factor -> bitwise_xor (*, /, %) + bitwise_xor -> unary (^) + unary -> primary (!, -, ~) + primary -> literals, functions, parentheses + + Supported data types: + - INTEGERS: signed/unsigned integers (decimal, hex 0x, binary 0b) + - BOOLEAN: boolean values (true, false) + - STRINGS: quoted or unquoted string literals + - NULL: null values + + The parser advances the string pointer *s as it consumes tokens. + + @note + The parser does not handle overflow/underflow of large numbers after + the initial parsing. It is the responsibility of the caller to ensure that + the result of the operations is within the range of the data type (2^64-1). + + @note Dies with error message if syntax error or type mismatch detected +*/ + +static void expr(Expression_value *result, const char **s) +{ + logical_or(result, s); +} + + +/* Expression function handling */ +#define MAX_FUNC_ARGS 100 + +static struct { + const char *name; + enum func_type type; +} function_table[]= { + // Numeric functions + {"abs", FUNC_ABS}, + {"bin", FUNC_BIN}, + {"conv", FUNC_CONV}, + {"hex", FUNC_HEX}, + {"oct", FUNC_OCT}, + // String functions + {"concat", FUNC_CONCAT}, + {"concat_ws", FUNC_CONCAT_WS}, + {"greatest", FUNC_GREATEST}, + {"insert", FUNC_INSERT}, + {"instr", FUNC_INSTR}, + {"lcase", FUNC_LOWER}, + {"least", FUNC_LEAST}, + {"length", FUNC_LENGTH}, + {"locate", FUNC_LOCATE}, + {"lower", FUNC_LOWER}, + {"lpad", FUNC_LPAD}, + {"ltrim", FUNC_LTRIM}, + {"repeat", FUNC_REPEAT}, + {"replace", FUNC_REPLACE}, + {"reverse", FUNC_REVERSE}, + {"rpad", FUNC_RPAD}, + {"rtrim", FUNC_RTRIM}, + {"substr", FUNC_SUBSTR}, + {"substring", FUNC_SUBSTR}, + {"substring_index", FUNC_SUBSTR_IDX}, + {"trim", FUNC_TRIM}, + {"ucase", FUNC_UPPER}, + {"upper", FUNC_UPPER}, + // Regexp functions + {"regexp_instr", FUNC_REGEXP_INSTR}, + {"regexp_replace", FUNC_REGEXP_REPLACE}, + {"regexp_substr", FUNC_REGEXP_SUBSTR}, + // Null functions + {"coalesce", FUNC_COALESCE}, + {"ifnull", FUNC_IFNULL}, + {"nullif", FUNC_NULLIF}, + {NULL, FUNC_UNKNOWN} +}; + + +static void convert_base_helper(const My_string &str, int from_base, int to_base, + Expression_value *value) +{ + char temp_buffer[66]; // should be enough for any base + long long result; + char *endptr; + int err; + size_t str_len= str.length(); + + if (from_base < 0) // Negative base = treat input as SIGNED + result= my_strntoll_8bit(charset_info, str.ptr(), str_len, -from_base, + &endptr, &err); + else // Positive base = treat input as UNSIGNED + result= (long long) my_strntoull_8bit(charset_info, str.ptr(), str_len, + from_base, &endptr, &err); + + if (err == ERANGE) + die("Range error: value out of range for Integer type"); + + if (err != 0 || endptr != str.ptr() + str_len) + die("invalid number '%.*s' for base %d", (int)str_len, str.ptr(), from_base); + + endptr= longlong2str(result, temp_buffer, to_base); + if (!endptr) + die("could not convert number '%.*s' for base %d", + (int)str_len, str.ptr(), to_base); + + value->set_string(temp_buffer, endptr - temp_buffer); +} + + +/** + @brief Compare two decimal strings numerically + @param[in] a First decimal string + @param[in] b Second decimal string + + @details + Compares two decimal number strings treating them as numeric values. + Handles leading/trailing whitespace, signs, and leading zeros properly. + + @return + -1 a < b + 0 a == b + 1 a > b +*/ + +static int cmp_decimal(const My_string &a, const My_string &b) +{ + const char *a_ptr= a.ptr(); + const char *b_ptr= b.ptr(); + size_t a_len= a.length(); + size_t b_len= b.length(); + + // Skip leading whitespace + while (a_len > 0 && isspace(*a_ptr)) + a_ptr++, a_len--; + while (b_len > 0 && isspace(*b_ptr)) + b_ptr++, b_len--; + + // Handle empty strings (treat as 0) + if (a_len == 0 && b_len == 0) return 0; + if (a_len == 0) return b_ptr[0] == '-' ? 1 : -1; + if (b_len == 0) return a_ptr[0] == '-' ? -1 : 1; + + // Extract signs + bool a_negative= false, b_negative= false; + if (*a_ptr == '-') a_negative= true, a_ptr++, a_len--; + else if (*a_ptr == '+') a_ptr++, a_len--; + + if (*b_ptr == '-') b_negative= true, b_ptr++, b_len--; + else if (*b_ptr == '+') b_ptr++, b_len--; + + // Skip leading zeros + while (a_len > 0 && *a_ptr == '0') a_ptr++, a_len--; + while (b_len > 0 && *b_ptr == '0') b_ptr++, b_len--; + + // Find actual numeric length (digits only) + size_t a_digits= 0, b_digits= 0; + for (size_t i= 0; i < a_len && isdigit(a_ptr[i]); i++) a_digits++; + for (size_t i= 0; i < b_len && isdigit(b_ptr[i]); i++) b_digits++; + + // Handle zero cases after removing leading zeros + bool a_is_zero= (a_digits == 0); + bool b_is_zero= (b_digits == 0); + + if (a_is_zero && b_is_zero) return 0; + if (a_is_zero) return b_negative ? 1 : -1; + if (b_is_zero) return a_negative ? -1 : 1; + + // Different signs: negative < positive + if (a_negative && !b_negative) return -1; + if (!a_negative && b_negative) return 1; + + // Same sign: compare absolute values + int abs_cmp= 0; + + // First compare by number of digits + if (a_digits != b_digits) + { + abs_cmp= (a_digits > b_digits) ? 1 : -1; + } + else + { + // Same number of digits: compare digit by digit + for (size_t i= 0; i < a_digits; i++) + { + if (a_ptr[i] != b_ptr[i]) + { + abs_cmp= (a_ptr[i] > b_ptr[i]) ? 1 : -1; + break; + } + } + } + + // If both negative, reverse the comparison result + return a_negative ? -abs_cmp : abs_cmp; +} + + +/* Expression Built-in Function Implementations */ + + +/** + @brief Absolute value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + ABS(X) returns the absolute (positive) value of X. + + @note Dies if argument count != 1 or argument is not numeric +*/ + +void func_abs(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("abs() expects 1 argument, got %d", count); + + if (!args[0].is_numeric) + die("abs() requires numeric argument"); + + result->set_int(abs(args[0].to_int())); +} + + +/** + @brief Base conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts numbers between different bases. + CONV(N, from_base, to_base) converts number N from base from_base to base to_base. + Bases can be from 2 to 62. Negative bases treat input as signed. + + @note Dies if argument count != 3, bases not numeric, or bases out of range +*/ + +void func_conv(Expression_value args[], int count, Expression_value *result) +{ + int from_base; + int to_base; + + if (count != 3) + die("conv() expects 3 arguments (N, from_base, to_base), got %d", count); + + from_base= (int)args[1].to_int(); + to_base= (int)args[2].to_int(); + + if (!args[1].is_numeric || !args[2].is_numeric) + die("conv() bases must be numeric"); + + if (abs(from_base) < 2 || abs(from_base) > 62) + die("conv() from_base must be between 2 and 62, got %d", from_base); + if (abs(to_base) < 2 || abs(to_base) > 62) + die("conv() to_base must be between 2 and 62, got %d", to_base); + + convert_base_helper(args[0].to_string(), from_base, to_base, result); +} + + +/** + @brief Binary conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts a number to binary representation. + BIN(N) returns a string representation of the binary value of N. + This is equivalent to CONV(N, 10, 2). + + @note Dies if argument count != 1 +*/ + +void func_bin(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("bin() expects 1 argument, got %d", count); + + convert_base_helper(args[0].to_string(), 10, 2, result); +} + + +/** + @brief Octal conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts a number to octal representation. + OCT(N) returns a string representation of the octal value of N. + This is equivalent to CONV(N, 10, 8). + + @note Dies if argument count != 1 +*/ + +void func_oct(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("oct() expects 1 argument, got %d", count); + + convert_base_helper(args[0].to_string(), 10, 8, result); +} + + +/** + @brief Hexadecimal conversion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + Converts a number to hexadecimal representation. + HEX(N) returns a string representation of the hexadecimal value of N. + This is equivalent to CONV(N, 10, 16). + + @note Dies if argument count != 1 +*/ + +void func_hex(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("hex() expects 1 argument, got %d", count); + + convert_base_helper(args[0].to_string(), 10, 16, result); +} + + +/** + @brief String search function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + INSTR(str, substr) returns position of first occurrence of substr in str. + Returns 0 if not found. Positions start at 1. Performs a case-insensitive + search. + + @note Dies if less than 2 arguments +*/ + +void func_instr(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("instr() expects 2 arguments (str, substr), got %d", count); + + my_match_t match; + My_string str= args[0].to_string(); + My_string substr= args[1].to_string(); + + if (charset_info->coll->instr(charset_info, str.ptr(), str.length(), + substr.ptr(), substr.length(), &match, 1)) + result->set_int(match.mb_len + 1); + else + result->set_int(0); +} + + +/** + @brief Locate substring function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LOCATE(substr, str [, start]) returns position of substr in str starting from + start (default 1). Returns 0 if substr is not in str. Positions start at 1. + Performs a case-insensitive search. + + @note Dies if wrong argument count or non-numeric start position +*/ + +void func_locate(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2 || count > 3) + die("locate() expects 2 or 3 arguments (substr, str [, start]), got %d", count); + + if (count == 3 && !args[2].is_numeric) + die("locate() start position must be numeric"); + + My_string substr= args[0].to_string(); + My_string str= args[1].to_string(); + + long long start= 0; + long long start0= 0; + my_match_t match; + + if (count == 3) + { + start0= start= args[2].to_int() - 1; + + if (start < 0 || start > (longlong)str.length()) + { + result->set_int(0); + return; + } + + start= str.charpos((int) start); + + // Substring is longer than str at start position. + if (start + substr.length() > str.length()) + { + result->set_int(0); + return; + } + } + + if (!substr.length()) + { + result->set_int(start + 1); + return; + } + + if (charset_info->coll->instr(charset_info, str.ptr() + start, + (uint)(str.length() - start), + substr.ptr(), substr.length(), &match, 1)) + result->set_int((longlong)match.mb_len + start0 + 1); + else + result->set_int(0); +} + + +/** + @brief String replacement function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REPLACE(str, from_str, to_str) replaces all occurrences of from_str with + to_str. Performs a case-sensitive match when searching for from_str. + + @note Dies if argument count != 3 or arguments are numeric +*/ + +void func_replace(Expression_value args[], int count, Expression_value *result) +{ + if (count != 3) + die("replace() expects 3 arguments (str, from, to), got %d", count); + + if (args[0].is_numeric || args[1].is_numeric || args[2].is_numeric) + die("replace() arguments must be strings"); + + My_string str= args[0].to_string(); + My_string from_str= args[1].to_string(); + My_string to_str= args[2].to_string(); + + if (from_str.length() == 0) + { + result->set_string(str.ptr(), str.length()); + return; + } + + My_string result_str; + result_str.copy(str); + + int pos= 0; + while ((pos= result_str.strstr(from_str, pos)) >= 0) + { + result_str.replace(pos, from_str.length(), to_str.ptr(), to_str.length()); + pos += to_str.length(); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief Substring extraction function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + SUBSTR(str, pos [, len]) returns substring starting at position pos. + Positions start at 1. Negative positions count from end. + + @note Dies if wrong argument count or non-numeric position/length +*/ + +void func_substr(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2 || count > 3) + die("substr() expects 2 or 3 arguments (str, start [, length]), got %d", count); + + if (args[0].is_numeric) + die("substr() first argument must be a string"); + + if (!args[1].is_numeric) + die("substr() start position must be numeric"); + + if (count == 3 && !args[2].is_numeric) + die("substr() length must be numeric"); + + My_string str= args[0].to_string(); + int start= (int)args[1].to_int(); + int length= count == 3 ? (int)args[2].to_int() : str.length(); + + if (start == 0 || start > (int)str.length() || length <= 0) + { + result->set_string("", 0); + return; + } + + if (start < 0) + start= str.length() + start; + else + start--; + + int end= str.length(); + if (count == 3) + { + end= start + length; + if (end > (int)str.length()) + end= str.length(); + } + + if (start >= end || start >= (int)str.length() || start < 0) + { + result->set_string("", 0); + return; + } + + result->set_string(str.ptr() + start, end - start); +} + + +/** + @brief String concatenation function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + CONCAT(str1, str2, ...) returns the string that results from concatenating + arguments. + + @note Dies if no arguments provided +*/ + +void func_concat(Expression_value args[], int count, Expression_value *result) +{ + if (count == 0) + die("concat() expects at least 1 argument"); + + My_string result_str= args[0].to_string(); + + for (int i= 1; i < count; ++i) + { + result_str.append(args[i].to_string()); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String concatenation with separator function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + CONCAT_WS(separator, str1, str2, ...) concatenates strings using separator. + If separator is NULL, returns NULL; all other NULL values are skipped. + + @note Dies if less than 2 arguments provided +*/ + +void func_concat_ws(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("concat_ws() expects at least 2 arguments"); + + if (args[0].type == EXPR_NULL) + { + result->reset(); + return; + } + + My_string separator= args[0].to_string(); + My_string result_str= args[1].to_string(); + + for (int i= 2; i < count; ++i) + { + if (args[i].type == EXPR_NULL) + continue; + result_str.append(separator); + result_str.append(args[i].to_string()); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String case conversion to lowercase + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LOWER(str) returns string str with all characters converted to lowercase. + LCASE(str) is an alias for LOWER(str). + + @note Dies if argument count != 1 +*/ + +void func_lower(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("lower() expects 1 argument, got %d", count); + + My_string result_str; + result_str.copy_casedn(charset_info, args[0].to_string().to_lex_cstring()); + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String case conversion to uppercase + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + UPPER(str) returns string str with all characters converted to uppercase. + UCASE(str) is an alias for UPPER(str). + + @note Dies if argument count != 1 +*/ + +void func_upper(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("upper() expects 1 argument, got %d", count); + + My_string result_str; + result_str.copy_caseup(charset_info, args[0].to_string().to_lex_cstring()); + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String reversal function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REVERSE(str) returns the string str with the order of the characters reversed. + + @note Dies if argument count != 1 +*/ + +void func_reverse(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("reverse() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + size_t len= str.length(); + for (size_t i= 0; i < len / 2; ++i) + { + char temp= str.c_ptr()[i]; + str.c_ptr()[i]= str.c_ptr()[len - 1 - i]; + str.c_ptr()[len - 1 - i]= temp; + } + + result->set_string(str.ptr(), str.length()); +} + + +/** + @brief String trimming function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + TRIM(str) returns string str with leading and trailing space removed. + + @note Dies if argument count != 1 +*/ + +void func_trim(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("trim() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + int start= 0; + while (start < (int)str.length() && my_isspace(charset_info, str.ptr()[start])) + start++; + + int end= (int)str.length(); + while (end > start && my_isspace(charset_info, str.ptr()[end - 1])) + end--; + + result->set_string(str.ptr() + start, end - start); +} + + +/** + @brief Left string trimming function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LTRIM(str) returns string str with leading space removed. + + @note Dies if argument count != 1 +*/ + +void func_ltrim(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("ltrim() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + int start= 0; + while (start < (int)str.length() && my_isspace(charset_info, str.ptr()[start])) + start++; + + result->set_string(str.ptr() + start, (int)str.length() - start); +} + + +/** + @brief Right string trimming function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + RTRIM(str) returns string str with trailing space removed. + + @note Dies if argument count != 1 +*/ + +void func_rtrim(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("rtrim() expects 1 argument, got %d", count); + + My_string str= args[0].to_string(); + + int end= (int)str.length(); + while (end > 0 && my_isspace(charset_info, str.ptr()[end - 1])) + end--; + + result->set_string(str.ptr(), end); +} + + +/** + @brief Left padding function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LPAD(str, len [, padstr]) returns the string str, left-padded with the + string padstr to a length of len characters. If str is longer than len, + the return value is shortened to len characters. If padstr is omitted, + the LPAD function pads spaces. + + @note Dies if wrong argument count, non-numeric length, or negative length +*/ + +void func_lpad(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2 && count != 3) + die("lpad() expects 2 or 3 arguments (str, length [, padstr]), got %d", count); + + if (!args[1].is_numeric) + die("lpad() length must be numeric"); + + My_string str= args[0].to_string(); + int length= (int)args[1].to_int(); + My_string padstr= count == 3 ? args[2].to_string() : My_string(); + My_string result_str; + + if (length < 0) + die("lpad() length cannot be negative"); + + if (count == 3 && padstr.is_empty()) + { + result->set_string("", 0); + return; + } + + if (length <= (int) str.length()) + { + result->set_string(str.ptr(), length); + return; + } + + int padding_needed= length - (int)str.length(); + if (count == 2) + { + for (int i= 0; i < padding_needed; ++i) + result_str.append(" ", 1); + } + else + { + for (int i= 0; i < padding_needed; ++i) + result_str.append(&padstr.ptr()[i % padstr.length()], 1); + } + + result_str.append(str.ptr(), str.length()); + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief Right padding function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + RPAD(str, len [, padstr]) returns the string str, right-padded with the + string padstr to a length of len characters. If str is longer than len, + the return value is shortened to len characters. If padstr is omitted, + the RPAD function pads spaces. + + @note Dies if wrong argument count, non-numeric length, or negative length +*/ + +void func_rpad(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2 && count != 3) + die("rpad() expects 2 or 3 arguments (str, length [, padstr]), got %d", count); + + if (!args[1].is_numeric) + die("rpad() length must be numeric"); + + My_string str= args[0].to_string(); + int length= (int)args[1].to_int(); + My_string padstr= count == 3 ? args[2].to_string() : My_string(); + + if (length < 0) + die("rpad() length cannot be negative"); + + if (count == 3 && padstr.is_empty()) + { + result->set_string("", 0); + return; + } + + if (length <= (int)str.length()) + { + result->set_string(str.ptr(), length); + return; + } + + int padding_needed= length - (int)str.length(); + + if (count == 2) + { + for (int i= 0; i < padding_needed; ++i) + str.append(" ", 1); + } + else + { + for (int i= 0; i < padding_needed; ++i) + str.append(&padstr.ptr()[i % padstr.length()], 1); + } + + result->set_string(str.ptr(), str.length()); +} + + +/** + @brief String length function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LENGTH(str) returns the length of the string str. + + @note Dies if argument count != 1 +*/ + +void func_length(Expression_value args[], int count, Expression_value *result) +{ + if (count != 1) + die("length() expects 1 argument, got %d", count); + + result->set_int((long long) args[0].to_string().length()); +} + + +/** + @brief Substring index function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + SUBSTRING_INDEX(str, delim, count) returns substring before count occurrences + of delim (counting from the left). If count is negative, returns substring + after count occurrences from end (counting from the right). Performs a + case-sensitive match when searching for delim. + + @note Dies if argument count != 3 or count is not numeric +*/ + +void func_substring_index(Expression_value args[], int count, + Expression_value *result) +{ + if (count != 3) + die("substring_index() expects 3 arguments (str, delimiter, count), got %d", count); + + if (!args[2].is_numeric) + die("substring_index() count must be numeric"); + + My_string str= args[0].to_string(); + My_string delimiter= args[1].to_string(); + int count_val= (int)args[2].to_int(); + + if (str.is_empty() || delimiter.is_empty() || !count_val) + { + result->set_string("", 0); + return; + } + + const char *str_ptr= str.ptr(); + const char *str_end= str.end(); + const char *delim_ptr= delimiter.ptr(); + int delim_len= (int)delimiter.length(); + + if (count_val > 0) + { + const char *current_pos= str_ptr; + int found_count= 0; + + while (current_pos < str_end && found_count < count_val) + { + const char *found= strstr(current_pos, delim_ptr); + if (!found) + break; + + found_count++; + if (found_count < count_val) + current_pos= found + delim_len; + else + current_pos= found; + } + + if (found_count < count_val) + result->set_string(str.ptr(), str.length()); + else + result->set_string(str.ptr(), current_pos - str_ptr); + } + else + { + count_val= -count_val; + const char *current_pos= str_end; + int found_count= 0; + + while (current_pos > str_ptr && found_count < count_val) + { + const char *found= NULL; + const char *search_pos= str_ptr; + + while (search_pos < current_pos) + { + const char *temp_found= strstr(search_pos, delim_ptr); + if (!temp_found || temp_found >= current_pos) + break; + found= temp_found; + search_pos= temp_found + delim_len; + } + + if (!found) + break; + + found_count++; + if (found_count < count_val) + current_pos= found; + else + current_pos= found + delim_len; + } + + if (found_count < count_val) + result->set_string(str.ptr(), str.length()); + else + result->set_string(current_pos, str_end - current_pos); + } +} + + +/** + @brief String repetition function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REPEAT(str, count) returns string consisting of str repeated count times. + If count is less than 1, returns an empty string. + + @note Dies if argument count != 2 or count is not numeric +*/ + +void func_repeat(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("repeat() expects 2 arguments (str, count), got %d", count); + + if (!args[1].is_numeric) + die("repeat() count must be numeric"); + + My_string result_str; + My_string str= args[0].to_string(); + int repeat_count= (int)args[1].to_int(); + + if (repeat_count <= 0 || str.is_empty()) + { + result->set_string("", 0); + return; + } + + if ((ulonglong) repeat_count > INT_MAX32) + repeat_count= INT_MAX32; + + for (int i= 0; i < repeat_count; ++i) + { + result_str.append(str.ptr(), str.length()); + } + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief String insertion function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + INSERT(str, pos, len, newstr) replaces len characters starting at pos with + newstr. Returns the original string if pos is not within the length of the string. + Replaces the rest of the string from position pos if len is not + within the length of the rest of the string. + + @note Dies if argument count != 4 or position/length not numeric +*/ + +void func_insert(Expression_value args[], int count, Expression_value *result) +{ + if (count != 4) + die("insert() expects 4 arguments (str, pos, len, newstr), got %d", count); + + if (!args[1].is_numeric) + die("insert() position must be numeric"); + + if (!args[2].is_numeric) + die("insert() length must be numeric"); + + My_string str= args[0].to_string(); + int pos= (int)args[1].to_int(); + int len= (int)args[2].to_int(); + My_string newstr= args[3].to_string(); + My_string result_str; + + + if (pos <= 0 || pos > (int)str.length()) + { + result->set_string(str.ptr(), str.length()); + return; + } + + pos--; + + int end_pos; + if (len < 0) + { + end_pos= str.length(); + } + else + { + end_pos= pos + len; + if (end_pos > (int)str.length()) + end_pos= str.length(); + } + + if (pos > 0) + result_str.append(str.ptr(), pos); + + result_str.append(newstr.ptr(), newstr.length()); + + if (end_pos < (int)str.length()) + result_str.append(str.ptr() + end_pos, str.length() - end_pos); + + result->set_string(result_str.ptr(), result_str.length()); +} + + +/** + @brief Regular expression position function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REGEXP_INSTR(subject, pattern) returns position of first match of pattern in + subject. Uses POSIX extended regular expressions with case-insensitive + matching. + + @note + The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags. + + @note + The $ literal is used as a special character for variable replacement. + + To use it as a regex End of Line/String Anchor, escape it with a backslash. + @code + $(regexp_instr('ABCC','C\$')) -> 4 + @endcode + + To use it as a literal, escape it with three backslashes. + @code + $(regexp_instr('ABC\$DE','\\\$')) -> 4 + @endcode + + @note Dies if argument count != 2 or regex compilation fails +*/ + +void func_regexp_instr(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("regexp_instr() expects 2 arguments (subject, pattern), got %d", count); + + regex_t regex; + regmatch_t match; + int err_code; + int cflags= REG_EXTENDED | REG_DOTALL | REG_ICASE; + My_string subject= args[0].to_string(); + My_string pattern= args[1].to_string(); + + if (pattern.is_empty()) + { + result->set_int(1); + return; + } + + if (subject.is_empty()) + { + result->set_int(0); + return; + } + + if ((err_code= regcomp(®ex, pattern.ptr(), cflags))) + { + char err_buf[1024]; + regerror(err_code, ®ex, err_buf, sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } + + err_code= regexec(®ex, subject.ptr(), 1, &match, 0); + regfree(®ex); + + result->set_int(err_code ? 0 : (int)(match.rm_so + 1)); +} + + +/** + @brief Regular expression substring extraction function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REGEXP_SUBSTR(subject, pattern) returns substring that matches pattern. + Uses POSIX extended regular expressions with case-insensitive matching. + + @note + The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags. + + @note + The $ literal is used as a special character for variable replacement. + + To use it as a regex End of Line/String Anchor, escape it with a backslash. + @code + $(regexp_substr('ABCC','C\$')) -> C + @endcode + + To use it as a literal, escape it with three backslashes. + @code + $(regexp_substr('ABC\$','\\\$')) -> $ + @endcode + + @note Dies if argument count != 2 or regex compilation fails +*/ + +void func_regexp_substr(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("regexp_substr() expects 2 arguments (subject, pattern), got %d", count); + + regex_t regex; + regmatch_t matches[1]; + int err_code; + int cflags= REG_EXTENDED | REG_DOTALL | REG_ICASE; + My_string subject= args[0].to_string(); + My_string pattern= args[1].to_string(); + + if (subject.is_empty()) + { + result->set_string("", 0); + return; + } + + if ((err_code= regcomp(®ex, pattern.ptr(), cflags))) + { + char err_buf[1024]; + regerror(err_code, ®ex, err_buf, sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } + + err_code= regexec(®ex, subject.ptr(), 1, matches, 0); + regfree(®ex); + + if (err_code) + { + result->set_string("", 0); + } + else + { + regoff_t start= matches[0].rm_so; + regoff_t end= matches[0].rm_eo; + result->set_string(subject.ptr() + start, end - start); + } +} + + +/** + @brief Regular expression replacement function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + REGEXP_REPLACE(subject, pattern, replace) replaces all matches of pattern + with replace. Supports backreferences \0-\9 in replace string. Uses + POSIX extended regex. + + @note + The collation case sensitivity can be overwritten using the (?i) and (?-i) PCRE flags. + + @note + The $ literal is used as a special character for variable replacement. + + To use it as a regex End of Line/String Anchor, escape it with a backslash. + @code + $(regexp_replace('ABCC','C\$','D')) -> ABCD + @endcode + + To use it as a literal, escape it with three backslashes. + @code + $(regexp_replace('ABC\$','\\\$','D')) -> ABCD + @endcode + + @note Dies if argument count != 3 or regex compilation fails +*/ + +void func_regexp_replace(Expression_value args[], int count, + Expression_value *result) +{ + if (count != 3) + die("regexp_replace() expects 3 arguments (subject, pattern, replace), got %d", count); + + regex_t regex; + regmatch_t matches[10]; // Array to store up to 10 matches (0=full match, 1-9=capture groups) + int err_code; + int cflags= REG_EXTENDED | REG_DOTALL | REG_ICASE; + My_string result_str; + My_string subject= args[0].to_string(); + My_string pattern= args[1].to_string(); + My_string replace= args[2].to_string(); + const char *current_pos= subject.ptr(); + const char *end_pos= subject.end(); + const char *replace_ptr; + const char *replace_end; + + if (pattern.is_empty()) + { + result->set_string(subject.ptr(), subject.length()); + return; + } + + if ((err_code= regcomp(®ex, pattern.ptr(), cflags))) + { + char err_buf[1024]; + regerror(err_code, ®ex, err_buf, sizeof(err_buf)); + die("Regex error: %s\n", err_buf); + } + + while (current_pos < end_pos) + { + err_code= regexec(®ex, current_pos, 10, matches, 0); + if (err_code) + { + result_str.append(current_pos, end_pos - current_pos); + break; + } + + // Append the text before the match + if (matches[0].rm_so > 0) + result_str.append(current_pos, matches[0].rm_so); + + // Process replacement string with backreferences + replace_ptr= replace.ptr(); + replace_end= replace.end(); + + while (replace_ptr < replace_end) + { + if (*replace_ptr == '\\' && replace_ptr + 1 < replace_end) + { + int back_ref_num= (int) (*(replace_ptr + 1) - '0'); + regoff_t start_off, end_off; + if (back_ref_num >= 0 && back_ref_num <= 9 && + (start_off=matches[back_ref_num].rm_so) > -1 && + (end_off=matches[back_ref_num].rm_eo) > -1) + { + result_str.append(current_pos + start_off, end_off - start_off); + } + else + { + result_str.append(replace_ptr, 2); + } + replace_ptr+= 2; + continue; + } + result_str.append(replace_ptr, 1); + replace_ptr++; + } + + current_pos+= matches[0].rm_eo; + + if (matches[0].rm_so == matches[0].rm_eo) + current_pos++; + } + + regfree(®ex); + result->set_string(result_str.ptr(), result_str.length()); } -static const char *get_col_value(MYSQL_RES *res, MYSQL_ROW row, const char *name) + +/** + @brief NULL-aware conditional function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + IFNULL(expr1, expr2) returns expr1 if it is not NULL, otherwise returns expr2. + Returns first non-NULL value. + + @note Dies if argument count != 2 +*/ + +void func_ifnull(Expression_value args[], int count, Expression_value *result) { - uint num_fields= mysql_num_fields(res); - MYSQL_FIELD *fields= mysql_fetch_fields(res); + if (count != 2) + die("ifnull() expects 2 arguments, got %d", count); - for (uint i= 0; i < num_fields; i++) + if (args[0].type == EXPR_NULL) { - if (strcmp(fields[i].name, name) == 0) - return row[i]; + *result= args[1]; + return; } - return "NULL"; + *result= args[0]; } -void do_sync_with_master2(struct st_command *command, long offset, - const char *connection_name) -{ - MYSQL_RES *res; - MYSQL_ROW row; - MYSQL *mysql= cur_con->mysql; - char query_buf[FN_REFLEN+128], query_buf2[120]; - int timeout= opt_wait_for_pos_timeout; +/** + @brief NULL-if-equal function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result - if (!master_pos.file[0]) - die("Calling 'sync_with_master' without calling 'save_master_pos'"); + @details + NULLIF(expr1, expr2) returns NULL if expr1 = expr2, otherwise returns expr1. + This is the same as `CASE WHEN expr1 = expr2 THEN NULL ELSE expr1 END`. - sprintf(query_buf, "select master_pos_wait('%s', %ld, %d, '%s')", - master_pos.file, master_pos.pos + offset, timeout, - connection_name); + @note Dies if argument count != 2 +*/ - if (mysql_query(mysql, query_buf)) - die("failed in '%s': %d: %s", query_buf, mysql_errno(mysql), - mysql_error(mysql)); +void func_nullif(Expression_value args[], int count, Expression_value *result) +{ + if (count != 2) + die("nullif() expects 2 arguments, got %d", count); - if (!(res= mysql_store_result(mysql))) - die("mysql_store_result() returned NULL for '%s'", query_buf); - if (!(row= mysql_fetch_row(res))) + /* If first is NULL, result is NULL (returns expr1) */ + if (args[0].type == EXPR_NULL) { - mysql_free_result(res); - die("empty result in %s", query_buf); + result->reset(); + return; } - int result= -99; - const char* result_str= row[0]; - if (result_str) - result= atoi(result_str); + bool equal= false; + if (args[0].is_numeric && args[1].is_numeric) + { + if (args[0].is_unsigned || args[1].is_unsigned) + equal= (args[0].to_uint() == args[1].to_uint()); + else + equal= (args[0].to_int() == args[1].to_int()); + } + else + { + equal= !(strcmp(args[0].to_string().c_ptr(), args[1].to_string().c_ptr())); + } - mysql_free_result(res); + if (equal) + result->reset(); + else + *result= args[0]; +} - if (!result_str || result < 0) - { - /* master_pos_wait returned NULL or < 0 */ - fprintf(stderr, "analyze: sync_with_master\n"); - sprintf(query_buf2, "show slave \"%s\" status", connection_name); +/** + @brief First non-NULL value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result - if (!mysql_query(mysql, query_buf2)) + @details + COALESCE(value1, value2, ...) returns first non-NULL value in list. + Returns NULL if all values are NULL. + + @note Dies if no arguments provided +*/ + +void func_coalesce(Expression_value args[], int count, Expression_value *result) +{ + if (count < 1) + die("coalesce() expects at least 1 argument"); + + for (int i= 0; i < count; ++i) + { + if (args[i].type != EXPR_NULL) { - if ((res= mysql_store_result(mysql))) - { - if ((row= mysql_fetch_row(res))) - { - fprintf(stderr, "Slave position: file: %s position: %s\n", - get_col_value(res, row, "Relay_Master_Log_File"), - get_col_value(res, row, "Read_Master_Log_Pos")); - fprintf(stderr, "Master position: file: %s position: %lld\n", - master_pos.file, (longlong) (master_pos.pos + offset)); - } - mysql_free_result(res); - } + *result= args[i]; + return; } - if (!result_str) + } + result->reset(); +} + + +/** + @brief Least value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + LEAST(value1, value2, ...) returns the minimum value among arguments. + For numeric values, performs numeric comparison. For strings, performs + string comparison. + + @note + If mixed numeric and string values are provided, the string values are + converted to numbers and the numeric comparison is performed. Be careful + with this, as a string could contain a number that is larger than 2^64-1. + + @note Dies if less than 2 arguments provided. +*/ + +void func_least(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("least() expects at least 2 arguments"); + + // Numeric mode if any arg is numeric + bool any_numeric= false; + for (int i= 0; i < count; ++i) + if (args[i].is_numeric) { any_numeric= true; break; } + + if (any_numeric) + { + int best_idx= 0; + for (int i= 1; i < count; ++i) { - /* - master_pos_wait returned NULL. This indicates that - slave SQL thread is not started, the slave's master - information is not initialized, the arguments are - incorrect, or an error has occurred - */ - die("%.*sB failed: '%s' returned NULL " \ - "indicating slave SQL thread failure", - command->first_word_len, command->query, query_buf); + if (cmp_decimal(args[i].to_string(), args[best_idx].to_string()) < 0) + best_idx= i; } - - if (result == -1) - die("%.*sB failed: '%s' returned -1 " \ - "indicating timeout after %d seconds", - command->first_word_len, command->query, query_buf, timeout); + if(args[best_idx].is_unsigned) + result->set_uint(args[best_idx].to_uint()); else - die("%.*sB failed: '%s' returned unknown result :%d", - command->first_word_len, command->query, query_buf, result); + result->set_int(args[best_idx].to_int()); + return; } - return; + // String mode: collation-aware + int best_idx= 0; + for (int i= 1; i < count; ++i) + { + My_string cur= args[i].to_string(); + My_string best= args[best_idx].to_string(); + if (sortcmp(&best, &cur, charset_info) > 0) + best_idx= i; + } + *result= args[best_idx]; } -void do_sync_with_master(struct st_command *command) -{ - long offset= 0; - char *p= command->first_argument; - const char *offset_start= p; - char *start, *buff= 0; - start= const_cast(""); - if (*offset_start) - { - for (; my_isdigit(charset_info, *p); p++) - offset = offset * 10 + *p - '0'; +/** + @brief Greatest value function + @param[in] args Array of function arguments + @param[in] count Number of arguments + @param[out] result Expression_value to store result + + @details + GREATEST(value1, value2, ...) returns the maximum value among arguments. + For numeric values, performs numeric comparison. For strings, performs + string comparison. + + @note + If mixed numeric and string values are provided, the string values are + converted to numbers and the numeric comparison is performed. Be careful + with this, as a string could contain a number that is larger than 2^64-1. + + @note Dies if less than 2 arguments provided. +*/ - if (*p && !my_isspace(charset_info, *p) && *p != ',') - die("Invalid integer argument \"%s\"", offset_start); +void func_greatest(Expression_value args[], int count, Expression_value *result) +{ + if (count < 2) + die("greatest() expects at least 2 arguments"); - while (*p && my_isspace(charset_info, *p)) - p++; - if (*p == ',') + bool any_numeric= false; + for (int i= 0; i < count; ++i) + if (args[i].is_numeric) { any_numeric= true; break; } + + if (any_numeric) + { + int best_idx= 0; + for (int i= 1; i < count; ++i) { - p++; - while (*p && my_isspace(charset_info, *p)) - p++; - start= buff= (char*)my_malloc(PSI_NOT_INSTRUMENTED, strlen(p)+1, - MYF(MY_WME|MY_FAE)); - get_string(&buff, &p, command); + if (cmp_decimal(args[i].to_string(), args[best_idx].to_string()) > 0) + best_idx= i; } - command->last_argument= p; + if(args[best_idx].is_unsigned) + result->set_uint(args[best_idx].to_uint()); + else + result->set_int(args[best_idx].to_int()); + return; } - do_sync_with_master2(command, offset, start); - if (buff) - my_free(start); - return; + + // String mode: collation-aware + int best_idx= 0; + for (int i= 1; i < count; ++i) + { + My_string best= args[best_idx].to_string(); + My_string cur= args[i].to_string(); + if (sortcmp(&best, &cur, charset_info) < 0) + best_idx= i; + } + *result= args[best_idx]; } -int do_save_master_pos() +enum func_type get_expr_function_type(const char *name, size_t len) { - MYSQL_RES *res; - MYSQL_ROW row; - MYSQL *mysql = cur_con->mysql; - const char *query; - DBUG_ENTER("do_save_master_pos"); + for (int i= 0; function_table[i].name; ++i) + { + if (!strncasecmp(function_table[i].name, name, len)) + return function_table[i].type; + } + return FUNC_UNKNOWN; +} - if (mysql_query(mysql, query= "show master status")) - die("failed in 'show master status': %d %s", - mysql_errno(mysql), mysql_error(mysql)); - if (!(res = mysql_store_result(mysql))) - die("mysql_store_result() returned NULL for '%s'", query); - if (!(row = mysql_fetch_row(res))) - die("empty result in show master status"); - strnmov(master_pos.file, row[0], sizeof(master_pos.file)-1); - master_pos.pos = strtoul(row[1], (char**) 0, 10); - mysql_free_result(res); - DBUG_RETURN(0); +/** + @brief Execute built-in function call during expression parsing + @param[in] func_type Type of function to execute (from func_type enum) + @param[out] result Expression_value to store function result + @param[in] s Pointer to string pointer containing expression + + @details + Parses function arguments and executes the specified built-in function. + Each argument is recursively evaluated as a full expression. + Then delegates to the appropriate func_* implementation based on func_type. + + @note Dies on syntax errors or argument count mismatches +*/ + +void handle_expr_function_call(enum func_type func_type, + Expression_value *result, const char **s) +{ + Expression_value args[MAX_FUNC_ARGS]; + int arg_count= 0; + + while (!match(s, ")")) + { + if (arg_count >= MAX_FUNC_ARGS) + die("Too many function arguments (max %d)", MAX_FUNC_ARGS); + + expr(&args[arg_count], s); + arg_count++; + + /* if the next character is a comma, skip it */ + if (match(s, ",")) + continue; + + if (match(s, ")")) + break; + + die("Syntax error: Expected ',' or ')' in function call"); + } + + /* generic NULL propagation, except for IFNULL/NULLIF/COALESCE/CONCAT_WS */ + if (func_type != FUNC_IFNULL && func_type != FUNC_NULLIF && + func_type != FUNC_COALESCE && func_type != FUNC_CONCAT_WS) + { + for (int i= 0; i < arg_count; i++) + { + if (args[i].type == EXPR_NULL) + { + result->reset(); + return; + } + } + } + + switch (func_type) { + case FUNC_ABS: + func_abs(args, arg_count, result); + break; + case FUNC_CONV: + func_conv(args, arg_count, result); + break; + case FUNC_BIN: + func_bin(args, arg_count, result); + break; + case FUNC_OCT: + func_oct(args, arg_count, result); + break; + case FUNC_HEX: + func_hex(args, arg_count, result); + break; + case FUNC_INSTR: + func_instr(args, arg_count, result); + break; + case FUNC_LOCATE: + func_locate(args, arg_count, result); + break; + case FUNC_REPLACE: + func_replace(args, arg_count, result); + break; + case FUNC_SUBSTR: + func_substr(args, arg_count, result); + break; + case FUNC_CONCAT: + func_concat(args, arg_count, result); + break; + case FUNC_CONCAT_WS: + func_concat_ws(args, arg_count, result); + break; + case FUNC_LOWER: + func_lower(args, arg_count, result); + break; + case FUNC_UPPER: + func_upper(args, arg_count, result); + break; + case FUNC_REVERSE: + func_reverse(args, arg_count, result); + break; + case FUNC_TRIM: + func_trim(args, arg_count, result); + break; + case FUNC_LTRIM: + func_ltrim(args, arg_count, result); + break; + case FUNC_RTRIM: + func_rtrim(args, arg_count, result); + break; + case FUNC_LPAD: + func_lpad(args, arg_count, result); + break; + case FUNC_RPAD: + func_rpad(args, arg_count, result); + break; + case FUNC_LENGTH: + func_length(args, arg_count, result); + break; + case FUNC_SUBSTR_IDX: + func_substring_index(args, arg_count, result); + break; + case FUNC_REPEAT: + func_repeat(args, arg_count, result); + break; + case FUNC_INSERT: + func_insert(args, arg_count, result); + break; + case FUNC_LEAST: + func_least(args, arg_count, result); + break; + case FUNC_GREATEST: + func_greatest(args, arg_count, result); + break; + case FUNC_REGEXP_INSTR: + func_regexp_instr(args, arg_count, result); + break; + case FUNC_REGEXP_SUBSTR: + func_regexp_substr(args, arg_count, result); + break; + case FUNC_REGEXP_REPLACE: + func_regexp_replace(args, arg_count, result); + break; + case FUNC_IFNULL: + func_ifnull(args, arg_count, result); + break; + case FUNC_NULLIF: + func_nullif(args, arg_count, result); + break; + case FUNC_COALESCE: + func_coalesce(args, arg_count, result); + break; + case FUNC_UNKNOWN: + default: + die("Unknown function"); + break; + } } @@ -5811,8 +8597,12 @@ void do_close_connection(struct st_command *command) DBUG_PRINT("info", ("Closing connection %s", con->name)); #ifndef EMBEDDED_LIBRARY if (command->type == Q_DIRTY_CLOSE) - { mariadb_cancel(con->mysql); + else + { + simple_command(con->mysql,COM_QUIT,0,0,0); + if (con->util_mysql) + simple_command(con->util_mysql,COM_QUIT,0,0,0); } #endif /*!EMBEDDED_LIBRARY*/ if (con->stmt) @@ -6559,6 +9349,84 @@ void do_block(enum block_cmd cmd, struct st_command* command) if (*p && *p != '{') die("Missing '{' after %s. Found \"%s\"", cmd_name, p); + if (*expr_start == '$' && *(expr_start + 1) == '(') + { + const char *scanner= expr_start + 2; + int paren_level= 1; + char in_quote= 0; // Track quote state + bool escaped= false; // Track if the current character is escaped + + while (*scanner && paren_level > 0) + { + if (!in_quote) + { + // Not inside quotes - handle parentheses normally + if (*scanner == '(') paren_level++; + else if (*scanner == ')') paren_level--; + else if (*scanner == '\'' || *scanner == '"') + in_quote= *scanner; // Start of quoted string + } + else + { + // Inside quotes - only look for closing quote + if (!escaped && *scanner == in_quote) + in_quote= 0; // End of quoted string + } + escaped= (!escaped && *scanner == '\\'); + scanner++; + } + + const char *end_ptr= expr_end; + while(end_ptr > expr_start && my_isspace(charset_info, *(end_ptr - 1))) + end_ptr--; + + // if the $(...) is the entire condition, evaluate it + if (scanner == end_ptr) + { + DYNAMIC_STRING evaluated_expr; + init_dynamic_string(&evaluated_expr, "", 64, 256); + + do_eval(&evaluated_expr, expr_start, expr_end, FALSE); + + char* result_str= evaluated_expr.str; + while (*result_str && my_isspace(charset_info, *result_str)) + result_str++; + + /* + Setup the next block on the stack + This logic is borrowed from the end of this function + Any non-empty string which does not begin with 0 is TRUE + */ + cur_block++; + cur_block->cmd= cmd; + cur_block->ok= (*result_str && *result_str != '0'); + + if (not_expr) + cur_block->ok= !cur_block->ok; + + if (cur_block->ok) + { + cur_block->delim[0]= '\0'; + } + else + { + /* Remember "old" delimiter if entering a false if block */ + if (safe_strcpy_truncated(cur_block->delim, sizeof cur_block->delim, + delimiter)) + die("Delimiter too long, truncated"); + } + + DBUG_PRINT("info", ("OK: %d", cur_block->ok)); + + dynstr_free(&evaluated_expr); + DBUG_VOID_RETURN; + } + else + { + die("Expression evaluator $(...) must be the entire condition"); + } + } + var_init(&v,0,0,0,0); /* If expression starts with a variable, it may be a compare condition */ @@ -9023,7 +11891,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, var_set_errno(mysql_stmt_errno(stmt)); display_optimizer_trace(cn, ds); - #if MYSQL_VERSION_ID >= 50000 if (cursor_protocol_enabled) { ulong type= CURSOR_TYPE_NO_CURSOR; @@ -9031,7 +11898,6 @@ void run_query_stmt(struct st_connection *cn, struct st_command *command, die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s", mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); } - #endif revert_properties(); @@ -9248,7 +12114,6 @@ void run_execute_stmt(struct st_connection *cn, struct st_command *command, init_dynamic_string(&ds_execute_warnings, NULL, 0, 256); } -#if MYSQL_VERSION_ID >= 50000 if (cursor_protocol_enabled) { /* @@ -9259,7 +12124,6 @@ void run_execute_stmt(struct st_connection *cn, struct st_command *command, die("mysql_stmt_attr_set(STMT_ATTR_CURSOR_TYPE) failed': %d %s", mysql_stmt_errno(stmt), mysql_stmt_error(stmt)); } -#endif /* Execute the query @@ -9494,6 +12358,7 @@ int util_query(MYSQL* org_mysql, const char* query){ /* enable local infile, in non-binary builds often disabled by default */ mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0); mysql_options(mysql, MYSQL_OPT_NONBLOCK, 0); + mysql_options(mysql,MYSQL_OPT_PROTOCOL,(char*)&(org_mysql->options.protocol)); SET_SSL_OPTS(mysql); safe_connect(mysql, "util", org_mysql->host, org_mysql->user, org_mysql->passwd, org_mysql->db, org_mysql->port, @@ -9615,7 +12480,7 @@ void run_query(struct st_connection *cn, struct st_command *command, int flags) dynstr_set(&ds_res, 0); if (view_protocol_enabled && mysql && - complete_query && + complete_query && !(mysql->server_status & SERVER_STATUS_IN_TRANS) && match_re(&view_re, query)) { /* diff --git a/client/readline.cc b/client/readline.cc index e4014658c0822..f88a942f012a4 100644 --- a/client/readline.cc +++ b/client/readline.cc @@ -23,38 +23,11 @@ #include #include "my_readline.h" -static bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size, - ulong max_size); static bool init_line_buffer_from_string(LINE_BUFFER *buffer,char * str); static size_t fill_buffer(LINE_BUFFER *buffer); static char *intern_read_line(LINE_BUFFER *buffer, ulong *out_length); -LINE_BUFFER *batch_readline_init(ulong max_size,FILE *file) -{ - LINE_BUFFER *line_buff; - -#ifndef _WIN32 - MY_STAT input_file_stat; - if (my_fstat(fileno(file), &input_file_stat, MYF(MY_WME)) || - MY_S_ISDIR(input_file_stat.st_mode) || - MY_S_ISBLK(input_file_stat.st_mode)) - return 0; -#endif - - if (!(line_buff=(LINE_BUFFER*) - my_malloc(PSI_NOT_INSTRUMENTED, sizeof(*line_buff), - MYF(MY_WME | MY_ZEROFILL)))) - return 0; - if (init_line_buffer(line_buff,my_fileno(file),IO_SIZE,max_size)) - { - my_free(line_buff); - return 0; - } - return line_buff; -} - - char *batch_readline(LINE_BUFFER *line_buff, bool binary_mode) { char *pos; @@ -105,8 +78,7 @@ LINE_BUFFER *batch_readline_command(LINE_BUFFER *line_buff, char * str) Functions to handle buffered readings of lines from a stream ******************************************************************************/ -static bool -init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,ulong max_buffer) +bool init_line_buffer(LINE_BUFFER *buffer,File file,ulong size,ulong max_buffer) { buffer->file=file; buffer->bufread=size; diff --git a/cmake/build_configurations/mysql_release.cmake b/cmake/build_configurations/mysql_release.cmake index 6b7b4d698b117..8c120642fe50f 100644 --- a/cmake/build_configurations/mysql_release.cmake +++ b/cmake/build_configurations/mysql_release.cmake @@ -120,8 +120,8 @@ ELSEIF(DEB) SET(WITH_ZLIB system CACHE STRING "") SET(WITH_LIBWRAP ON) SET(HAVE_EMBEDDED_PRIVILEGE_CONTROL ON) - # No hurd implementation - IF(NOT CMAKE_SYSTEM_PROCESSOR STREQUAL "i686-AT386") + # On Hurd systems (GNU) there is no auth socket implementation + IF(NOT CMAKE_SYSTEM_NAME STREQUAL "GNU") SET(PLUGIN_AUTH_SOCKET YES CACHE STRING "") ENDIF() SET(WITH_EMBEDDED_SERVER ON CACHE BOOL "") diff --git a/cmake/build_depends.cmake b/cmake/build_depends.cmake index 5adaee337403c..758ba184628bd 100644 --- a/cmake/build_depends.cmake +++ b/cmake/build_depends.cmake @@ -32,7 +32,7 @@ IF(RPM) GET_PROPERTY(T CACHE ${V} PROPERTY TYPE) IF ((T STREQUAL FILEPATH OR V MATCHES "^CMAKE_COMMAND$") AND ${V} MATCHES "^/") IF (RPM) - FIND_DEP(${V} rpm -q --qf "%{NAME}" -f ${${V}}) + FIND_DEP(${V} rpm -q --qf "%{NAME} " -f ${${V}}) ELSE() # must be DEB MESSAGE(FATAL_ERROR "Not implemented") ENDIF () diff --git a/cmake/cpack_rpm.cmake b/cmake/cpack_rpm.cmake index 72595e358bd0a..55645b69d2d04 100644 --- a/cmake/cpack_rpm.cmake +++ b/cmake/cpack_rpm.cmake @@ -229,6 +229,10 @@ SETA(CPACK_RPM_client_PACKAGE_REQUIRES SETA(CPACK_RPM_common_PACKAGE_CONFLICTS "MariaDB-server < 10.6.1") +SETA(CPACK_RPM_common_PACKAGE_OBSOLETES + "mysql-common") +SETA(CPACK_RPM_common_PACKAGE_PROVIDES + "mysql-common") SETA(CPACK_RPM_devel_PACKAGE_OBSOLETES "MySQL-devel") @@ -259,14 +263,6 @@ SETA(CPACK_RPM_server_PACKAGE_REQUIRES "MariaDB-common >= 10.6.1" "MariaDB-client >= 11.0.0") -IF(WITH_WSREP) - SETA(CPACK_RPM_server_PACKAGE_REQUIRES - "galera-4" "rsync" "grep" "gawk" "iproute" - "coreutils" "findutils" "tar") - SETA(CPACK_RPM_server_PACKAGE_RECOMMENDS "lsof" "socat" "pv") - SETA(CPACK_RPM_test_PACKAGE_REQUIRES "${CPACK_RPM_PACKAGE_REQUIRES}" "socat") -ENDIF() - SET(CPACK_RPM_server_PRE_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-prein.sh) SET(CPACK_RPM_server_PRE_UNINSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-preun.sh) SET(CPACK_RPM_server_POST_INSTALL_SCRIPT_FILE ${CMAKE_SOURCE_DIR}/support-files/rpm/server-postin.sh) @@ -322,8 +318,6 @@ ELSEIF(RPM MATCHES "(rhel|centos|rocky)") ALTERNATIVE_NAME("shared" "mariadb-connector-c" ${MARIADB_CONNECTOR_C_VERSION}-1) ALTERNATIVE_NAME("shared" "mariadb-connector-c-config" ${MARIADB_CONNECTOR_C_VERSION}-1) ALTERNATIVE_NAME("devel" "mariadb-connector-c-devel" ${MARIADB_CONNECTOR_C_VERSION}-1) - SETA(CPACK_RPM_client_PACKAGE_PROVIDES "mariadb-galera = 3:%{version}-%{release}") - SETA(CPACK_RPM_common_PACKAGE_PROVIDES "mariadb-galera-common = 3:%{version}-%{release}") SETA(CPACK_RPM_common_PACKAGE_REQUIRES "MariaDB-shared") ELSEIF(RPM MATCHES "sles") ALTERNATIVE_NAME("server" "mariadb") @@ -341,6 +335,9 @@ IF(RPM MATCHES "fedora") ALTERNATIVE_NAME("shared" "mariadb-connector-c" ${MARIADB_CONNECTOR_C_VERSION}-1) ENDIF() +IF(RPM MATCHES "fedora|rhel|centos" AND NOT RPM MATCHES "rhel[78]") + SETA(CPACK_RPM_server_PACKAGE_REQUIRES "(mysql-selinux >= 1.0.14 if selinux-policy-targeted)") +ENDIF() SET(PYTHON_SHEBANG "/usr/bin/python3" CACHE STRING "python shebang") ################ diff --git a/cmake/info_bin.cmake b/cmake/info_bin.cmake deleted file mode 100644 index d59b512bcec24..0000000000000 --- a/cmake/info_bin.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. -# -# 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 - - -# The sole purpose of this cmake control file is to create the "INFO_BIN" file. - -# By having a separate cmake file for this, it is ensured this happens -# only in the build (Unix: "make") phase, not when cmake runs. -# This, in turn, avoids creating stuff in the source directory - -# it should get into the binary directory only. - - -# Get the macros which the "INFO_*" files. -INCLUDE(${CMAKE_BINARY_DIR}/info_macros.cmake) - -# Here is where the action is. -CREATE_INFO_BIN() - diff --git a/cmake/info_macros.cmake.in b/cmake/info_macros.cmake.in deleted file mode 100644 index 89ca1ec79dc33..0000000000000 --- a/cmake/info_macros.cmake.in +++ /dev/null @@ -1,161 +0,0 @@ -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. -# -# 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 - - -# Handle/create the "INFO_*" files describing a MariaDB (server) binary. -# This is part of the fix for bug#42969. - - -# Several of cmake's variables need to be translated from '@' notation -# to '${}', this is done by the "configure" call in top level "CMakeLists.txt". -# If further variables are used in this file, add them to this list. - -SET(VERSION "@VERSION@") -SET(MAJOR_VERSION "@MAJOR_VERSION@") -SET(MINOR_VERSION "@MINOR_VERSION@") -SET(PATCH_VERSION "@PATCH_VERSION@") -SET(CMAKE_SOURCE_DIR "@CMAKE_SOURCE_DIR@") -SET(CMAKE_BINARY_DIR "@CMAKE_BINARY_DIR@") -SET(CMAKE_GENERATOR "@CMAKE_GENERATOR@") -SET(CMAKE_SIZEOF_VOID_P "@CMAKE_SIZEOF_VOID_P@") -SET(GIT_EXECUTABLE "@GIT_EXECUTABLE@") -SET(CMAKE_CROSSCOMPILING "@CMAKE_CROSSCOMPILING@") -SET(CMAKE_HOST_SYSTEM "@CMAKE_HOST_SYSTEM@") -SET(CMAKE_HOST_SYSTEM_PROCESSOR "@CMAKE_HOST_SYSTEM_PROCESSOR@") -SET(CMAKE_SYSTEM "@CMAKE_SYSTEM@") -SET(CMAKE_SYSTEM_PROCESSOR "@CMAKE_SYSTEM_PROCESSOR@") - - -# Create an "INFO_SRC" file with information about the source (only). -# We use "git log", if possible, and the "VERSION" contents. -# -# Outside development (git tree), the "INFO_SRC" file will not be modified -# provided it exists (from "make dist" or a source tarball creation). - -MACRO(CREATE_INFO_SRC target_dir) - SET(INFO_SRC "${target_dir}/INFO_SRC") - - SET(PERLSCRIPT - "use warnings; use POSIX qw(strftime); " - "print strftime \"%F %T %z\", localtime;") - EXECUTE_PROCESS( - COMMAND perl -e "${PERLSCRIPT}" - RESULT_VARIABLE result - OUTPUT_VARIABLE bdate - ERROR_VARIABLE error - ) - IF(error) - MESSAGE(STATUS "Could not determine build-date: <${error}>") - ENDIF() - - IF(GIT_EXECUTABLE AND EXISTS ${CMAKE_SOURCE_DIR}/.git) - # Sources are in a GIT repository: Always update. - EXECUTE_PROCESS( - COMMAND ${GIT_EXECUTABLE} rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE bname - ) - - EXECUTE_PROCESS( - COMMAND ${GIT_EXECUTABLE} log -1 - --pretty="commit: %H%ndate: %ci%nbuild-date: ${bdate} %nshort: %h%nbranch: ${bname}" - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE VERSION_INFO - ) - - ## Output from git is quoted with "", remove them. - STRING(REPLACE "\"" "" VERSION_INFO "${VERSION_INFO}") - FILE(WRITE ${INFO_SRC} "${VERSION_INFO}\n") - # to debug, add: FILE(APPEND ${INFO_SRC} "\nResult ${RESULT}\n") - # For better readability ... - FILE(APPEND ${INFO_SRC} - "MariaDB source ${MAJOR_VERSION}.${MINOR_VERSION}.${PATCH_VERSION}\n") - ELSEIF(EXISTS ${INFO_SRC}) - # Outside a git tree, there is no need to change an existing "INFO_SRC", - # it cannot be improved. - ELSEIF(EXISTS ${CMAKE_SOURCE_DIR}/Docs/INFO_SRC) - # If we are building from a source distribution, it also contains "INFO_SRC". - # Similar, the export used for a release build already has the file. - FILE(READ ${CMAKE_SOURCE_DIR}/Docs/INFO_SRC SOURCE_INFO) - FILE(WRITE ${INFO_SRC} "${SOURCE_INFO}\n") - ELSEIF(EXISTS ${CMAKE_SOURCE_DIR}/INFO_SRC) - # This is not the proper location, but who knows ... - FILE(READ ${CMAKE_SOURCE_DIR}/INFO_SRC SOURCE_INFO) - FILE(WRITE ${INFO_SRC} "${SOURCE_INFO}\n") - ELSE() - # This is a fall-back. - FILE(WRITE ${INFO_SRC} "\nMariaDB source ${VERSION}\n") - ENDIF() -ENDMACRO(CREATE_INFO_SRC) - - -# This is for the "real" build, must be run again with each cmake run -# to make sure we report the current flags (not those of some previous run). - -MACRO(CREATE_INFO_BIN) - SET(INFO_BIN "Docs/INFO_BIN") - - FILE(WRITE ${INFO_BIN} "===== Information about the build process: =====\n") - IF (WIN32) - EXECUTE_PROCESS(COMMAND cmd /c date /T - OUTPUT_VARIABLE TMP_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) - ELSEIF(UNIX) - EXECUTE_PROCESS(COMMAND date "+%Y-%m-%d %H:%M:%S" - OUTPUT_VARIABLE TMP_DATE OUTPUT_STRIP_TRAILING_WHITESPACE) - ELSE() - SET(TMP_DATE "(no date command known for this platform)") - ENDIF() - SITE_NAME(HOSTNAME) - FILE(APPEND ${INFO_BIN} "Build was run at ${TMP_DATE} on host '${HOSTNAME}'\n\n") - - # According to the cmake docs, these variables should always be set. - # However, they are empty in my tests, using cmake 2.6.4 on Linux, various Unix, and Windows. - # Still, include this code, so we will profit if a build environment does provide that info. - IF(CMAKE_HOST_SYSTEM) - FILE(APPEND ${INFO_BIN} "Build was done on ${CMAKE_HOST_SYSTEM} using ${CMAKE_HOST_SYSTEM_PROCESSOR}\n") - ENDIF() - IF(CMAKE_CROSSCOMPILING) - FILE(APPEND ${INFO_BIN} "Build was done for ${CMAKE_SYSTEM} using ${CMAKE_SYSTEM_PROCESSOR}\n") - ENDIF() - - # ${CMAKE_VERSION} doesn't work in 2.6.0, use the separate components. - FILE(APPEND ${INFO_BIN} "Build was done using cmake ${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION} \n\n") - - IF (WIN32) - FILE(APPEND ${INFO_BIN} "===== Compiler / generator used: =====\n") - FILE(APPEND ${INFO_BIN} ${CMAKE_GENERATOR} "\n\n") - ELSEIF(UNIX) - FILE(APPEND ${INFO_BIN} "===== Compiler flags used (from the 'sql/' subdirectory): =====\n") - IF(EXISTS sql/CMakeFiles/sql.dir/flags.make) - EXECUTE_PROCESS(COMMAND egrep "^# compile|^C_|^CXX_" sql/CMakeFiles/sql.dir/flags.make OUTPUT_VARIABLE COMPILE_FLAGS) - FILE(APPEND ${INFO_BIN} ${COMPILE_FLAGS} "\n") - ELSE() - FILE(APPEND ${INFO_BIN} "File 'sql/CMakeFiles/sql.dir/flags.make' is not yet found.\n\n") - ENDIF() - ENDIF() - FILE(APPEND ${INFO_BIN} "Pointer size: ${CMAKE_SIZEOF_VOID_P}\n\n") - - FILE(APPEND ${INFO_BIN} "===== Feature flags used: =====\n") - IF(EXISTS ${CMAKE_BINARY_DIR}/CMakeCache.txt) - # Attention: "-N" prevents cmake from entering a recursion, and it must be a separate flag from "-L". - EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -N -L ${CMAKE_BINARY_DIR} OUTPUT_VARIABLE FEATURE_FLAGS) - FILE(APPEND ${INFO_BIN} ${FEATURE_FLAGS} "\n") - ELSE() - FILE(APPEND ${INFO_BIN} "File 'CMakeCache.txt' is not yet found.\n\n") - ENDIF() - - FILE(APPEND ${INFO_BIN} "===== EOF =====\n") -ENDMACRO(CREATE_INFO_BIN) - diff --git a/cmake/info_src.cmake b/cmake/info_src.cmake deleted file mode 100644 index df6249f111e1c..0000000000000 --- a/cmake/info_src.cmake +++ /dev/null @@ -1,31 +0,0 @@ -# Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. -# -# 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 - - -# The sole purpose of this cmake control file is to create the "INFO_SRC" file. - -# As long as and "git pull" (or "git commit") is followed by a "cmake", -# the call in top level "CMakeLists.txt" is sufficient. -# This file is to provide a separate target for the "make" phase, -# to ensure the git commit hash is correct even after a sequence -# cmake ; make ; git pull ; make - - -# Get the macros which handle the "INFO_*" files. -INCLUDE(${CMAKE_BINARY_DIR}/info_macros.cmake) - -# Here is where the action is. -CREATE_INFO_SRC(${CMAKE_BINARY_DIR}/Docs) - diff --git a/cmake/install_layout.cmake b/cmake/install_layout.cmake index eb969679bf786..55e960a3c1572 100644 --- a/cmake/install_layout.cmake +++ b/cmake/install_layout.cmake @@ -163,6 +163,7 @@ SET(INSTALL_UNIX_ADDRDIR_RPM "${INSTALL_MYSQLDATADIR_RPM}/mysql.sock" SET(INSTALL_SYSTEMD_UNITDIR_RPM "/usr/lib/systemd/system") SET(INSTALL_SYSTEMD_SYSUSERSDIR_RPM "/usr/lib/sysusers.d") SET(INSTALL_SYSTEMD_TMPFILESDIR_RPM "/usr/lib/tmpfiles.d") +SET(INSTALL_RUNDATADIR_RPM "/run/mariadb") SET(INSTALL_PAMDIR_RPM "/${INSTALL_LIBDIR_RPM}/security") SET(INSTALL_PAMDATADIR_RPM "/etc/security") @@ -193,7 +194,8 @@ SET(INSTALL_SUPPORTFILESDIR_DEB "share/mariadb") # SET(INSTALL_MYSQLDATADIR_DEB "/var/lib/mysql") -SET(INSTALL_UNIX_ADDRDIR_DEB "/run/mysqld/mysqld.sock") +SET(INSTALL_RUNDATADIR_DEB "/run/mysqld") +SET(INSTALL_UNIX_ADDRDIR_DEB "${INSTALL_RUNDATADIR_DEB}/mysqld.sock") SET(INSTALL_SYSTEMD_UNITDIR_DEB "/lib/systemd/system") SET(INSTALL_SYSTEMD_SYSUSERSDIR_DEB "/usr/lib/sysusers.d") SET(INSTALL_SYSTEMD_TMPFILESDIR_DEB "/usr/lib/tmpfiles.d") @@ -257,3 +259,7 @@ IF(NOT MYSQL_UNIX_ADDR) SET(MYSQL_UNIX_ADDR ${INSTALL_UNIX_ADDRDIR}) ENDIF() +IF(NOT INSTALL_RUNDATADIR) + get_filename_component(MYSQL_UNIX_DIR ${MYSQL_UNIX_ADDR} DIRECTORY) + SET(INSTALL_RUNDATADIR "${MYSQL_UNIX_DIR}" CACHE FILEPATH "Rundata installation directory" ${FORCE}) +ENDIF() diff --git a/cmake/install_macros.cmake b/cmake/install_macros.cmake index cad94a641930f..282800a3285e8 100644 --- a/cmake/install_macros.cmake +++ b/cmake/install_macros.cmake @@ -286,6 +286,7 @@ FUNCTION(INSTALL_RUNTIME_DEPS) POST_EXCLUDE_REGEXES ".*system32/.*\\.dll" # Windows stuff POST_INCLUDE_REGEXES + "libssl" "libcrypto" # Account for OpenSSL libraries in system32 DIRECTORIES $<$:${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/bin $<$,$>:${VCPKG_INSTALLED_DIR}/${VCPKG_TARGET_TRIPLET}/debug/bin> diff --git a/cmake/libfmt.cmake b/cmake/libfmt.cmake index 47f2e00bae164..bdd7d8c0be958 100644 --- a/cmake/libfmt.cmake +++ b/cmake/libfmt.cmake @@ -15,8 +15,8 @@ MACRO(BUNDLE_LIBFMT) ExternalProject_Add( libfmt PREFIX "${dir}" - URL "https://github.com/fmtlib/fmt/releases/download/11.1.4/fmt-11.1.4.zip" - URL_MD5 ad6a56b15cddf4aad2a234e7cfc9e8c9 + URL "https://github.com/fmtlib/fmt/releases/download/12.1.0/fmt-12.1.0.zip" + URL_MD5 028c6979cad96a4260154f091885171a INSTALL_COMMAND "" CONFIGURE_COMMAND "" BUILD_COMMAND "" diff --git a/cmake/maintainer.cmake b/cmake/maintainer.cmake index ce183d5d238f0..d454f10e86695 100644 --- a/cmake/maintainer.cmake +++ b/cmake/maintainer.cmake @@ -67,6 +67,14 @@ IF(CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS SET(MY_ERROR_FLAGS ${MY_ERROR_FLAGS} -Wno-error=non-virtual-dtor) # gcc bug 7302 ENDIF() +FOREACH(LANG C CXX) + IF(CMAKE_${LANG}_COMPILER_ID MATCHES "Clang") + MY_CHECK_AND_SET_COMPILER_FLAG(-Werror=uninitialized-explicit-init) + MY_CHECK_AND_SET_COMPILER_FLAG(-Werror=uninitialized-const-reference) + SET(CMAKE_${LANG}_FLAGS "${CMAKE_${LANG}_FLAGS} -Werror=uninitialized") + ENDIF() +ENDFOREACH() + IF(MYSQL_MAINTAINER_MODE MATCHES "OFF|WARN") RETURN() ELSEIF(MYSQL_MAINTAINER_MODE MATCHES "AUTO") diff --git a/cmake/make_dist.cmake.in b/cmake/make_dist.cmake.in index 8a219ac7ddc27..4a19486a1417c 100644 --- a/cmake/make_dist.cmake.in +++ b/cmake/make_dist.cmake.in @@ -141,12 +141,6 @@ IF(MYSQL_DOCS_LOCATION) EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} -E copy_directory "${MYSQL_DOCS_LOCATION}" "${PACKAGE_DIR}") ENDIF() -# Ensure there is an "INFO_SRC" file. -INCLUDE(${CMAKE_BINARY_DIR}/info_macros.cmake) -IF(NOT EXISTS ${PACKAGE_DIR}/Docs/INFO_SRC) - CREATE_INFO_SRC(${PACKAGE_DIR}/Docs) -ENDIF() - INCLUDE(${CMAKE_SOURCE_DIR}/cmake/generate_submodule_info.cmake) GENERATE_SUBMODULE_INFO(${PACKAGE_DIR}/cmake/submodule_info.cmake) diff --git a/cmake/mariadb_connector_c.cmake b/cmake/mariadb_connector_c.cmake index 86e7d5612e20e..859f96a8dcccc 100644 --- a/cmake/mariadb_connector_c.cmake +++ b/cmake/mariadb_connector_c.cmake @@ -7,12 +7,7 @@ ENDIF() SET(CONC_WITH_SIGNCODE ${SIGNCODE}) SET(SIGN_OPTIONS ${SIGNTOOL_PARAMETERS}) SET(CONC_WITH_EXTERNAL_ZLIB ON) -SET(CLIENT_PLUGIN_PARSEC OFF) -CHECK_INCLUDE_FILES (threads.h HAVE_THREADS_H) -IF(HAVE_THREADS_H) -SET(CLIENT_PLUGIN_PARSEC DYNAMIC) -ENDIF() IF(NOT CONC_WITH_SSL) IF(SSL_DEFINES MATCHES "WOLFSSL") diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 08353e9236ad3..9ebab4e66fee0 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -8,7 +8,6 @@ MACRO(BUNDLE_PCRE2) "Which pcre to use (possible values are 'bundled', 'system', or 'auto')") SET(dir "${CMAKE_BINARY_DIR}/extra/pcre2") - SET(PCRE_INCLUDE_DIRS ${dir}/src/pcre2-build ${dir}/src/pcre2/src) MESSAGE(STATUS "Will download and bundle pcre2") SET(byproducts) FOREACH(lib pcre2-posix pcre2-8) @@ -43,6 +42,8 @@ MACRO(BUNDLE_PCRE2) ENDIF() SET(byproducts ${byproducts} BUILD_BYPRODUCTS ${file} ${file_d}) SET_TARGET_PROPERTIES(${lib} PROPERTIES IMPORTED_LOCATION ${file}) + MAKE_DIRECTORY(${dir}/src/pcre2-build/interface) + TARGET_INCLUDE_DIRECTORIES(${lib} INTERFACE ${dir}/src/pcre2-build/interface) ENDFOREACH() FOREACH(v "" "_DEBUG" "_RELWITHDEBINFO" "_RELEASE" "_MINSIZEREL") @@ -64,8 +65,8 @@ MACRO(BUNDLE_PCRE2) ExternalProject_Add( pcre2 PREFIX "${dir}" - URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.45/pcre2-10.45.zip" - URL_MD5 873da56c6469ec207ca5c5ae9688b83a + URL "https://github.com/PCRE2Project/pcre2/releases/download/pcre2-10.47/pcre2-10.47.zip" + URL_MD5 7906aec38f872b74f1b925122dde9069 INSTALL_COMMAND "" CMAKE_ARGS "-DCMAKE_WARN_DEPRECATED=FALSE" diff --git a/cmake/ssl.cmake b/cmake/ssl.cmake index b72f959828ff3..6d6e0de4f873a 100644 --- a/cmake/ssl.cmake +++ b/cmake/ssl.cmake @@ -53,7 +53,6 @@ MACRO (MYSQL_USE_BUNDLED_SSL) SET(HAVE_ERR_remove_thread_state ON CACHE INTERNAL "wolfssl doesn't have ERR_remove_thread_state") SET(HAVE_EncryptAes128Ctr ON CACHE INTERNAL "wolfssl does support AES-CTR") SET(HAVE_EncryptAes128Gcm OFF CACHE INTERNAL "wolfssl does not support AES-GCM") - SET(HAVE_des ON CACHE INTERNAL "wolfssl does support DES API") SET(HAVE_evp_pkey ON CACHE INTERNAL "wolfssl does support EVP_PKEY API") SET(HAVE_hkdf ON CACHE INTERNAL "wolfssl does support EVP_PKEY_HKDF API") CHANGE_SSL_SETTINGS("bundled") @@ -136,8 +135,6 @@ MACRO (MYSQL_CHECK_SSL) HAVE_EncryptAes128Ctr) CHECK_SYMBOL_EXISTS(EVP_aes_128_gcm "openssl/evp.h" HAVE_EncryptAes128Gcm) - CHECK_SYMBOL_EXISTS(DES_set_key_unchecked "openssl/des.h" - HAVE_des) CHECK_SYMBOL_EXISTS(EVP_PKEY_get_raw_public_key "openssl/evp.h" HAVE_evp_pkey) CHECK_SYMBOL_EXISTS(EVP_PKEY_CTX_set_hkdf_md "string.h;stdarg.h;openssl/kdf.h" diff --git a/cmake/systemd.cmake b/cmake/systemd.cmake index 6788cf0d295be..a825cd0cb6809 100644 --- a/cmake/systemd.cmake +++ b/cmake/systemd.cmake @@ -50,8 +50,7 @@ MACRO(CHECK_SYSTEMD) SET(SYSTEMD_SCRIPTS ${SYSTEMD_SCRIPTS} galera_recovery) ENDIF() IF(DEB) - SET(SYSTEMD_EXECSTARTPRE "ExecStartPre=+/usr/bin/install -m 755 -o mysql -g root -d /var/run/mysqld") - SET(SYSTEMD_EXECSTARTPOST "ExecStartPost=+/etc/mysql/debian-start") + SET(SYSTEMD_EXECSTARTPOST "ExecStartPost=!/etc/mysql/debian-start") ENDIF() IF(URING_FOUND) SET(SYSTEMD_LIMIT "# For liburing and io_uring_setup() diff --git a/cmake/zlib.cmake b/cmake/zlib.cmake index a933194cd33e6..2a7043b325428 100644 --- a/cmake/zlib.cmake +++ b/cmake/zlib.cmake @@ -21,6 +21,11 @@ MACRO (MYSQL_USE_BUNDLED_ZLIB) SET(ZLIB_LIBRARY ${ZLIB_LIBRARIES}) SET(ZLIB_INCLUDE_DIR ${ZLIB_INCLUDE_DIRS}) SET(ZLIB_FOUND TRUE) + IF(VCPKG_INSTALLED_DIR) + # Avoid errors in vcpkg's FIND_PACKAGE + # for packages dependend on zlib + SET(CMAKE_DISABLE_FIND_PACKAGE_ZLIB 1) + ENDIF() SET(WITH_ZLIB "bundled" CACHE STRING "Use bundled zlib") ADD_SUBDIRECTORY(zlib) ENDMACRO() diff --git a/config.h.cmake b/config.h.cmake index cf3c1afe4eddd..903d2d837b755 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -493,7 +493,6 @@ this is the case with Microsoft Windows VirtualFree(MEM_DECOMMIT) */ #cmakedefine HAVE_COMPRESS 1 #cmakedefine HAVE_EncryptAes128Ctr 1 #cmakedefine HAVE_EncryptAes128Gcm 1 -#cmakedefine HAVE_des 1 #cmakedefine HAVE_hkdf 1 /* diff --git a/debian/additions/mariadb.conf.d/50-server.cnf b/debian/additions/mariadb.conf.d/50-server.cnf index 32d65931f6186..6f3abfc668469 100644 --- a/debian/additions/mariadb.conf.d/50-server.cnf +++ b/debian/additions/mariadb.conf.d/50-server.cnf @@ -110,7 +110,7 @@ expire_logs_days = 10 # you can put MariaDB-only options here [mariadbd] -# This group is only read by MariaDB-12.0 servers. +# This group is only read by MariaDB servers of the specific version. # If you use the same .cnf file for MariaDB of different versions, # use this group for options that older servers don't understand -[mariadb-12.0] +[mariadb-13.0] diff --git a/debian/autobake-deb.sh b/debian/autobake-deb.sh index 55bffa79f9613..0d7505041c616 100755 --- a/debian/autobake-deb.sh +++ b/debian/autobake-deb.sh @@ -109,7 +109,7 @@ in remove_uring fi ;& - "trixie"|"forky"|"sid") + "trixie"|"forky"|"duke"|"sid") # The default packaging should always target Debian Sid, so in this case # there is intentionally no customizations whatsoever. ;; @@ -128,7 +128,7 @@ in replace_uring_with_aio fi ;& - "noble"|"oracular"|"plucky"|"questing") + "noble"|"oracular"|"plucky"|"questing"|"resolute") # mariadb-plugin-rocksdb s390x not supported by us (yet) # ubuntu doesn't support mips64el yet, so keep this just # in case something changes. diff --git a/debian/changelog b/debian/changelog index 45c6112e36a2a..83d25e5a15bd6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,5 +1,5 @@ -mariadb (1:12.0.0) unstable; urgency=medium +mariadb (1:13.0.0) unstable; urgency=medium * Initial Release - -- Sergei Golubchik Tue Aug 20 08:40:21 CEST 2024 + -- Sergei Golubchik Wed Feb 11 11:24:57 CET 2026 diff --git a/debian/control b/debian/control index 7300d3296e9d2..eb73631d68cc5 100644 --- a/debian/control +++ b/debian/control @@ -2,54 +2,55 @@ Source: mariadb Section: database Priority: optional Maintainer: MariaDB Developers -Build-Depends: bison, - cmake, - cracklib-runtime , - debhelper (>= 11), - default-jdk, - dh-exec, - dh-package-notes, - flex [amd64 arm64], - gdb , - libaio-dev [linux-any], - libboost-atomic-dev [amd64 arm64], - libboost-chrono-dev [amd64 arm64], - libboost-date-time-dev [amd64 arm64], - libboost-dev, - libboost-filesystem-dev [amd64 arm64], - libboost-regex-dev [amd64 arm64], - libboost-system-dev [amd64 arm64], - libboost-thread-dev [amd64 arm64], - libbz2-dev, - libcrack2-dev (>= 2.9.0), - libcurl4-openssl-dev | libcurl4-dev, - libedit-dev, - libedit-dev:native, - libfmt-dev (>= 7.0.0), - libjemalloc-dev [linux-any], - libjudy-dev, - libkrb5-dev, - liblz4-dev, - liblzma-dev, - liblzo2-dev, - libncurses-dev, - libnuma-dev [linux-any], - libpam0g-dev, - libpcre2-dev, - libsnappy-dev, - libssl-dev, - libssl-dev:native, - libsystemd-dev [linux-any], - liburing-dev [linux-any], - libxml2-dev, - libzstd-dev (>= 1.1.3), - lsb-release, - perl:any, - po-debconf, - psmisc, - unixodbc-dev, - uuid-dev, - zlib1g-dev (>= 1:1.1.3-5~) +Build-Depends: + debhelper (>= 11), + dh-exec, + dh-package-notes, + bison, + cmake, + cracklib-runtime , + default-jdk, + flex [amd64 arm64], + gdb , + libaio-dev [linux-any], + libboost-atomic-dev [amd64 arm64], + libboost-chrono-dev [amd64 arm64], + libboost-date-time-dev [amd64 arm64], + libboost-dev, + libboost-filesystem-dev [amd64 arm64], + libboost-regex-dev [amd64 arm64], + libboost-system-dev [amd64 arm64], + libboost-thread-dev [amd64 arm64], + libbz2-dev, + libcrack2-dev (>= 2.9.0), + libcurl4-openssl-dev | libcurl4-dev, + libedit-dev, + libedit-dev:native, + libfmt-dev (>= 7.0.0), + libjemalloc-dev [linux-any], + libjudy-dev, + libkrb5-dev, + liblz4-dev, + liblzma-dev, + liblzo2-dev, + libncurses-dev, + libnuma-dev [linux-any], + libpam0g-dev, + libpcre2-dev, + libsnappy-dev, + libssl-dev, + libssl-dev:native, + libsystemd-dev [linux-any], + liburing-dev [linux-any], + libxml2-dev, + libzstd-dev (>= 1.1.3), + lsb-release, + perl:any, + po-debconf, + psmisc, + unixodbc-dev, + uuid-dev, + zlib1g-dev (>= 1:1.1.3-5~), Rules-Requires-Root: no Standards-Version: 4.5.0 Homepage: https://mariadb.org/ @@ -59,23 +60,28 @@ Vcs-Git: https://github.com/MariaDB/server.git Package: libmariadb-dev Architecture: any Section: libdevel -Depends: libmariadb3 (= ${binary:Version}), - libssl-dev, - zlib1g-dev, - ${misc:Depends}, - ${shlibs:Depends} -Conflicts: libmariadb-dev-compat (<< 3.0.0), - libmariadbclient-dev, - libmariadbclient16-dev -Provides: libmariadbclient-dev -Breaks: libmariadb-client-lgpl-dev, - libmysqlclient-dev (<< ${source:Version}), - libmysqld-dev (<< ${source:Version}) -Replaces: libmariadb-client-lgpl-dev, - libmariadb-dev-compat (<< 3.0.0), - libmariadbclient-dev, - libmysqlclient-dev (<< ${source:Version}), - libmysqld-dev (<< ${source:Version}) +Depends: + libmariadb3 (= ${binary:Version}), + libssl-dev, + zlib1g-dev, + ${misc:Depends}, + ${shlibs:Depends}, +Conflicts: + libmariadb-dev-compat (<< 3.0.0), + libmariadbclient-dev, + libmariadbclient16-dev, +Provides: + libmariadbclient-dev, +Breaks: + libmariadb-client-lgpl-dev, + libmysqlclient-dev (<< ${source:Version}), + libmysqld-dev (<< ${source:Version}), +Replaces: + libmariadb-client-lgpl-dev, + libmariadb-dev-compat (<< 3.0.0), + libmariadbclient-dev, + libmysqlclient-dev (<< ${source:Version}), + libmysqld-dev (<< ${source:Version}), Description: MariaDB database development files MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -89,28 +95,33 @@ Description: MariaDB database development files Package: libmariadb-dev-compat Architecture: any Section: libdevel -Depends: libmariadb-dev (= ${binary:Version}), - ${misc:Depends} -Conflicts: libmariadb-client-lgpl-dev, - libmariadb-client-lgpl-dev-compat, - libmariadbclient-dev (<< ${source:Version}), - libmariadbclient-dev-compat, - libmysqlclient-dev, - libmysqlclient10-dev, - libmysqlclient12-dev, - libmysqlclient14-dev, - libmysqlclient15-dev, - libmysqlclient16-dev -Provides: libmariadb-client-lgpl-dev-compat, - libmariadbclient-dev-compat, - libmysqlclient-dev -Breaks: libmariadb-dev (<< ${source:Version}) -Replaces: libmariadb-client-lgpl-dev, - libmariadb-client-lgpl-dev-compat, - libmariadb-dev (<< ${source:Version}), - libmariadbclient-dev (<< ${source:Version}), - libmariadbclient-dev-compat, - libmysqlclient-dev +Depends: + libmariadb-dev (= ${binary:Version}), + ${misc:Depends}, +Conflicts: + libmariadb-client-lgpl-dev, + libmariadb-client-lgpl-dev-compat, + libmariadbclient-dev (<< ${source:Version}), + libmariadbclient-dev-compat, + libmysqlclient-dev, + libmysqlclient10-dev, + libmysqlclient12-dev, + libmysqlclient14-dev, + libmysqlclient15-dev, + libmysqlclient16-dev, +Provides: + libmariadb-client-lgpl-dev-compat, + libmariadbclient-dev-compat, + libmysqlclient-dev, +Breaks: + libmariadb-dev (<< ${source:Version}), +Replaces: + libmariadb-client-lgpl-dev, + libmariadb-client-lgpl-dev-compat, + libmariadb-dev (<< ${source:Version}), + libmariadbclient-dev (<< ${source:Version}), + libmariadbclient-dev-compat, + libmysqlclient-dev, Description: MariaDB Connector/C, compatibility symlinks MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -124,19 +135,23 @@ Package: libmariadb3 Architecture: any Multi-Arch: same Section: libs -Depends: mariadb-common, - ${misc:Depends}, - ${shlibs:Depends} -Conflicts: libmariadbclient18 (<< 10.2.0), - mariadb-galera-server-10.0, - mariadb-galera-server-5.5, - mariadb-server-10.0, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5 -Breaks: libmariadbclient18 (<< ${source:Version}) -Replaces: libmariadbclient18 (<< ${source:Version}) +Depends: + mariadb-common, + ${misc:Depends}, + ${shlibs:Depends}, +Conflicts: + libmariadbclient18 (<< 10.2.0), + mariadb-galera-server-10.0, + mariadb-galera-server-5.5, + mariadb-server-10.0, + mariadb-server-5.1, + mariadb-server-5.2, + mariadb-server-5.3, + mariadb-server-5.5, +Breaks: + libmariadbclient18 (<< ${source:Version}), +Replaces: + libmariadbclient18 (<< ${source:Version}), Description: MariaDB database client library MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -148,18 +163,22 @@ Description: MariaDB database client library Package: libmariadb3-compat Architecture: any Section: libs -Depends: libmariadb3, - mariadb-common, - ${misc:Depends} -Breaks: libmysqlclient19, - libmysqlclient20, - libmysqlclient21 -Replaces: libmysqlclient19, - libmysqlclient20, - libmysqlclient21 -Provides: libmysqlclient19, - libmysqlclient20, - libmysqlclient21 +Depends: + libmariadb3, + mariadb-common, + ${misc:Depends}, +Breaks: + libmysqlclient19, + libmysqlclient20, + libmysqlclient21, +Replaces: + libmysqlclient19, + libmysqlclient20, + libmysqlclient21, +Provides: + libmysqlclient19, + libmysqlclient20, + libmysqlclient21, Description: MariaDB database client library MySQL compat package MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -172,10 +191,13 @@ Description: MariaDB database client library MySQL compat package Package: libmariadbclient18 Section: libs Architecture: any -Depends: libmariadb3 (= ${binary:Version}), - ${misc:Depends} -Replaces: libmariadbclient18 -Provides: libmariadbclient18 +Depends: + libmariadb3 (= ${binary:Version}), + ${misc:Depends}, +Replaces: + libmariadbclient18, +Provides: + libmariadbclient18, Description: Virtual package to satisfy external libmariadbclient18 depends MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -188,10 +210,13 @@ Description: Virtual package to satisfy external libmariadbclient18 depends Package: libmysqlclient18 Section: libs Architecture: any -Depends: libmariadb3 (= ${binary:Version}), - ${misc:Depends} -Replaces: libmysqlclient18 -Provides: libmysqlclient18 +Depends: + libmariadb3 (= ${binary:Version}), + ${misc:Depends}, +Replaces: + libmysqlclient18, +Provides: + libmysqlclient18, Description: Virtual package to satisfy external libmysqlclient18 depends MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -204,11 +229,15 @@ Description: Virtual package to satisfy external libmysqlclient18 depends Package: libmariadbd19 Architecture: any Section: libs -Depends: ${misc:Depends}, - ${shlibs:Depends} -Breaks: libmariadbd-dev (<< ${source:Version}) -Conflicts: libmariadbd19t64 -Replaces: libmariadbd-dev (<< ${source:Version}) +Depends: + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + libmariadbd-dev (<< ${source:Version}), +Conflicts: + libmariadbd19t64, +Replaces: + libmariadbd-dev (<< ${source:Version}), Multi-Arch: same Description: MariaDB embedded database, shared library MariaDB is a fast, stable and true multi-user, multi-threaded SQL database @@ -221,17 +250,22 @@ Description: MariaDB embedded database, shared library Package: libmariadbd-dev Architecture: any Section: libdevel -Provides: libmysqld-dev -Pre-Depends: ${misc:Pre-Depends} -Depends: libmariadb-dev (= ${binary:Version}), - libmariadbd19 (= ${binary:Version}), - ${misc:Depends} -Breaks: libmariadb-dev (<< ${source:Version}), - libmariadbclient-dev (<< ${source:Version}), - libmysqld-dev -Replaces: libmariadb-dev (<< ${source:Version}), - libmariadbclient-dev (<< ${source:Version}), - libmysqld-dev +Provides: + libmysqld-dev, +Pre-Depends: + ${misc:Pre-Depends}, +Depends: + libmariadb-dev (= ${binary:Version}), + libmariadbd19 (= ${binary:Version}), + ${misc:Depends}, +Breaks: + libmariadb-dev (<< ${source:Version}), + libmariadbclient-dev (<< ${source:Version}), + libmysqld-dev, +Replaces: + libmariadb-dev (<< ${source:Version}), + libmariadbclient-dev (<< ${source:Version}), + libmysqld-dev, Description: MariaDB embedded database, development files package MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -243,7 +277,8 @@ Description: MariaDB embedded database, development files package Package: mysql-common Architecture: all -Depends: ${misc:Depends} +Depends: + ${misc:Depends}, Description: MariaDB client common configuration files package (e.g. /etc/mysql/my.cnf) MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -255,8 +290,9 @@ Description: MariaDB client common configuration files package (e.g. /etc/mysql/ Package: mariadb-common Architecture: all -Depends: mysql-common (>= 5.6.25), - ${misc:Depends} +Depends: + mysql-common (>= 5.6.25), + ${misc:Depends}, Multi-Arch: foreign Description: MariaDB database common files (e.g. /etc/mysql/mariadb.conf.d/) MariaDB is a fast, stable and true multi-user, multi-threaded SQL database @@ -268,132 +304,137 @@ Description: MariaDB database common files (e.g. /etc/mysql/mariadb.conf.d/) Package: mariadb-client-core Architecture: any -Depends: libmariadb3 (>= 10.5.4), - mariadb-common (>= ${source:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Conflicts: mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-client-core-5.1, - mariadb-client-core-5.2, - mariadb-client-core-5.3, - mariadb-client-core-5.5, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - virtual-mysql-client-core -Breaks: mariadb-client (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-cluster-community-client-plugins, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-server-server-5.7, - percona-server-server-8.0, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - percona-xtradb-cluster-server-8.0 -Replaces: mariadb-client (<< ${source:Version}), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-client-core-5.1, - mariadb-client-core-5.2, - mariadb-client-core-5.3, - mariadb-client-core-5.5, - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mysql-cluster-community-client-plugins, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-server-server-5.7, - percona-server-server-8.0, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - percona-xtradb-cluster-server-8.0, - virtual-mysql-client-core -Provides: default-mysql-client-core, - virtual-mysql-client-core +Depends: + libmariadb3 (>= 10.5.4), + mariadb-common (>= ${source:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Conflicts: + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-client-5.1, + mariadb-client-5.2, + mariadb-client-5.3, + mariadb-client-5.5, + mariadb-client-core-10.0, + mariadb-client-core-10.1, + mariadb-client-core-10.2, + mariadb-client-core-10.3, + mariadb-client-core-10.4, + mariadb-client-core-10.5, + mariadb-client-core-10.6, + mariadb-client-core-10.7, + mariadb-client-core-10.8, + mariadb-client-core-5.1, + mariadb-client-core-5.2, + mariadb-client-core-5.3, + mariadb-client-core-5.5, + mysql-client (<< 5.0.51), + mysql-client-5.0, + mysql-client-5.1, + mysql-client-5.5, + mysql-client-core-5.1, + mysql-client-core-5.5, + mysql-client-core-5.6, + mysql-client-core-5.7, + mysql-client-core-8.0, + virtual-mysql-client-core, +Breaks: + mariadb-client (<< ${source:Version}), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-core (<< ${source:Version}), + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mysql-cluster-community-client-plugins, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + percona-server-server-5.6, + percona-server-server-5.7, + percona-server-server-8.0, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, + percona-xtradb-cluster-server-8.0, +Replaces: + mariadb-client (<< ${source:Version}), + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-client-5.1, + mariadb-client-5.2, + mariadb-client-5.3, + mariadb-client-5.5, + mariadb-client-core-10.0, + mariadb-client-core-10.1, + mariadb-client-core-10.2, + mariadb-client-core-10.3, + mariadb-client-core-10.4, + mariadb-client-core-10.5, + mariadb-client-core-10.6, + mariadb-client-core-10.7, + mariadb-client-core-10.8, + mariadb-client-core-5.1, + mariadb-client-core-5.2, + mariadb-client-core-5.3, + mariadb-client-core-5.5, + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-core (<< ${source:Version}), + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mysql-client (<< 5.0.51), + mysql-client-5.0, + mysql-client-5.1, + mysql-client-5.5, + mysql-client-core-5.1, + mysql-client-core-5.5, + mysql-client-core-5.6, + mysql-client-core-5.7, + mysql-client-core-8.0, + mysql-cluster-community-client-plugins, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + percona-server-server-5.6, + percona-server-server-5.7, + percona-server-server-8.0, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, + percona-xtradb-cluster-server-8.0, + virtual-mysql-client-core, +Provides: + default-mysql-client-core, + virtual-mysql-client-core, Description: MariaDB database core client binaries MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -404,157 +445,163 @@ Description: MariaDB database core client binaries Package: mariadb-client Architecture: any -Depends: debianutils (>=1.6), - libconfig-inifiles-perl, - mariadb-client-core (>= ${source:Version}), - mariadb-common, - ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} -Conflicts: mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-5.0, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mytop, - virtual-mysql-client -Breaks: mariadb-client-core (<< ${source:Version}), - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 -Replaces: mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core (<< ${source:Version}), - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core (<< ${source:Version}), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-5.0, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - mytop, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-client -Provides: default-mysql-client, - virtual-mysql-client -Recommends: libdbd-mariadb-perl | libdbd-mysql-perl, - libdbi-perl, - libterm-readkey-perl, - mariadb-client-compat +Depends: + debianutils (>=1.6), + libconfig-inifiles-perl, + mariadb-client-core (>= ${source:Version}), + mariadb-common, + ${misc:Depends}, + ${perl:Depends}, + ${shlibs:Depends}, +Conflicts: + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-client-5.1, + mariadb-client-5.2, + mariadb-client-5.3, + mariadb-client-5.5, + mysql-client (<< 5.0.51), + mysql-client-5.0, + mysql-client-5.1, + mysql-client-5.5, + mysql-client-5.6, + mysql-client-5.7, + mysql-client-8.0, + mysql-client-core-5.0, + mysql-client-core-5.1, + mysql-client-core-5.5, + mysql-client-core-5.6, + mysql-client-core-5.7, + mysql-client-core-8.0, + mytop, + virtual-mysql-client, +Breaks: + mariadb-client-core (<< ${source:Version}), + mariadb-client-core-10.0, + mariadb-client-core-10.1, + mariadb-client-core-10.2, + mariadb-client-core-10.3, + mariadb-client-core-10.4, + mariadb-client-core-10.5, + mariadb-client-core-10.6, + mariadb-client-core-10.7, + mariadb-client-core-10.8, + mariadb-server (<< ${source:Version}), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-core (<< ${source:Version}), + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mysql-server-5.5, + mysql-server-5.6, + mysql-server-5.7, + mysql-server-8.0, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, +Replaces: + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-client-5.1, + mariadb-client-5.2, + mariadb-client-5.3, + mariadb-client-5.5, + mariadb-client-core (<< ${source:Version}), + mariadb-client-core-10.0, + mariadb-client-core-10.1, + mariadb-client-core-10.2, + mariadb-client-core-10.3, + mariadb-client-core-10.4, + mariadb-client-core-10.5, + mariadb-client-core-10.6, + mariadb-client-core-10.7, + mariadb-client-core-10.8, + mariadb-server (<< ${source:Version}), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-core (<< ${source:Version}), + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mysql-client (<< 5.0.51), + mysql-client-5.0, + mysql-client-5.1, + mysql-client-5.5, + mysql-client-5.6, + mysql-client-5.7, + mysql-client-8.0, + mysql-client-core-5.0, + mysql-client-core-5.1, + mysql-client-core-5.5, + mysql-client-core-5.6, + mysql-client-core-5.7, + mysql-client-core-8.0, + mysql-server-5.5, + mysql-server-5.6, + mysql-server-5.7, + mysql-server-8.0, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + mytop, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, + virtual-mysql-client, +Provides: + default-mysql-client, + virtual-mysql-client, +Recommends: + libdbd-mariadb-perl | libdbd-mysql-perl, + libdbi-perl, + libterm-readkey-perl, + mariadb-client-compat, Description: MariaDB database client binaries MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -566,75 +613,77 @@ Description: MariaDB database client binaries Package: mariadb-client-compat Architecture: all -Depends: mariadb-client (>= ${source:Version}) -Conflicts: mariadb-client (<< 11.0.0), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-client-5.1, - mariadb-client-5.2, - mariadb-client-5.3, - mariadb-client-5.5, - mariadb-client-core (<< 11.0.0), - mariadb-client-core-10.0, - mariadb-client-core-10.1, - mariadb-client-core-10.2, - mariadb-client-core-10.3, - mariadb-client-core-10.4, - mariadb-client-core-10.5, - mariadb-client-core-10.6, - mariadb-client-core-10.7, - mariadb-client-core-10.8, - mariadb-client-core-5.1, - mariadb-client-core-5.2, - mariadb-client-core-5.3, - mariadb-client-core-5.5, - mariadb-server (<< 11.0.0), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core (<< 11.0.0), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mysql-client (<< 5.0.51), - mysql-client-5.0, - mysql-client-5.1, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-5.0, - mysql-client-core-5.1, - mysql-client-core-5.5, - mysql-client-core-5.6, - mysql-client-core-5.7, - mysql-client-core-8.0, - mysql-server-5.7, - mysql-server-core-8.0, - percona-server-server, - percona-server-server-5.6, - percona-xtradb-cluster-server, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 +Depends: + mariadb-client (>= ${source:Version}), +Conflicts: + mariadb-client (<< 11.0.0), + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-client-5.1, + mariadb-client-5.2, + mariadb-client-5.3, + mariadb-client-5.5, + mariadb-client-core (<< 11.0.0), + mariadb-client-core-10.0, + mariadb-client-core-10.1, + mariadb-client-core-10.2, + mariadb-client-core-10.3, + mariadb-client-core-10.4, + mariadb-client-core-10.5, + mariadb-client-core-10.6, + mariadb-client-core-10.7, + mariadb-client-core-10.8, + mariadb-client-core-5.1, + mariadb-client-core-5.2, + mariadb-client-core-5.3, + mariadb-client-core-5.5, + mariadb-server (<< 11.0.0), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-core (<< 11.0.0), + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mysql-client (<< 5.0.51), + mysql-client-5.0, + mysql-client-5.1, + mysql-client-5.5, + mysql-client-5.6, + mysql-client-5.7, + mysql-client-8.0, + mysql-client-core-5.0, + mysql-client-core-5.1, + mysql-client-core-5.5, + mysql-client-core-5.6, + mysql-client-core-5.7, + mysql-client-core-8.0, + mysql-server-5.7, + mysql-server-core-8.0, + percona-server-server, + percona-server-server-5.6, + percona-xtradb-cluster-server, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, Multi-Arch: foreign Description: MySQL compatibility links to mariadb-client binaries/scripts. The package contains links and binaries that are needed by MySQL centric @@ -645,106 +694,111 @@ Description: MySQL compatibility links to mariadb-client binaries/scripts. Package: mariadb-server-core Architecture: any -Depends: mariadb-common (>= ${source:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Conflicts: mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mariadb-server-core-5.1, - mariadb-server-core-5.2, - mariadb-server-core-5.3, - mariadb-server-core-5.5, - mysql-server-5.0, - mysql-server-core-5.0, - mysql-server-core-5.1, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - virtual-mysql-server-core -Breaks: mariadb-client (<< ${source:Version}), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mysql-client-5.5, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 -Replaces: mariadb-client (<< ${source:Version}), - mariadb-client-10.0, - mariadb-client-10.1, - mariadb-client-10.2, - mariadb-client-10.3, - mariadb-client-10.4, - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-server (<< ${source:Version}), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-5.1, - mariadb-server-core-5.2, - mariadb-server-core-5.3, - mariadb-server-core-5.5, - mysql-client-5.5, - mysql-server-5.0, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.0, - mysql-server-core-5.1, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-server-core -Provides: default-mysql-server-core, - virtual-mysql-server-core +Depends: + mariadb-common (>= ${source:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Conflicts: + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mariadb-server-core-5.1, + mariadb-server-core-5.2, + mariadb-server-core-5.3, + mariadb-server-core-5.5, + mysql-server-5.0, + mysql-server-core-5.0, + mysql-server-core-5.1, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + virtual-mysql-server-core, +Breaks: + mariadb-client (<< ${source:Version}), + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-server (<< ${source:Version}), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mysql-client-5.5, + mysql-server-5.5, + mysql-server-5.6, + mysql-server-5.7, + mysql-server-8.0, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, +Replaces: + mariadb-client (<< ${source:Version}), + mariadb-client-10.0, + mariadb-client-10.1, + mariadb-client-10.2, + mariadb-client-10.3, + mariadb-client-10.4, + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-server (<< ${source:Version}), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-5.1, + mariadb-server-core-5.2, + mariadb-server-core-5.3, + mariadb-server-core-5.5, + mysql-client-5.5, + mysql-server-5.0, + mysql-server-5.5, + mysql-server-5.6, + mysql-server-5.7, + mysql-server-8.0, + mysql-server-core-5.0, + mysql-server-core-5.1, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, + virtual-mysql-server-core, +Provides: + default-mysql-server-core, + virtual-mysql-server-core, Description: MariaDB database core server files MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -755,106 +809,107 @@ Description: MariaDB database core server files Package: mariadb-server Architecture: any -Suggests: mailx, - mariadb-test, - netcat-openbsd -Recommends: libhtml-template-perl, - mariadb-server-compat, - pv -Pre-Depends: adduser (>= 3.40), - debconf, - mariadb-common (>= ${source:Version}) -Depends: galera-4 (>= 26.4), - gawk, - iproute2 [linux-any], - libdbi-perl, - lsof [linux-any], - mariadb-client (>= ${source:Version}), - mariadb-server-core (>= ${source:Version}), - passwd, - perl (>= 5.6), - procps, - psmisc, - rsync, - socat, - ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} -Conflicts: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-8.0, - mysql-server, - mysql-server-4.1, - mysql-server-5.0, - mysql-server-5.1, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - virtual-mysql-server -Breaks: handlersocket-mysql-5.5, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 -Replaces: handlersocket-mysql-5.5, - libmariadbclient-dev (<< 5.5.0), - libmariadbclient16, - mariadb-client (<< ${source:Version}), - mariadb-client-10.5, - mariadb-client-10.6, - mariadb-client-10.7, - mariadb-client-10.8, - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5, - mysql-client-5.5, - mysql-client-5.6, - mysql-client-5.7, - mysql-client-8.0, - mysql-client-core-8.0, - mysql-server, - mysql-server-4.1, - mysql-server-5.0, - mysql-server-5.1, - mysql-server-5.5, - mysql-server-5.6, - mysql-server-5.7, - mysql-server-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-server -Provides: default-mysql-server, - virtual-mysql-server +Suggests: + mailx, + mariadb-test, + netcat-openbsd, +Recommends: + libhtml-template-perl, + mariadb-server-compat, +Pre-Depends: + adduser (>= 3.40), + debconf, + mariadb-common (>= ${source:Version}), +Depends: + libdbi-perl, + mariadb-client (>= ${source:Version}), + mariadb-server-core (>= ${source:Version}), + passwd, + perl (>= 5.6), + procps, + psmisc, + ${misc:Depends}, + ${perl:Depends}, + ${shlibs:Depends}, +Conflicts: + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-5.1, + mariadb-server-5.2, + mariadb-server-5.3, + mariadb-server-5.5, + mysql-client-5.5, + mysql-client-5.6, + mysql-client-5.7, + mysql-client-8.0, + mysql-client-core-8.0, + mysql-server, + mysql-server-4.1, + mysql-server-5.0, + mysql-server-5.1, + mysql-server-5.5, + mysql-server-5.6, + mysql-server-5.7, + mysql-server-8.0, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + virtual-mysql-server, +Breaks: + handlersocket-mysql-5.5, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, +Replaces: + handlersocket-mysql-5.5, + libmariadbclient-dev (<< 5.5.0), + libmariadbclient16, + mariadb-client (<< ${source:Version}), + mariadb-client-10.5, + mariadb-client-10.6, + mariadb-client-10.7, + mariadb-client-10.8, + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-5.1, + mariadb-server-5.2, + mariadb-server-5.3, + mariadb-server-5.5, + mysql-client-5.5, + mysql-client-5.6, + mysql-client-5.7, + mysql-client-8.0, + mysql-client-core-8.0, + mysql-server, + mysql-server-4.1, + mysql-server-5.0, + mysql-server-5.1, + mysql-server-5.5, + mysql-server-5.6, + mysql-server-5.7, + mysql-server-8.0, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, + virtual-mysql-server, +Provides: + default-mysql-server, + virtual-mysql-server, Description: MariaDB database server binaries MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -865,48 +920,50 @@ Description: MariaDB database server binaries Package: mariadb-server-compat Architecture: all -Depends: mariadb-server (>= ${source:Version}) -Conflicts: mariadb-server (<< 11.0.0), - mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4, - mariadb-server-10.5, - mariadb-server-10.6, - mariadb-server-10.7, - mariadb-server-10.8, - mariadb-server-5.1, - mariadb-server-5.2, - mariadb-server-5.3, - mariadb-server-5.5, - mariadb-server-core (<< 11.0.0), - mariadb-server-core-10.0, - mariadb-server-core-10.1, - mariadb-server-core-10.2, - mariadb-server-core-10.3, - mariadb-server-core-10.4, - mariadb-server-core-10.5, - mariadb-server-core-10.6, - mariadb-server-core-10.7, - mariadb-server-core-10.8, - mariadb-server-core-5.1, - mariadb-server-core-5.2, - mariadb-server-core-5.3, - mariadb-server-core-5.5, - mysql-server-5.0, - mysql-server-core-5.0, - mysql-server-core-5.1, - mysql-server-core-5.5, - mysql-server-core-5.6, - mysql-server-core-5.7, - mysql-server-core-8.0, - percona-server-server, - percona-server-server-5.6, - percona-server-server-5.7, - percona-xtradb-cluster-server, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 +Depends: + mariadb-server (>= ${source:Version}), +Conflicts: + mariadb-server (<< 11.0.0), + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, + mariadb-server-10.5, + mariadb-server-10.6, + mariadb-server-10.7, + mariadb-server-10.8, + mariadb-server-5.1, + mariadb-server-5.2, + mariadb-server-5.3, + mariadb-server-5.5, + mariadb-server-core (<< 11.0.0), + mariadb-server-core-10.0, + mariadb-server-core-10.1, + mariadb-server-core-10.2, + mariadb-server-core-10.3, + mariadb-server-core-10.4, + mariadb-server-core-10.5, + mariadb-server-core-10.6, + mariadb-server-core-10.7, + mariadb-server-core-10.8, + mariadb-server-core-5.1, + mariadb-server-core-5.2, + mariadb-server-core-5.3, + mariadb-server-core-5.5, + mysql-server-5.0, + mysql-server-core-5.0, + mysql-server-core-5.1, + mysql-server-core-5.5, + mysql-server-core-5.6, + mysql-server-core-5.7, + mysql-server-core-8.0, + percona-server-server, + percona-server-server-5.6, + percona-server-server-5.7, + percona-xtradb-cluster-server, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, Multi-Arch: foreign Description: MySQL compatibility links to mariadb-server binaries/scripts. The package contains links and binaries that are needed by MySQL centric @@ -917,17 +974,20 @@ Description: MySQL compatibility links to mariadb-server binaries/scripts. Package: mariadb-backup Architecture: any -Breaks: mariadb-backup-10.1, - mariadb-backup-10.2, - mariadb-backup-10.3, - mariadb-client-10.1 -Replaces: mariadb-backup-10.1, - mariadb-backup-10.2, - mariadb-backup-10.3, - mariadb-client-10.1 -Depends: mariadb-client-core (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends} +Breaks: + mariadb-backup-10.1, + mariadb-backup-10.2, + mariadb-backup-10.3, + mariadb-client-10.1, +Replaces: + mariadb-backup-10.1, + mariadb-backup-10.2, + mariadb-backup-10.3, + mariadb-client-10.1, +Depends: + mariadb-client-core (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, Description: Backup tool for MariaDB server Based on Xtrabackup, but improved to work with MariaDB server. This backup tool is guaranteed to be compatible with MariaDB server. @@ -937,27 +997,31 @@ Description: Backup tool for MariaDB server Package: mariadb-plugin-connect Architecture: any -Depends: libxml2, - mariadb-server (= ${server:Version}), - unixodbc, - ${misc:Depends}, - ${shlibs:Depends} -Recommends: curl -Breaks: mariadb-connect-engine-10.0, - mariadb-connect-engine-10.1, - mariadb-connect-engine-10.2, - mariadb-connect-engine-10.3, - mariadb-connect-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 -Replaces: mariadb-connect-engine-10.0, - mariadb-connect-engine-10.1, - mariadb-connect-engine-10.2, - mariadb-connect-engine-10.3, - mariadb-connect-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 -Suggests: mariadb-plugin-connect-jdbc +Depends: + mariadb-server (= ${server:Version}), + unixodbc, + ${misc:Depends}, + ${shlibs:Depends}, +Recommends: + curl, +Breaks: + mariadb-connect-engine-10.0, + mariadb-connect-engine-10.1, + mariadb-connect-engine-10.2, + mariadb-connect-engine-10.3, + mariadb-connect-engine-10.4, + mariadb-server-10.0, + mariadb-server-10.1, +Replaces: + mariadb-connect-engine-10.0, + mariadb-connect-engine-10.1, + mariadb-connect-engine-10.2, + mariadb-connect-engine-10.3, + mariadb-connect-engine-10.4, + mariadb-server-10.0, + mariadb-server-10.1, +Suggests: + mariadb-plugin-connect-jdbc, Description: Connect storage engine for MariaDB server Connect engine supports a number of file formats (dbf, xml, txt, bin, etc), connections to ODBC tables and remote MySQL tables, as well as a number of @@ -966,13 +1030,16 @@ Description: Connect storage engine for MariaDB server Package: mariadb-plugin-connect-jdbc Architecture: any -Depends: default-jre-headless -Suggests: libcsvjdbc-java, - libmariadb-java, - libpostgis-java, - libpostgresql-jdbc-java, - libxerial-sqlite-jdbc-java -Enhances: mariadb-plugin-connect +Depends: + default-jre-headless, +Suggests: + libcsvjdbc-java, + libmariadb-java, + libpostgis-java, + libpostgresql-jdbc-java, + libxerial-sqlite-jdbc-java, +Enhances: + mariadb-plugin-connect, Description: Connect storage engine JDBC interface for MariaDB server. To connect to remote DBMS using Connect Storage Engine (SE) and JDBC driver, there is need for JDBC interface byte code. @@ -981,10 +1048,10 @@ Description: Connect storage engine JDBC interface for MariaDB server. Package: mariadb-plugin-s3 Architecture: any -Depends: libcurl4, - mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server (= ${server:Version}), + ${misc:Depends}, + ${shlibs:Depends}, Description: Amazon S3 archival storage engine for MariaDB The S3 storage engine allows one to archive MariaDB tables in Amazon S3 (or any third-party public or private cloud that implements S3 API), but still have @@ -992,18 +1059,22 @@ Description: Amazon S3 archival storage engine for MariaDB Package: mariadb-plugin-rocksdb Architecture: amd64 arm64 mips64el ppc64el riscv64 -Depends: mariadb-server (= ${server:Version}), - python3:any, - rocksdb-tools, - ${misc:Depends}, - ${shlibs:Depends} -Breaks: mariadb-rocksdb-engine-10.2, - mariadb-rocksdb-engine-10.3, - mariadb-rocksdb-engine-10.4 -Replaces: mariadb-rocksdb-engine-10.2, - mariadb-rocksdb-engine-10.3, - mariadb-rocksdb-engine-10.4 -Recommends: python3-mysqldb +Depends: + mariadb-server (= ${server:Version}), + python3:any, + rocksdb-tools, + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-rocksdb-engine-10.2, + mariadb-rocksdb-engine-10.3, + mariadb-rocksdb-engine-10.4, +Replaces: + mariadb-rocksdb-engine-10.2, + mariadb-rocksdb-engine-10.3, + mariadb-rocksdb-engine-10.4, +Recommends: + python3-mysqldb, Description: RocksDB storage engine for MariaDB server The RocksDB storage engine is a high performance storage engine, aimed at maximising storage efficiency while maintaining InnoDB-like performance. @@ -1011,24 +1082,26 @@ Description: RocksDB storage engine for MariaDB server Package: mariadb-plugin-oqgraph Architecture: any -Depends: libjudydebian1, - mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Breaks: mariadb-oqgraph-engine-10.0, - mariadb-oqgraph-engine-10.1, - mariadb-oqgraph-engine-10.2, - mariadb-oqgraph-engine-10.3, - mariadb-oqgraph-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 -Replaces: mariadb-oqgraph-engine-10.0, - mariadb-oqgraph-engine-10.1, - mariadb-oqgraph-engine-10.2, - mariadb-oqgraph-engine-10.3, - mariadb-oqgraph-engine-10.4, - mariadb-server-10.0, - mariadb-server-10.1 +Depends: + mariadb-server (= ${server:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-oqgraph-engine-10.0, + mariadb-oqgraph-engine-10.1, + mariadb-oqgraph-engine-10.2, + mariadb-oqgraph-engine-10.3, + mariadb-oqgraph-engine-10.4, + mariadb-server-10.0, + mariadb-server-10.1, +Replaces: + mariadb-oqgraph-engine-10.0, + mariadb-oqgraph-engine-10.1, + mariadb-oqgraph-engine-10.2, + mariadb-oqgraph-engine-10.3, + mariadb-oqgraph-engine-10.4, + mariadb-server-10.0, + mariadb-server-10.1, Description: OQGraph storage engine for MariaDB server The OQGraph engine is a computation engine plugin for handling hierarchies (trees) and graphs (friend-of-a-friend, etc) cleanly through standard SQL. @@ -1036,19 +1109,22 @@ Description: OQGraph storage engine for MariaDB server Package: mariadb-plugin-mroonga Architecture: any-alpha any-amd64 any-arm any-arm64 any-i386 any-ia64 any-mips64el any-mips64r6el any-mipsel any-mipsr6el any-nios2 any-powerpcel any-ppc64el any-sh3 any-sh4 any-tilegx -Depends: mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Breaks: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 -Replaces: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 +Depends: + mariadb-server (= ${server:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, +Replaces: + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, Description: Mroonga storage engine for MariaDB server Mroonga (formerly named Groonga Storage Engine) is a storage engine that provides fast CJK-ready full text searching using column store. @@ -1056,19 +1132,22 @@ Description: Mroonga storage engine for MariaDB server Package: mariadb-plugin-spider Architecture: any -Depends: mariadb-server (= ${server:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Breaks: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 -Replaces: mariadb-server-10.0, - mariadb-server-10.1, - mariadb-server-10.2, - mariadb-server-10.3, - mariadb-server-10.4 +Depends: + mariadb-server (= ${server:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, +Replaces: + mariadb-server-10.0, + mariadb-server-10.1, + mariadb-server-10.2, + mariadb-server-10.3, + mariadb-server-10.4, Description: Spider storage engine for MariaDB server The Spider storage engine with built-in sharding features. It supports partitioning and xa transactions, and allows tables of different MariaDB server @@ -1077,22 +1156,24 @@ Description: Spider storage engine for MariaDB server Package: mariadb-plugin-gssapi-server Architecture: any -Depends: libgssapi-krb5-2, - mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} -Breaks: mariadb-gssapi-server-10.1, - mariadb-gssapi-server-10.2, - mariadb-gssapi-server-10.3, - mariadb-gssapi-server-10.4, - mariadb-server-10.0, - mariadb-server-10.1 -Replaces: mariadb-gssapi-server-10.1, - mariadb-gssapi-server-10.2, - mariadb-gssapi-server-10.3, - mariadb-gssapi-server-10.4, - mariadb-server-10.0, - mariadb-server-10.1 +Depends: + mariadb-server (= ${server:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-gssapi-server-10.1, + mariadb-gssapi-server-10.2, + mariadb-gssapi-server-10.3, + mariadb-gssapi-server-10.4, + mariadb-server-10.0, + mariadb-server-10.1, +Replaces: + mariadb-gssapi-server-10.1, + mariadb-gssapi-server-10.2, + mariadb-gssapi-server-10.3, + mariadb-gssapi-server-10.4, + mariadb-server-10.0, + mariadb-server-10.1, Description: GSSAPI authentication plugin for MariaDB server This plugin includes support for Kerberos on Unix, but can also be used for Windows authentication with or without domain environment. @@ -1101,18 +1182,20 @@ Description: GSSAPI authentication plugin for MariaDB server Package: mariadb-plugin-gssapi-client Architecture: any -Depends: libgssapi-krb5-2, - mariadb-client (= ${binary:Version}), - ${misc:Depends}, - ${shlibs:Depends} -Breaks: mariadb-gssapi-client-10.1, - mariadb-gssapi-client-10.2, - mariadb-gssapi-client-10.3, - mariadb-gssapi-client-10.4 -Replaces: mariadb-gssapi-client-10.1, - mariadb-gssapi-client-10.2, - mariadb-gssapi-client-10.3, - mariadb-gssapi-client-10.4 +Depends: + mariadb-client (= ${binary:Version}), + ${misc:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-gssapi-client-10.1, + mariadb-gssapi-client-10.2, + mariadb-gssapi-client-10.3, + mariadb-gssapi-client-10.4, +Replaces: + mariadb-gssapi-client-10.1, + mariadb-gssapi-client-10.2, + mariadb-gssapi-client-10.3, + mariadb-gssapi-client-10.4, Description: GSSAPI authentication plugin for MariaDB client This plugin includes support for Kerberos on Unix, but can also be used for Windows authentication with or without domain environment. @@ -1121,10 +1204,10 @@ Description: GSSAPI authentication plugin for MariaDB client Package: mariadb-plugin-cracklib-password-check Architecture: any -Depends: libcrack2 (>= 2.9.0), - mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: CrackLib Password Validation Plugin for MariaDB server This password validation plugin uses cracklib to allow only sufficiently secure (as defined by cracklib) user passwords in @@ -1135,19 +1218,20 @@ Description: CrackLib Password Validation Plugin for MariaDB server Package: mariadb-plugin-hashicorp-key-management Architecture: any -Depends: libcurl4, - mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: Hashicorp Key Management plugin for MariaDB This encryption plugin uses Hashicorp Vault for storing encryption keys for MariaDB Data-at-Rest encryption. Package: mariadb-plugin-provider-bzip2 Architecture: any -Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: BZip2 compression support in the server and storage engines The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, can use different compression libraries. @@ -1159,9 +1243,10 @@ Description: BZip2 compression support in the server and storage engines Package: mariadb-plugin-provider-lz4 Architecture: any -Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: LZ4 compression support in the server and storage engines The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, can use different compression libraries. @@ -1173,9 +1258,10 @@ Description: LZ4 compression support in the server and storage engines Package: mariadb-plugin-provider-lzma Architecture: any -Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: LZMA compression support in the server and storage engines The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, can use different compression libraries. @@ -1187,9 +1273,10 @@ Description: LZMA compression support in the server and storage engines Package: mariadb-plugin-provider-lzo Architecture: any -Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: LZO compression support in the server and storage engines The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, can use different compression libraries. @@ -1201,9 +1288,10 @@ Description: LZO compression support in the server and storage engines Package: mariadb-plugin-provider-snappy Architecture: any -Depends: mariadb-server, - ${misc:Depends}, - ${shlibs:Depends} +Depends: + mariadb-server, + ${misc:Depends}, + ${shlibs:Depends}, Description: Snappy compression support in the server and storage engines The various MariaDB storage engines, such as InnoDB, RocksDB, Mroonga, can use different compression libraries. @@ -1213,58 +1301,75 @@ Description: Snappy compression support in the server and storage engines Note that these affect InnoDB and Mroonga only; RocksDB still uses the compression algorithms from its own library -Package: mariadb-test +Package: mariadb-plugin-videx Architecture: any -Depends: libnet-ssleay-perl, - mariadb-client (= ${binary:Version}), - mariadb-server (= ${server:Version}), - mariadb-test-data (= ${source:Version}), - virtual-mysql-testsuite, +Depends: mariadb-server (= ${server:Version}), ${misc:Depends}, - ${perl:Depends}, ${shlibs:Depends} -Conflicts: mariadb-server-5.5, - mysql-server-5.7, - mysql-server-core-8.0 -Breaks: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-10.3, - mariadb-test-10.4, - mariadb-test-5.5, - mysql-client-5.5, - mysql-server-5.5, - mysql-server-5.7, - mysql-server-core-8.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7 -Replaces: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-10.3, - mariadb-test-10.4, - mariadb-test-5.5, - mysql-client-5.5, - mysql-server-5.5, - mysql-server-5.7, - mysql-server-core-8.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0, - percona-server-server-5.6, - percona-xtradb-cluster-server-5.6, - percona-xtradb-cluster-server-5.7, - virtual-mysql-testsuite -Provides: virtual-mysql-testsuite -Suggests: patch +Description: Virtual index engine for what-if analysis in MariaDB + The VIDEX storage engine allows developers and DBAs to perform what-if + analysis by evaluating the impact of potential indexes on query plans. + It simulates the cost and behavior of engines like InnoDB without requiring + the indexes to be physically built, saving significant time and resources. + +Package: mariadb-test +Architecture: any +Depends: + libnet-ssleay-perl, + mariadb-client (= ${binary:Version}), + mariadb-server (= ${server:Version}), + mariadb-test-data (= ${source:Version}), + virtual-mysql-testsuite, + ${misc:Depends}, + ${perl:Depends}, + ${shlibs:Depends}, +Conflicts: + mariadb-server-5.5, + mysql-server-5.7, + mysql-server-core-8.0, +Breaks: + mariadb-test-10.0, + mariadb-test-10.1, + mariadb-test-10.2, + mariadb-test-10.3, + mariadb-test-10.4, + mariadb-test-5.5, + mysql-client-5.5, + mysql-server-5.5, + mysql-server-5.7, + mysql-server-core-8.0, + mysql-testsuite, + mysql-testsuite-5.5, + mysql-testsuite-5.6, + mysql-testsuite-5.7, + mysql-testsuite-8.0, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, +Replaces: + mariadb-test-10.0, + mariadb-test-10.1, + mariadb-test-10.2, + mariadb-test-10.3, + mariadb-test-10.4, + mariadb-test-5.5, + mysql-client-5.5, + mysql-server-5.5, + mysql-server-5.7, + mysql-server-core-8.0, + mysql-testsuite, + mysql-testsuite-5.5, + mysql-testsuite-5.6, + mysql-testsuite-5.7, + mysql-testsuite-8.0, + percona-server-server-5.6, + percona-xtradb-cluster-server-5.6, + percona-xtradb-cluster-server-5.7, + virtual-mysql-testsuite, +Provides: + virtual-mysql-testsuite, +Suggests: + patch, Description: MariaDB database regression test suite MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query @@ -1276,29 +1381,32 @@ Description: MariaDB database regression test suite Package: mariadb-test-data Architecture: all Multi-Arch: foreign -Depends: ${misc:Depends}, - ${perl:Depends}, - ${shlibs:Depends} -Breaks: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-5.5, - mariadb-test-data-10.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0 -Replaces: mariadb-test-10.0, - mariadb-test-10.1, - mariadb-test-10.2, - mariadb-test-5.5, - mariadb-test-data-10.0, - mysql-testsuite, - mysql-testsuite-5.5, - mysql-testsuite-5.6, - mysql-testsuite-5.7, - mysql-testsuite-8.0 +Depends: + ${misc:Depends}, + ${perl:Depends}, + ${shlibs:Depends}, +Breaks: + mariadb-test-10.0, + mariadb-test-10.1, + mariadb-test-10.2, + mariadb-test-5.5, + mariadb-test-data-10.0, + mysql-testsuite, + mysql-testsuite-5.5, + mysql-testsuite-5.6, + mysql-testsuite-5.7, + mysql-testsuite-8.0, +Replaces: + mariadb-test-10.0, + mariadb-test-10.1, + mariadb-test-10.2, + mariadb-test-5.5, + mariadb-test-data-10.0, + mysql-testsuite, + mysql-testsuite-5.5, + mysql-testsuite-5.6, + mysql-testsuite-5.7, + mysql-testsuite-8.0, Description: MariaDB database regression test suite - data files MariaDB is a fast, stable and true multi-user, multi-threaded SQL database server. SQL (Structured Query Language) is the most popular database query diff --git a/debian/libmariadb3.install b/debian/libmariadb3.install index be143ad5f13ee..1910b8fcd10b8 100644 --- a/debian/libmariadb3.install +++ b/debian/libmariadb3.install @@ -3,5 +3,5 @@ usr/lib/*/libmariadb3/plugin/caching_sha2_password.so usr/lib/*/libmariadb3/plugin/client_ed25519.so usr/lib/*/libmariadb3/plugin/dialog.so usr/lib/*/libmariadb3/plugin/mysql_clear_password.so -usr/lib/*/libmariadb3/plugin/sha256_password.so usr/lib/*/libmariadb3/plugin/parsec.so +usr/lib/*/libmariadb3/plugin/sha256_password.so diff --git a/debian/mariadb-plugin-videx.install b/debian/mariadb-plugin-videx.install new file mode 100644 index 0000000000000..8c8a327fe7afc --- /dev/null +++ b/debian/mariadb-plugin-videx.install @@ -0,0 +1,2 @@ +etc/mysql/mariadb.conf.d/videx.cnf +usr/lib/mysql/plugin/ha_videx.so \ No newline at end of file diff --git a/debian/mariadb-server.install b/debian/mariadb-server.install index 5889bd827ae1d..e2563ca5b4519 100644 --- a/debian/mariadb-server.install +++ b/debian/mariadb-server.install @@ -7,11 +7,11 @@ etc/apparmor.d/usr.sbin.mariadbd etc/logrotate.d/mariadb etc/security/user_map.conf lib/*/security/pam_user_map.so -lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf lib/systemd/system/mariadb-extra@.socket lib/systemd/system/mariadb.service lib/systemd/system/mariadb@.service lib/systemd/system/mariadb@.socket +lib/systemd/system/mariadb@bootstrap.service.d/use_galera_new_cluster.conf lib/systemd/system/mysql.service lib/systemd/system/mysqld.service support-files/rpm/enable_encryption.preset etc/mysql/mariadb.conf.d/99-enable-encryption.cnf.preset @@ -36,6 +36,7 @@ usr/bin/wsrep_sst_mysqldump usr/bin/wsrep_sst_rsync usr/bin/wsrep_sst_rsync_wan usr/lib/mysql/plugin/auth_ed25519.so +usr/lib/mysql/plugin/auth_mysql_sha2.so usr/lib/mysql/plugin/auth_pam.so usr/lib/mysql/plugin/auth_pam_tool_dir/auth_pam_tool usr/lib/mysql/plugin/auth_pam_v1.so @@ -58,6 +59,7 @@ usr/lib/mysql/plugin/simple_password_check.so usr/lib/mysql/plugin/sql_errlog.so usr/lib/mysql/plugin/type_mysql_json.so usr/lib/mysql/plugin/wsrep_info.so +usr/lib/tmpfiles.d/mariadb.conf usr/share/doc/mariadb-server/mariadbd.sym.gz usr/share/man/man1/aria_chk.1 usr/share/man/man1/aria_dump_log.1 diff --git a/debian/mariadb-server.links b/debian/mariadb-server.links new file mode 100644 index 0000000000000..40b0b80a143dd --- /dev/null +++ b/debian/mariadb-server.links @@ -0,0 +1,6 @@ +#!/usr/bin/dh-exec +usr/lib/${DEB_HOST_MULTIARCH}/libmariadb3/plugin/caching_sha2_password.so usr/lib/mysql/plugin/caching_sha2_password.so +usr/lib/${DEB_HOST_MULTIARCH}/libmariadb3/plugin/client_ed25519.so usr/lib/mysql/plugin/client_ed25519.so +usr/lib/${DEB_HOST_MULTIARCH}/libmariadb3/plugin/dialog.so usr/lib/mysql/plugin/dialog.so +usr/lib/${DEB_HOST_MULTIARCH}/libmariadb3/plugin/mysql_clear_password.so usr/lib/mysql/plugin/mysql_clear_password.so +usr/lib/${DEB_HOST_MULTIARCH}/libmariadb3/plugin/sha256_password.so usr/lib/mysql/plugin/sha256_password.so diff --git a/debian/not-installed b/debian/not-installed index 16cd355f55973..8936d8e7d76c4 100644 --- a/debian/not-installed +++ b/debian/not-installed @@ -22,7 +22,6 @@ usr/lib/*/pkgconfig/mariadb.pc usr/bin/uca-dump usr/bin/wsrep_sst_backup usr/lib/sysusers.d/mariadb.conf # Not used (yet) in Debian systemd -usr/lib/tmpfiles.d/mariadb.conf # Not used (yet) in Debian systemd usr/sbin/rcmysql usr/share/doc/mariadb-server/COPYING (related file: "debian/tmp/usr/share/mariadb/mroonga/COPYING") usr/share/doc/mariadb-server/CREDITS diff --git a/debian/rules b/debian/rules index cdbbd0e818b72..bc0ea43a5a6e2 100644 --- a/debian/rules +++ b/debian/rules @@ -146,9 +146,6 @@ override_dh_auto_install: # If mariadb-test package is removed, also remove most of it's files grep --quiet "Package: mariadb-test" debian/control || rm -rf $(TMP)/usr/share/mariadb/mariadb-test - # Delete private files from libraries so they don't get shipped in the -dev packages - rm -r $(TMP)/usr/include/mariadb/server/private - # Don't ship sql-bench at all, just delete it completely even though it builds rm -r $(TMP)/usr/sql-bench diff --git a/debian/tests/control b/debian/tests/control index 01bb919578a35..f11e41aecb64b 100644 --- a/debian/tests/control +++ b/debian/tests/control @@ -1,17 +1,26 @@ -Tests: smoke +Tests: + smoke, # RocksDB is not built for all archs. Rather than duplicating the condition # for its existence (see the list in debian/control), install it if available # and check in the test if it's functional when it should be. # The plugin package also already depends on the other one. -Depends: mariadb-plugin-provider-bzip2, - mariadb-plugin-provider-lz4, - mariadb-plugin-provider-lzma, - mariadb-plugin-provider-lzo, - mariadb-plugin-provider-snappy, - mariadb-plugin-rocksdb | mariadb-server -Restrictions: allow-stderr needs-root isolation-container +Depends: + mariadb-plugin-provider-bzip2, + mariadb-plugin-provider-lz4, + mariadb-plugin-provider-lzma, + mariadb-plugin-provider-lzo, + mariadb-plugin-provider-snappy, + mariadb-plugin-rocksdb | mariadb-server, +Restrictions: + allow-stderr, + isolation-container, + needs-root, -Tests: upstream -Depends: eatmydata, - mariadb-test -Restrictions: allow-stderr breaks-testbed +Tests: + upstream, +Depends: + eatmydata, + mariadb-test, +Restrictions: + allow-stderr, + breaks-testbed, diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index 864a576bd09a6..ee8d4c4ef91af 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -51,7 +51,6 @@ The parts not included are excluded by #ifndef UNIV_INNOCHECKSUM. */ #include "page0zip.h" /* page_zip_*() */ #include "trx0undo.h" /* TRX_* */ #include "fil0crypt.h" /* fil_space_verify_crypt_checksum */ - #include #ifndef PRIuMAX @@ -74,6 +73,8 @@ static ulint extent_size; static ulint xdes_size; ulong srv_page_size; uint32_t srv_page_size_shift; +static uint32_t dblwr_1; +static uint32_t dblwr_2; /* Current page number (0 based). */ uint32_t cur_page_num; /* Current space. */ @@ -97,8 +98,10 @@ FILE* log_file = NULL; /* Enabled for log write option. */ static bool is_log_enabled = false; static bool skip_freed_pages; +static uint32_t tablespace_flags= 0; static byte field_ref_zero_buf[UNIV_PAGE_SIZE_MAX]; const byte *field_ref_zero = field_ref_zero_buf; +constexpr uint32_t USE_FSP_FLAGS{UINT32_MAX}; #ifndef _WIN32 /* advisory lock for non-window system. */ @@ -253,12 +256,9 @@ void print_leaf_stats( } /** Init the page size for the tablespace. -@param[in] buf buffer used to read the page */ -static void init_page_size(const byte* buf) +@param[in] flags InnoDB tablespace flags */ +static void init_page_size_from_flags(const uint32_t flags) { - const unsigned flags = mach_read_from_4(buf + FIL_PAGE_DATA - + FSP_SPACE_FLAGS); - if (fil_space_t::full_crc32(flags)) { const uint32_t ssize = FSP_FLAGS_FCRC32_GET_PAGE_SSIZE(flags); srv_page_size_shift = UNIV_ZIP_SIZE_SHIFT_MIN - 1 + ssize; @@ -540,24 +540,15 @@ static bool is_page_corrupted(byte *buf, bool is_encrypted, uint32_t flags) return(is_corrupted); } -/********************************************//* - Check if page is doublewrite buffer or not. - @param [in] page buffer page - - @retval true if page is doublewrite buffer otherwise false. -*/ -static -bool -is_page_doublewritebuffer( - const byte* page) +/** Check if page is doublewrite buffer or not. +@retval true if page is doublewrite buffer otherwise false. */ +static bool is_page_doublewritebuffer() { - if ((cur_page_num >= extent_size) - && (cur_page_num < extent_size * 3)) { - /* page is doublewrite buffer. */ - return (true); - } - - return (false); + if (cur_space != 0) return false; + const uint32_t extent{static_cast( + cur_page_num & ~(extent_size - 1))}; + return cur_page_num > FSP_DICT_HDR_PAGE_NO && + extent && (extent == dblwr_1 || extent == dblwr_2); } /*******************************************************//* @@ -764,7 +755,7 @@ Parse the page and collect/dump the information about page type @param [in] file file for diagnosis. @param [in] is_encrypted tablespace is encrypted */ -void +static void parse_page( const byte* page, byte* xdes, @@ -784,6 +775,12 @@ parse_page( str = skip_page ? "Double_write_buffer" : "-"; page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); if (skip_freed_pages) { + + /** Skip doublewrite pages when -r is enabled */ + if (is_page_doublewritebuffer()) { + return; + } + const byte *des= xdes + XDES_ARR_OFFSET + xdes_size * ((page_no & (physical_page_size - 1)) / extent_size); @@ -978,6 +975,18 @@ parse_page( fprintf(file, "#::" UINT32PF "\t\t|\t\tTransaction system " "page\t\t|\t%s\n", cur_page_num, str); } + + if (cur_space == 0 && + (mach_read_from_4(page + TRX_SYS_DOUBLEWRITE + + TRX_SYS_DOUBLEWRITE_MAGIC) == + TRX_SYS_DOUBLEWRITE_MAGIC_N)) { + dblwr_1 = mach_read_from_4( + page + TRX_SYS_DOUBLEWRITE + + TRX_SYS_DOUBLEWRITE_BLOCK1); + dblwr_2 = mach_read_from_4( + page + TRX_SYS_DOUBLEWRITE + + TRX_SYS_DOUBLEWRITE_BLOCK2); + } break; case FIL_PAGE_TYPE_FSP_HDR: @@ -1220,6 +1229,9 @@ static struct my_option innochecksum_options[] = { {"skip-freed-pages", 'r', "skip freed pages for the tablespace", &skip_freed_pages, &skip_freed_pages, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"tablespace-flags", 0, "InnoDB tablespace flags (default: 4294967295 " + "= read from page 0)", &tablespace_flags, &tablespace_flags, 0, + GET_UINT, REQUIRED_ARG, USE_FSP_FLAGS, 0, USE_FSP_FLAGS, 0, 0, 0}, {0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1280,6 +1292,14 @@ innochecksum_get_one_option( my_end(0); exit(EXIT_SUCCESS); break; + default: + if (tablespace_flags != USE_FSP_FLAGS && + !fil_space_t::is_valid_flags(tablespace_flags, false) && + !fil_space_t::is_valid_flags(tablespace_flags, true)) { + fprintf(stderr, "Error: Provided --tablespace-flags " + "is not valid."); + return true; + } } return(false); @@ -1410,6 +1430,87 @@ rewrite_checksum( && !write_file(filename, fil_in, buf, flags, pos); } +/** Read and validate page 0, then initialize tablespace flags +and page size. +@param fil_in File pointer +@param buf Buffer to read page into +@return whether the page was read successfully */ +static bool read_and_validate_page0(FILE *fil_in, byte *buf) +{ + /* Read the minimum page size first */ + size_t initial_page_size= UNIV_ZIP_SIZE_MIN; + if (tablespace_flags != USE_FSP_FLAGS) + { + init_page_size_from_flags(tablespace_flags); + initial_page_size= physical_page_size; + } + + /* Read just enough to get the tablespace flags */ + size_t bytes= fread(buf, 1, initial_page_size, fil_in); + + if (bytes != initial_page_size) + { + fprintf(stderr, "Error: Was not able to read the " + "minimum page size of %zu bytes. Bytes read " + "was %zu\n", initial_page_size, bytes); + return false; + } + + /* Read space_id and page offset */ + cur_space= mach_read_from_4(buf + FIL_PAGE_SPACE_ID); + cur_page_num= mach_read_from_4(buf + FIL_PAGE_OFFSET); + + /* Get tablespace flags from the FSP header */ + uint32_t flags= mach_read_from_4(buf + FSP_HEADER_OFFSET + + FSP_SPACE_FLAGS); + + if (tablespace_flags != USE_FSP_FLAGS) + { + if (cur_page_num == 0 && flags != tablespace_flags) + fprintf(stderr, "Error: Mismatch between provided tablespace " + "flags (0x%x) and file flags (0x%x)\n", + tablespace_flags, flags); + } + else + { + if (cur_page_num) + { + fprintf(stderr, "Error: First page of the tablespace file " + "should be 0, but encountered page number %" PRIu32 ". " + "If you are checking multi file system " + "tablespace files, please specify the correct " + "tablespace flags using --tablespace-flags option.\n", + cur_page_num); + return false; + } + /* Initialize page size parameters based on flags */ + init_page_size_from_flags(flags); + /* Read the rest of the page if it's larger than the minimum size */ + if (physical_page_size > UNIV_ZIP_SIZE_MIN) + { + /* Read rest of the page 0 to determine crypt_data */ + ulint bytes= read_file(buf, true, physical_page_size, fil_in); + if (bytes != physical_page_size) + { + fprintf(stderr, "Error: Was not able to read the rest of the " + "page of " ULINTPF " bytes. Bytes read was " ULINTPF "\n", + physical_page_size - UNIV_ZIP_SIZE_MIN, bytes); + return false; + } + } + tablespace_flags= flags; + } + + if (physical_page_size < UNIV_ZIP_SIZE_MIN || + physical_page_size > UNIV_PAGE_SIZE_MAX) + { + fprintf(stderr, "Error: Invalid page size " ULINTPF + " encountered\n", physical_page_size); + return false; + } + return true; +} + int main( int argc, char **argv) @@ -1545,51 +1646,13 @@ int main( } } - /* Read the minimum page size. */ - bytes = fread(buf, 1, UNIV_ZIP_SIZE_MIN, fil_in); - partial_page_read = true; - - if (bytes != UNIV_ZIP_SIZE_MIN) { - fprintf(stderr, "Error: Was not able to read the " - "minimum page size "); - fprintf(stderr, "of %d bytes. Bytes read was " ULINTPF "\n", - UNIV_ZIP_SIZE_MIN, bytes); - + /* Read and validate page 0 */ + if (!read_and_validate_page0(fil_in, buf)) { exit_status = 1; goto my_exit; } - /* enable variable is_system_tablespace when space_id of given - file is zero. Use to skip the checksum verification and rewrite - for doublewrite pages. */ - cur_space = mach_read_from_4(buf + FIL_PAGE_SPACE_ID); - cur_page_num = mach_read_from_4(buf + FIL_PAGE_OFFSET); - - /* Determine page size, zip_size and page compression - from fsp_flags and encryption metadata from page 0 */ - init_page_size(buf); - - uint32_t flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + buf); - - if (physical_page_size == UNIV_ZIP_SIZE_MIN) { - partial_page_read = false; - } else { - /* Read rest of the page 0 to determine crypt_data */ - bytes = read_file(buf, partial_page_read, physical_page_size, fil_in); - if (bytes != physical_page_size) { - fprintf(stderr, "Error: Was not able to read the " - "rest of the page "); - fprintf(stderr, "of " ULINTPF " bytes. Bytes read was " ULINTPF "\n", - physical_page_size - UNIV_ZIP_SIZE_MIN, bytes); - - exit_status = 1; - goto my_exit; - } - partial_page_read = false; - } - - - /* Now that we have full page 0 in buffer, check encryption */ + /* Check if tablespace is encrypted */ bool is_encrypted = check_encryption(filename, buf); /* Verify page 0 contents. Note that we can't allow @@ -1600,7 +1663,8 @@ int main( allow_mismatches = 0; exit_status = verify_checksum(buf, is_encrypted, - &mismatch_count, flags); + &mismatch_count, + tablespace_flags); if (exit_status) { fprintf(stderr, "Error: Page 0 checksum mismatch, can't continue. \n"); @@ -1611,7 +1675,8 @@ int main( if ((exit_status = rewrite_checksum( filename, fil_in, buf, - &pos, is_encrypted, flags))) { + &pos, is_encrypted, + tablespace_flags))) { goto my_exit; } @@ -1807,7 +1872,7 @@ int main( first_non_zero: if (is_system_tablespace) { /* enable when page is double write buffer.*/ - skip_page = is_page_doublewritebuffer(buf); + skip_page = is_page_doublewritebuffer(); } else { skip_page = false; } @@ -1828,13 +1893,16 @@ int main( && !is_page_free(xdes, physical_page_size, cur_page_num) && (exit_status = verify_checksum( buf, is_encrypted, - &mismatch_count, flags))) { + &mismatch_count, + tablespace_flags))) { goto my_exit; } - if ((exit_status = rewrite_checksum( - filename, fil_in, buf, - &pos, is_encrypted, flags))) { + if (!is_page_doublewritebuffer() && + (exit_status = rewrite_checksum( + filename, fil_in, buf, + &pos, is_encrypted, + tablespace_flags))) { goto my_exit; } diff --git a/extra/mariabackup/aria_backup_client.cc b/extra/mariabackup/aria_backup_client.cc index ab293c07989b1..eefeb78c6a8dd 100644 --- a/extra/mariabackup/aria_backup_client.cc +++ b/extra/mariabackup/aria_backup_client.cc @@ -161,7 +161,10 @@ class Table { File m_data_file = -1; MY_STAT m_data_file_stat; }; - Table() = default; + Table() + { + bzero(&m_cap, sizeof(m_cap)); + } Table (Table &&other) = delete; Table & operator= (Table &&other) = delete; Table(const Table &) = delete; @@ -222,6 +225,7 @@ class Table { }; Table::~Table() { + aria_free_capabilities(&m_cap); (void)close(); } @@ -298,7 +302,8 @@ bool Table::open(MYSQL *con, bool opt_no_lock, unsigned thread_num) { goto exit; } if (!have_capabilities) { - if ((error= aria_get_capabilities(partition.m_index_file, &m_cap))) { + if ((error= aria_get_capabilities(partition.m_index_file, + m_full_name.c_str(), &m_cap))) { msg(thread_num, "aria_get_capabilities failed: %d", error); goto exit; } @@ -343,6 +348,7 @@ bool Table::open(MYSQL *con, bool opt_no_lock, unsigned thread_num) { } bool Table::close() { + aria_free_capabilities(&m_cap); for (Partition &partition : m_partitions) { if (partition.m_index_file >= 0) { my_close(partition.m_index_file, MYF(MY_WME)); @@ -399,26 +405,27 @@ bool Table::copy(ds_ctxt_t *ds, bool is_index, unsigned thread_num) { for (ulonglong block= 0 ; ; block++) { size_t length = m_cap.block_size; - if (is_index) { - if ((error= aria_read_index( - partition.m_index_file, &m_cap, block, copy_buffer) == - HA_ERR_END_OF_FILE)) - break; - } else { - if ((error= aria_read_data( - partition.m_data_file, &m_cap, block, copy_buffer, &length) == - HA_ERR_END_OF_FILE)) - break; - } - if (error) { - msg(thread_num, "error: aria_read %s failed: %d", - is_index ? "index" : "data", error); - goto err; + if (is_index) + error= aria_read_index(partition.m_index_file, &m_cap, + block, copy_buffer); + else + error= aria_read_data(partition.m_data_file, &m_cap, + block, copy_buffer, &length); + if (error) + { + if (error == HA_ERR_END_OF_FILE) + break; + msg(thread_num, "error: aria_read %s from %s failed " + "with error %d", + is_index ? "index" : "data", full_name.c_str(), + error); + goto err; } xtrabackup_io_throttling(); if ((error = ds_write(dst_file, copy_buffer, length))) { - msg(thread_num, "error: aria_write failed: %d", error); - goto err; + msg(thread_num, "error: aria_write to %s failed " + "with error: %d", dst_path, error); + goto err; } } @@ -990,8 +997,8 @@ bool prepare(const char *target_dir) { logs.find_logs_after_last(target_dir); last_logno= logs.last(); // Update last_logno if extra logs were found - if (init_pagecache(maria_pagecache, 1024L*1024L, 0, 0, - static_cast(maria_block_size), 0, MY_WME) == 0) + if (multi_init_pagecache(&maria_pagecaches, 1, 1024L*1024L, 0, 0, + static_cast(maria_block_size), 0, MY_WME)) die("Got error in Aria init_pagecache() (errno: %d)", errno); if (init_pagecache(maria_log_pagecache, 1024L*1024L, diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index ed308c75c9e10..36e4210b7f498 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -61,6 +61,7 @@ Street, Fifth Floor, Boston, MA 02110-1335 USA #include "backup_debug.h" #include "backup_mysql.h" #include +#include #ifdef _WIN32 #include /* rmdir */ #endif @@ -1630,7 +1631,10 @@ class Copy_back_dst_dir return mysql_data_home; if (is_absolute_path(path)) return path; - return buf.assign(mysql_data_home).append(path).c_str(); + buf.assign(mysql_data_home); + if (!buf.empty() && buf.back() != '/' IF_WIN(&& buf.back() != '\\', )) + buf.append("/"); + return buf.append(path).c_str(); } }; @@ -1674,6 +1678,7 @@ copy_back() datadir_iter_t *it = NULL; datadir_node_t node; const char *dst_dir; + ds_ctxt *ds_binlogs = NULL; memset(&node, 0, sizeof(node)); @@ -1753,7 +1758,7 @@ copy_back() for (uint i = 1; i <= TRX_SYS_MAX_UNDO_SPACES; i++) { char filename[20]; - sprintf(filename, "undo%03u", i); + snprintf(filename, sizeof(filename), "undo%03u", i); if (!file_exists(filename)) { break; } @@ -1799,6 +1804,10 @@ copy_back() ds_destroy(ds_tmp); + /* Prepare destination directory for any InnoDB binlog files. */ + dst_dir = dst_dir_buf.make(opt_binlog_directory); + ds_binlogs = ds_create(dst_dir, DS_TYPE_LOCAL); + /* copy the rest of tablespaces */ ds_tmp = ds_create(mysql_data_home, DS_TYPE_LOCAL); @@ -1860,6 +1869,16 @@ copy_back() filename = base_name(node.filepath); + /* Copy InnoDB binlog files into --binlog-directory. */ + uint64_t file_no; + if (is_binlog_name(filename, &file_no)) { + if (!(ret = copy_or_move_file(ds_binlogs, filename, filename, + dst_dir, 1))) { + goto cleanup; + } + continue; + } + /* skip .qp files */ if (filename_matches(filename, ext_list)) { continue; @@ -1920,6 +1939,11 @@ copy_back() ds_tmp = NULL; + if (ds_binlogs != NULL) { + ds_destroy(ds_binlogs); + ds_binlogs = NULL; + } + return(ret); } diff --git a/extra/mariabackup/backup_mysql.cc b/extra/mariabackup/backup_mysql.cc index 4492827eb9715..713c2cb44fb04 100644 --- a/extra/mariabackup/backup_mysql.cc +++ b/extra/mariabackup/backup_mysql.cc @@ -77,6 +77,7 @@ bool have_lock_wait_timeout = false; bool have_galera_enabled = false; bool have_multi_threaded_slave = false; bool have_gtid_slave = false; +bool innobase_data_file_path_allocated= false; /* Kill long selects */ static mysql_mutex_t kill_query_thread_mutex; @@ -147,7 +148,7 @@ xb_mysql_connect() char mysql_port_str[std::numeric_limits::digits10 + 3]; const char *user= opt_user ? opt_user : get_os_user(); - sprintf(mysql_port_str, "%d", opt_port); + snprintf(mysql_port_str, sizeof(mysql_port_str), "%d", opt_port); if (connection == NULL) { msg("Failed to init MariaDB struct: %s.", @@ -162,11 +163,6 @@ xb_mysql_connect() } #endif - if (!opt_secure_auth) { - mysql_options(connection, MYSQL_SECURE_AUTH, - (char *) &opt_secure_auth); - } - if (xb_plugin_dir && *xb_plugin_dir){ mysql_options(connection, MYSQL_PLUGIN_DIR, xb_plugin_dir); } @@ -384,6 +380,7 @@ bool get_mysql_vars(MYSQL *connection) char *aria_log_dir_path_var= NULL; char *page_zip_level_var= NULL; char *ignore_db_dirs= NULL; + char *binlog_directory_var= NULL; char *endptr; ulong server_version= mysql_get_server_version(connection); @@ -410,6 +407,7 @@ bool get_mysql_vars(MYSQL *connection) {"innodb_compression_level", &page_zip_level_var}, {"ignore_db_dirs", &ignore_db_dirs}, {"aria_log_dir_path", &aria_log_dir_path_var}, + {"binlog_directory", &binlog_directory_var}, {NULL, NULL}}; read_mysql_variables(connection, "SHOW VARIABLES", mysql_vars, true); @@ -500,21 +498,19 @@ bool get_mysql_vars(MYSQL *connection) } if (innodb_data_file_path_var && *innodb_data_file_path_var) - innobase_data_file_path= my_strdup(PSI_NOT_INSTRUMENTED, - innodb_data_file_path_var, MYF(MY_FAE)); + innobase_data_file_path= my_once_strdup(innodb_data_file_path_var, + MYF(MY_FAE)); if (innodb_data_home_dir_var) - innobase_data_home_dir= my_strdup(PSI_NOT_INSTRUMENTED, - innodb_data_home_dir_var, MYF(MY_FAE)); + innobase_data_home_dir= my_once_strdup(innodb_data_home_dir_var, + MYF(MY_FAE)); if (innodb_log_group_home_dir_var && *innodb_log_group_home_dir_var) - srv_log_group_home_dir= my_strdup(PSI_NOT_INSTRUMENTED, - innodb_log_group_home_dir_var, - MYF(MY_FAE)); + srv_log_group_home_dir= my_once_strdup(innodb_log_group_home_dir_var, + MYF(MY_FAE)); if (innodb_undo_directory_var && *innodb_undo_directory_var) - srv_undo_dir= my_strdup(PSI_NOT_INSTRUMENTED, innodb_undo_directory_var, - MYF(MY_FAE)); + srv_undo_dir= my_once_strdup(innodb_undo_directory_var, MYF(MY_FAE)); if (innodb_log_file_size_var) { @@ -536,10 +532,7 @@ bool get_mysql_vars(MYSQL *connection) } if (aria_log_dir_path_var) - { - aria_log_dir_path= my_strdup(PSI_NOT_INSTRUMENTED, - aria_log_dir_path_var, MYF(MY_FAE)); - } + aria_log_dir_path= my_once_strdup(aria_log_dir_path_var, MYF(MY_FAE)); if (page_zip_level_var != NULL) { @@ -551,12 +544,20 @@ bool get_mysql_vars(MYSQL *connection) if (ignore_db_dirs) xb_load_list_string(ignore_db_dirs, ",", register_ignore_db_dirs_filter); + if (free_opt_binlog_directory) + my_free(const_cast(opt_binlog_directory)); + opt_binlog_directory= my_strdup(PSI_NOT_INSTRUMENTED, + (binlog_directory_var ? binlog_directory_var : ""), + MYF(MY_FAE)); + free_opt_binlog_directory= true; + out: free_mysql_variables(mysql_vars); return (ret); } + static bool select_incremental_lsn_from_history(lsn_t *incremental_lsn) @@ -932,7 +933,7 @@ lock_for_backup_stage_flush(MYSQL *connection) { if (opt_kill_long_queries_timeout) { start_query_killer(); } - xb_mysql_query(connection, "BACKUP STAGE FLUSH", true); + xb_mysql_query(connection, "BACKUP STAGE FLUSH", false); if (opt_kill_long_queries_timeout) { stop_query_killer(); } @@ -944,7 +945,7 @@ lock_for_backup_stage_block_ddl(MYSQL *connection) { if (opt_kill_long_queries_timeout) { start_query_killer(); } - xb_mysql_query(connection, "BACKUP STAGE BLOCK_DDL", true); + xb_mysql_query(connection, "BACKUP STAGE BLOCK_DDL", false); DBUG_MARIABACKUP_EVENT("after_backup_stage_block_ddl", {}); if (opt_kill_long_queries_timeout) { stop_query_killer(); @@ -957,7 +958,7 @@ lock_for_backup_stage_commit(MYSQL *connection) { if (opt_kill_long_queries_timeout) { start_query_killer(); } - xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", true); + xb_mysql_query(connection, "BACKUP STAGE BLOCK_COMMIT", false); DBUG_MARIABACKUP_EVENT("after_backup_stage_block_commit", {}); if (opt_kill_long_queries_timeout) { stop_query_killer(); @@ -968,12 +969,12 @@ lock_for_backup_stage_commit(MYSQL *connection) { bool backup_lock(MYSQL *con, const char *table_name) { static const std::string backup_lock_prefix("BACKUP LOCK "); std::string backup_lock_query = backup_lock_prefix + table_name; - xb_mysql_query(con, backup_lock_query.c_str(), true); + xb_mysql_query(con, backup_lock_query.c_str(), false); return true; } bool backup_unlock(MYSQL *con) { - xb_mysql_query(con, "BACKUP UNLOCK", true); + xb_mysql_query(con, "BACKUP UNLOCK", false); return true; } @@ -987,6 +988,8 @@ get_tables_in_use(MYSQL *con) { msg("Table %s is in use", tk.c_str()); result.insert(std::move(tk)); } + if (q_res) + mysql_free_result(q_res); return result; } @@ -1517,7 +1520,9 @@ write_galera_info(ds_ctxt *datasink, MYSQL *connection) domain_id ? domain_id : domain_id55); cleanup: + free_mysql_variables(vars); free_mysql_variables(status); + free_mysql_variables(value); return(result); } @@ -2070,6 +2075,7 @@ ulonglong get_current_lsn(MYSQL *connection) { static const char lsn_prefix[] = "\nLog sequence number "; ulonglong lsn = 0; + msg("Getting InnoDB LSN"); if (MYSQL_RES *res = xb_mysql_query(connection, "SHOW ENGINE INNODB STATUS", true, false)) { @@ -2083,5 +2089,10 @@ ulonglong get_current_lsn(MYSQL *connection) } mysql_free_result(res); } + msg("InnoDB LSN: %llu, Flushing Logs", lsn); + /* Make sure that current LSN is written and flushed to disk. */ + xb_mysql_query(connection, "FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS", + false, false); + msg("Flushed Logs"); return lsn; } diff --git a/extra/mariabackup/backup_mysql.h b/extra/mariabackup/backup_mysql.h index ce7755d17afea..55700dddf6d67 100644 --- a/extra/mariabackup/backup_mysql.h +++ b/extra/mariabackup/backup_mysql.h @@ -97,5 +97,4 @@ bool write_slave_info(ds_ctxt *datasink, MYSQL *connection); ulonglong get_current_lsn(MYSQL *connection); - #endif diff --git a/extra/mariabackup/common_engine.cc b/extra/mariabackup/common_engine.cc index a360f63d84f9f..366e2da38ca6a 100644 --- a/extra/mariabackup/common_engine.cc +++ b/extra/mariabackup/common_engine.cc @@ -9,6 +9,9 @@ #include #include +#include "innodb_binlog.h" + + namespace common_engine { class Table { @@ -298,17 +301,21 @@ class BackupImpl { } bool copy_log_tables(bool finalize); bool copy_stats_tables(); + bool copy_engine_binlogs(const char *binlog_dir, lsn_t backup_lsn); bool wait_for_finish(); bool close_log_tables(); private: void process_table_job(Table *table, bool no_lock, bool delete_table, bool finalize, unsigned thread_num); + void process_binlog_job(std::string src, std::string dst, + lsn_t backup_lsn, unsigned thread_num); const char *m_datadir_path; ds_ctxt_t *m_ds; std::vector &m_con_pool; TasksGroup m_process_table_jobs; + std::unique_ptr m_page_buf; post_copy_table_hook_t m_table_post_copy_hook; std::unordered_map> m_log_tables; @@ -337,6 +344,35 @@ void BackupImpl::process_table_job(Table *table, bool no_lock, m_process_table_jobs.finish_task(result); } +void BackupImpl::process_binlog_job(std::string src, std::string dst, + lsn_t backup_lsn, unsigned thread_num) { + int result = 0; + const char *c_src= src.c_str(); + bool is_empty= true; + lsn_t start_lsn; + int binlog_found; + + if (!m_process_table_jobs.get_result()) + goto exit; + + binlog_found= get_binlog_header(c_src, m_page_buf.get(), start_lsn, is_empty); + if (binlog_found > 0 && !is_empty && start_lsn <= backup_lsn) { + // Test binlog_in_engine.mariabackup_binlogs will try to inject + // RESET MASTER and PURGE BINARY LOGS here. + DBUG_EXECUTE_IF("binlog_copy_sleep_2", + if (src.find("binlog-000002.ibb") != + std::string::npos) + my_sleep(2000000);); + if (!m_ds->copy_file(c_src, dst.c_str(), thread_num)) + goto exit; + } + + result = 1; + +exit: + m_process_table_jobs.finish_task(result); +} + bool BackupImpl::scan(const std::unordered_set &exclude_tables, std::unordered_set *out_processed_tables, bool no_lock, bool collect_log_and_stats) { @@ -461,6 +497,26 @@ bool BackupImpl::copy_stats_tables() { return true; } +bool BackupImpl::copy_engine_binlogs(const char *binlog_dir, lsn_t backup_lsn) { + std::vectorfiles; + std::string dir(binlog_dir && binlog_dir[0] ? binlog_dir : m_datadir_path); + foreach_file_in_datadir(dir.c_str(), + [&](const char *name)->bool { + uint64_t file_no; + if (is_binlog_name(name, &file_no)) + files.emplace_back(name); + return true; + }); + m_page_buf.reset(new byte [ibb_page_size]); + for (auto &file : files) { + std::string path(dir + "/" + file); + m_process_table_jobs.push_task( + std::bind(&BackupImpl::process_binlog_job, this, path, + file, backup_lsn, std::placeholders::_1)); + } + return true; +} + bool BackupImpl::wait_for_finish() { /* Wait for threads to exit */ return m_process_table_jobs.wait_for_finish(); @@ -499,6 +555,10 @@ bool Backup::copy_stats_tables() { return m_backup_impl->copy_stats_tables(); } +bool Backup::copy_engine_binlogs(const char *binlog_dir, lsn_t backup_lsn) { + return m_backup_impl->copy_engine_binlogs(binlog_dir, backup_lsn); +} + bool Backup::wait_for_finish() { return m_backup_impl->wait_for_finish(); } diff --git a/extra/mariabackup/common_engine.h b/extra/mariabackup/common_engine.h index 6f5d8062e5040..3e6035f47f368 100644 --- a/extra/mariabackup/common_engine.h +++ b/extra/mariabackup/common_engine.h @@ -28,6 +28,7 @@ class Backup { bool no_lock, bool collect_log_and_stats); bool copy_log_tables(bool finalize); bool copy_stats_tables(); + bool copy_engine_binlogs(const char *binlog_dir, lsn_t backup_lsn); bool wait_for_finish(); bool close_log_tables(); void set_post_copy_table_hook(const post_copy_table_hook_t &hook); diff --git a/extra/mariabackup/ds_local.cc b/extra/mariabackup/ds_local.cc index ff2021fc03522..bd2b6d02ecd02 100644 --- a/extra/mariabackup/ds_local.cc +++ b/extra/mariabackup/ds_local.cc @@ -211,7 +211,7 @@ static void init_ibd_data(ds_local_file_t *local_file, const uchar *buf, size_t ? fil_space_t::is_compressed(flags) : bool(FSP_FLAGS_HAS_PAGE_COMPRESSION(flags)); -#if defined(_WIN32) && (MYSQL_VERSION_ID > 100200) +#if defined(_WIN32) /* Make compressed file sparse, on Windows. In 10.1, we do not use sparse files. */ if (local_file->compressed) { diff --git a/extra/mariabackup/encryption_plugin.cc b/extra/mariabackup/encryption_plugin.cc index e7e8d95823cb1..9d98a4a631f40 100644 --- a/extra/mariabackup/encryption_plugin.cc +++ b/extra/mariabackup/encryption_plugin.cc @@ -29,6 +29,7 @@ extern struct st_maria_plugin *mysql_optional_plugins[]; extern struct st_maria_plugin *mysql_mandatory_plugins[]; static void encryption_plugin_init(int argc, char **argv); +void initialize_default_encryption(); extern char *xb_plugin_load; extern char *xb_plugin_dir; @@ -140,7 +141,10 @@ void encryption_plugin_backup_init(MYSQL *mysql) } mysql_free_result(result); if (!plugin_load.length()) + { + initialize_default_encryption(); return; + } oss << "plugin_load=" << plugin_load.c_str() + 1 << std::endl; @@ -248,3 +252,45 @@ static void encryption_plugin_init(int argc, char **argv) plugin_init(&argc, argv, PLUGIN_INIT_SKIP_PLUGIN_TABLE); } + +/* + Setup encryption_handler with default encryption to avoid crashes when + calling encryption_get_key +*/ +uint no_get_key(uint, uint, uchar*, uint*) +{ + return ENCRYPTION_KEY_VERSION_INVALID; +} +uint no_key(uint) +{ + return ENCRYPTION_KEY_VERSION_INVALID; +} + +static int ctx_init(void *ctx, const unsigned char* key, unsigned int klen, + const unsigned char* iv, unsigned int ivlen, int flags, + unsigned int key_id, unsigned int key_version) +{ + return my_aes_crypt_init(ctx, MY_AES_CBC, flags, key, klen, iv, ivlen); +} + +static unsigned int get_length(unsigned int slen, unsigned int key_id, + unsigned int key_version) +{ + return my_aes_get_size(MY_AES_CBC, slen); +} + +uint ctx_size(unsigned int, unsigned int) +{ + return MY_AES_CTX_SIZE; +} + +void initialize_default_encryption() +{ + encryption_handler.encryption_ctx_size_func= ctx_size; + encryption_handler.encryption_ctx_init_func= ctx_init; + encryption_handler.encryption_ctx_update_func= my_aes_crypt_update; + encryption_handler.encryption_ctx_finish_func= my_aes_crypt_finish; + encryption_handler.encryption_encrypted_length_func= get_length; + encryption_handler.encryption_key_get_func= no_get_key; + encryption_handler.encryption_key_get_latest_version_func= no_key; +} diff --git a/extra/mariabackup/innobackupex.cc b/extra/mariabackup/innobackupex.cc index 867afa1a6f47a..1c0bc11b45f21 100644 --- a/extra/mariabackup/innobackupex.cc +++ b/extra/mariabackup/innobackupex.cc @@ -447,7 +447,7 @@ static struct my_option ibx_long_options[] = {"startup-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, "This option specifies time in seconds that mariadb-backup should wait for " "BACKUP STAGE START to complete. BACKUP STAGE START has to wait until all " - "currently running queries using explicite LOCK TABLES has ended. " + "currently running queries using explicit LOCK TABLES has ended. " "If there are still such queries when the timeout expires, mariadb-backup " "terminates with an error. Default is 0, in which case mariadb-backup waits " "indefinitely for BACKUP STAGE START to finish", diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index d36011b5bf548..445e336734d5a 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -129,6 +129,7 @@ int sd_notifyf() { return 0; } } int sys_var_init(); +void sys_var_end(); extern const char* fts_common_tables[]; extern const fts_index_selector_t fts_index_selector[]; @@ -203,6 +204,8 @@ struct xb_filter_entry_t{ /** whether log_copying_thread() is active; protected by recv_sys.mutex */ static bool log_copying_running; +/** the log parsing function for --backup */ +static recv_sys_t::parser backup_log_parse; /** for --backup, target LSN to copy the log to; protected by recv_sys.mutex */ lsn_t metadata_to_lsn; @@ -373,6 +376,7 @@ my_bool tty_password= FALSE; my_bool opt_lock_ddl_per_table = FALSE; static my_bool opt_check_privileges; +my_bool opt_backup_binlog= TRUE; extern const char *innodb_checksum_algorithm_names[]; extern TYPELIB innodb_checksum_algorithm_typelib; @@ -395,6 +399,8 @@ char *opt_incremental_history_uuid; char *opt_user; const char *opt_password; +bool free_opt_password; +bool free_opt_binlog_directory= false; char *opt_host; char *opt_defaults_group; char *opt_socket; @@ -660,11 +666,12 @@ void CorruptedPages::zero_out_free_pages() if (!space) die("Can't find space object for space name %s to check corrupted page", space_name.c_str()); + mtr_t mtr{nullptr}; for (std::set::const_iterator page_it= space_it->second.pages.begin(); page_it != space_it->second.pages.end(); ++page_it) { - if (fseg_page_is_allocated(space, *page_it)) + if (fseg_page_is_allocated(&mtr, space, *page_it)) { space_info_t &space_info = non_free_pages[space_id]; space_info.pages.insert(*page_it); @@ -1232,7 +1239,7 @@ static void backup_file_op_fail(uint32_t space_id, int type, msg("DDL tracking : create %" PRIu32 " \"%.*s\"", space_id, int(len), name); fail = !check_if_skip_table(spacename.c_str()); - if (!opt_no_lock && fail && + if (fail && !opt_no_lock && check_if_fts_table(spacename.c_str())) { /* Ignore the FTS internal table because InnoDB does create intermediate table and their associative FTS @@ -1259,6 +1266,11 @@ static void backup_file_op_fail(uint32_t space_id, int type, break; case FILE_DELETE: fail = !check_if_skip_table(spacename.c_str()) + /* Ignore the FTS internal table because InnoDB may + drop intermediate table and their associative FTS + internal table as a part of inplace rollback operation. + backup_set_alter_copy_lock() downgrades the + MDL_BACKUP_DDL before inplace phase of alter */ && !check_if_fts_table(spacename.c_str()); msg("DDL tracking : delete %" PRIu32 " \"%.*s\"", space_id, int(len), name); @@ -1448,7 +1460,9 @@ enum options_xtrabackup OPT_XB_IGNORE_INNODB_PAGE_CORRUPTION, OPT_INNODB_FORCE_RECOVERY, OPT_INNODB_CHECKPOINT, - OPT_ARIA_LOG_DIR_PATH + OPT_ARIA_LOG_DIR_PATH, + OPT_BINLOG, + OPT_BINLOG_DIRECTORY }; struct my_option xb_client_options[]= { @@ -1798,7 +1812,7 @@ struct my_option xb_client_options[]= { {"startup-wait-timeout", OPT_LOCK_WAIT_TIMEOUT, "This option specifies time in seconds that mariadb-backup should wait for " "BACKUP STAGE START to complete. BACKUP STAGE START has to wait until all " - "currently running queries using explicite LOCK TABLES has ended. " + "currently running queries using explicit LOCK TABLES has ended. " "If there are still such queries when the timeout expires, mariadb-backup " "terminates with an error. Default is 0, in which case mariadb-backup waits " "indefinitely for BACKUP STAGE START to finish", @@ -1825,11 +1839,8 @@ struct my_option xb_client_options[]= { &opt_binlog_info, &opt_binlog_info, &binlog_info_typelib, GET_ENUM, OPT_ARG, BINLOG_INFO_AUTO, 0, 0, 0, 0, 0}, - {"secure-auth", OPT_XB_SECURE_AUTH, - "Refuse client connecting to server if it" - " uses old (pre-4.1.1) protocol.", - &opt_secure_auth, &opt_secure_auth, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, - 0}, + {"secure-auth", OPT_XB_SECURE_AUTH, "Unused", + 0, 0, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, {"log-innodb-page-corruption", OPT_XB_IGNORE_INNODB_PAGE_CORRUPTION, "Continue backup if innodb corrupted pages are found. The pages are " @@ -1960,7 +1971,7 @@ struct my_option xb_server_options[] = "Whether ib_logfile0 should be memory-mapped", (G_PTR*) &log_sys.log_mmap, (G_PTR*) &log_sys.log_mmap, 0, GET_BOOL, NO_ARG, - log_sys.log_mmap_default, 0, 0, 0, 0, 0}, + FALSE, 0, 0, 0, 0, 0}, #if defined __linux__ || defined _WIN32 {"innodb_log_file_buffering", OPT_INNODB_LOG_FILE_BUFFERING, "Whether the file system cache for ib_logfile0 is enabled during --backup", @@ -2099,7 +2110,7 @@ struct my_option xb_server_options[] = "(for --backup): Force an InnoDB checkpoint", (G_PTR*)&innodb_log_checkpoint_now, (G_PTR*)&innodb_log_checkpoint_now, - 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0}, {"mysqld-args", OPT_XTRA_MYSQLD_ARGS, "All arguments that follow this argument are considered as server " @@ -2113,6 +2124,24 @@ struct my_option xb_server_options[] = (G_PTR *) &xtrabackup_help, (G_PTR *) &xtrabackup_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"binlog", OPT_BINLOG, + "Backup the server binary logs. Only applies to server configured with " + "--binlog-storage-engine, old-style binlog is not backed up. Enabled by " + "default, specify --skip-binlog to not backup the binlog files. The " + "--skip-binlog option, if used, must be specified with both --backup and " + "--prepare", + (G_PTR*)&opt_backup_binlog, + (G_PTR*)&opt_backup_binlog, + 0, GET_BOOL, OPT_ARG, 1, 0, 0, 0, 0, 0}, + + {"binlog-directory", OPT_BINLOG_DIRECTORY, + "The directory into which to copy any binlog files in the backup. This can " + "be used to put binlog files in the correct location if the restored " + "server is to be configured with a non-default --binlog-directory. Only " + "used with --copy-back", + &opt_binlog_directory, &opt_binlog_directory, + 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -2428,6 +2457,10 @@ xb_get_one_option(const struct my_option *opt, if (my_handle_options_init_variables) fprintf(stderr, "Obsolete option: %s. Ignored\n", opt->name); break; + case OPT_BINLOG_DIRECTORY: + + ADD_PRINT_PARAM_OPT(opt_binlog_directory); + break; #define MYSQL_CLIENT #include "sslopt-case.h" #undef MYSQL_CLIENT @@ -2448,6 +2481,7 @@ xb_get_one_option(const struct my_option *opt, static bool innodb_init_param() { + static bool mysql_tmpdir_list_set= 0; if (!ut_is_2pow(log_sys.write_size)) { msg("InnoDB: innodb_log_write_ahead_size=%u" " is not a power of two", log_sys.write_size); @@ -2455,12 +2489,15 @@ static bool innodb_init_param() } srv_is_being_started = TRUE; /* === some variables from mysqld === */ - memset((G_PTR) &mysql_tmpdir_list, 0, sizeof(mysql_tmpdir_list)); - - if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) { - msg("init_tmpdir() failed"); - return true; - } + if (!mysql_tmpdir_list_set) + { + mysql_tmpdir_list_set= 1; + memset((G_PTR) &mysql_tmpdir_list, 0, sizeof(mysql_tmpdir_list)); + if (init_tmpdir(&mysql_tmpdir_list, opt_mysql_tmpdir)) { + msg("init_tmpdir() failed"); + return true; + } + } xtrabackup_tmpdir = my_tmpdir(&mysql_tmpdir_list); /* dummy for initialize all_charsets[] */ get_charset_name(0); @@ -2591,6 +2628,13 @@ static bool innodb_init_param() srv_undo_dir = (char*) "."; } + if (!opt_binlog_directory || !xtrabackup_backup) { + if (free_opt_binlog_directory) + my_free(const_cast(opt_binlog_directory)); + opt_binlog_directory = "."; + free_opt_binlog_directory= false; + } + compile_time_assert(SRV_FORCE_IGNORE_CORRUPT == 1); /* @@ -2628,7 +2672,10 @@ static byte log_hdr_buf[log_t::START_OFFSET + SIZE_OF_FILE_CHECKPOINT]; static void log_hdr_init() { memset(log_hdr_buf, 0, sizeof log_hdr_buf); - mach_write_to_4(LOG_HEADER_FORMAT + log_hdr_buf, log_t::FORMAT_10_8); + /* log_t::FORMAT_ENC_10_8 is written to the file as FORMAT_10_8 */ + mach_write_to_4(LOG_HEADER_FORMAT + log_hdr_buf, + log_sys.format == log_t::FORMAT_ENC_11 + ? log_t::FORMAT_ENC_11 : log_t::FORMAT_10_8); mach_write_to_8(LOG_HEADER_START_LSN + log_hdr_buf, log_sys.next_checkpoint_lsn); snprintf(reinterpret_cast(LOG_HEADER_CREATOR + log_hdr_buf), @@ -3460,87 +3507,51 @@ static bool xtrabackup_copy_mmap_logfile() recv_sys.len= size_t(log_sys.file_size); const size_t seq_offset{log_sys.is_encrypted() ? 8U + 5U : 5U}; const char one{'\1'}; + const byte *start= &log_sys.buf[recv_sys.offset]; + ut_d(recv_sys_t::parse_mtr_result r); - for (unsigned retry_count{0};;) + if ((ut_d(r=) backup_log_parse(false)) == recv_sys_t::OK) { - recv_sys_t::parse_mtr_result r; - const byte *start= &log_sys.buf[recv_sys.offset]; - - if (recv_sys.parse_mmap(false) == - recv_sys_t::OK) + do { - const byte *end; - - do + /* Set the sequence bit (the backed-up log will not wrap around) */ + size_t seqo= recv_sys.offset - seq_offset; + if (seqo < log_sys.START_OFFSET) + seqo+= static_cast(log_sys.file_size - log_sys.START_OFFSET); + const byte *seq= &log_sys.buf[seqo]; + ut_ad(*seq == log_sys.get_sequence_bit(recv_sys.lsn - seq_offset)); + if (!*seq) { - /* Set the sequence bit (the backed-up log will not wrap around) */ - size_t seqo= recv_sys.offset - seq_offset; - if (seqo < log_sys.START_OFFSET) - seqo+= static_cast(log_sys.file_size - log_sys.START_OFFSET); - const byte *seq= &log_sys.buf[seqo]; - ut_ad(*seq == log_sys.get_sequence_bit(recv_sys.lsn - seq_offset)); - if (!*seq) - { - if (xtrabackup_copy_mmap_snippet(dst_log_file, start, seq) || - ds_write(dst_log_file, &one, 1)) - goto write_error; - start = seq + 1; - } + if (xtrabackup_copy_mmap_snippet(dst_log_file, start, seq) || + ds_write(dst_log_file, &one, 1)) + goto write_error; + start = seq + 1; } - while ((r= recv_sys.parse_mmap(false)) == - recv_sys_t::OK); - - end= &log_sys.buf[recv_sys.offset]; - - if (xtrabackup_copy_mmap_snippet(dst_log_file, start, end)) - { - write_error: - msg("Error: write to ib_logfile0 failed"); - return true; - } - - start= end; - - pthread_cond_broadcast(&scanned_lsn_cond); - - if (r == recv_sys_t::GOT_EOF) - break; - - retry_count= 0; } - else - { - if (metadata_to_lsn) - { - if (metadata_to_lsn <= recv_sys.lsn) - return false; - } - else if (xtrabackup_throttle && io_ticket-- < 0) - mysql_cond_wait(&wait_throttle, &recv_sys.mutex); + while ((ut_d(r=) backup_log_parse(false)) == recv_sys_t::OK); - if (!retry_count++) - msg("Retrying read of log at LSN=" LSN_PF, recv_sys.lsn); - else if (retry_count == 100) - break; - else - { - timespec abstime; - set_timespec_nsec(abstime, 1000000ULL /* 1 ms */); - if (!mysql_cond_timedwait(&log_copying_stop, &recv_sys.mutex, - &abstime)) - return true; - } + if (xtrabackup_copy_mmap_snippet(dst_log_file, start, + &log_sys.buf[recv_sys.offset])) + { + write_error: + msg("Error: write to ib_logfile0 failed"); + return true; } + + pthread_cond_broadcast(&scanned_lsn_cond); } + ut_ad(r == recv_sys_t::GOT_EOF); + if (verbose) msg(">> log scanned up to (" LSN_PF ")", recv_sys.lsn); return false; } /** Copy redo log until the current end of the log is reached +@param early_exit parse and copy only logs from first read and return @return whether the operation failed */ -static bool xtrabackup_copy_logfile() +static bool xtrabackup_copy_logfile(bool early_exit) { mysql_mutex_assert_owner(&recv_sys.mutex); DBUG_EXECUTE_IF("log_checksum_mismatch", return false;); @@ -3556,7 +3567,6 @@ static bool xtrabackup_copy_logfile() recv_sys.offset= size_t(recv_sys.lsn - log_sys.get_first_lsn()) & block_size_1; - recv_sys.len= 0; for (unsigned retry_count{0};;) { @@ -3564,12 +3574,12 @@ static bool xtrabackup_copy_logfile() size_t start_offset{recv_sys.offset}; { + recv_sys.len= 0; { auto source_offset= - log_sys.calc_lsn_offset(recv_sys.lsn + recv_sys.len - - recv_sys.offset); + log_sys.calc_lsn_offset(recv_sys.lsn - recv_sys.offset); source_offset&= ~block_size_1; - size_t size{log_sys.buf_size - recv_sys.len}; + size_t size{log_sys.buf_size}; if (UNIV_UNLIKELY(source_offset + size > log_sys.file_size)) { const size_t first{size_t(log_sys.file_size - source_offset)}; @@ -3591,8 +3601,7 @@ static bool xtrabackup_copy_logfile() if (log_sys.buf[recv_sys.offset] <= 1) break; - if (recv_sys.parse_mtr(false) == - recv_sys_t::OK) + if (backup_log_parse(false) == recv_sys_t::OK) { do { @@ -3602,8 +3611,7 @@ static bool xtrabackup_copy_logfile() sequence_offset)); *seq= 1; } - while ((r= recv_sys.parse_mtr(false)) == - recv_sys_t::OK); + while ((r= backup_log_parse(false)) == recv_sys_t::OK); if (ds_write(dst_log_file, log_sys.buf + start_offset, recv_sys.offset - start_offset)) @@ -3611,32 +3619,25 @@ static bool xtrabackup_copy_logfile() msg("Error: write to ib_logfile0 failed"); return true; } - else - { - const auto ofs= recv_sys.offset & ~block_size_1; - memmove_aligned<64>(log_sys.buf, log_sys.buf + ofs, - recv_sys.len - ofs); - recv_sys.len-= ofs; - recv_sys.offset&= block_size_1; - } - pthread_cond_broadcast(&scanned_lsn_cond); - if (r == recv_sys_t::GOT_EOF) + if (r == recv_sys_t::GOT_EOF || early_exit) break; + ut_ad(r == recv_sys_t::PREMATURE_EOF); + if (recv_sys.offset < log_sys.write_size) break; if (xtrabackup_throttle && io_ticket-- < 0) mysql_cond_wait(&wait_throttle, &recv_sys.mutex); + recv_sys.offset&= block_size_1; retry_count= 0; continue; } else { - recv_sys.len= recv_sys.offset & ~block_size_1; if (retry_count == 100) break; @@ -3716,7 +3717,7 @@ static void log_copying_thread() { my_thread_init(); mysql_mutex_lock(&recv_sys.mutex); - while (!xtrabackup_copy_logfile() && + while (!xtrabackup_copy_logfile(false) && (!metadata_last_lsn || metadata_last_lsn > recv_sys.lsn)) { timespec abstime; @@ -4934,7 +4935,7 @@ static bool backup_wait_for_commit_lsn() ut_ad(metadata_to_lsn); metadata_last_lsn= lsn; - last_lsn= backup_wait_for_lsn_low(LSN_MAX); + last_lsn= backup_wait_for_lsn_low(lsn); metadata_last_lsn= last_lsn; stop_backup_threads(); @@ -5425,6 +5426,29 @@ class BackupStages { return res; } + bool do_backup_binlogs() { + // Copy InnoDB binlog files. + // Going to BACKUP STAGE START protects against RESET + // MASTER deleting files during the copy, or FLUSH + // BINARY LOGS truncating them. + if (!opt_no_lock) + xb_mysql_query(mysql_connection, "BACKUP STAGE START", + false, false); + if (!m_common_backup.copy_engine_binlogs(opt_binlog_directory, + recv_sys.lsn)) { + msg("Error on copy InnoDB binlog files"); + return false; + } + if (!m_common_backup.wait_for_finish()) { + msg("InnoDB binlog file backup process is finished with error"); + return false; + } + if (!opt_no_lock) + xb_mysql_query(mysql_connection, "BACKUP STAGE END", + false, false); + return true; + } + bool stage_end(Backup_datasinks &backup_datasinks) { msg("Starting BACKUP STAGE END"); /* release all locks */ @@ -5445,6 +5469,11 @@ class BackupStages { nullptr); ); + if (opt_backup_binlog) { + if (!do_backup_binlogs()) + return false; + } + backup_finish(backup_datasinks.m_data); return true; } @@ -5490,12 +5519,14 @@ static bool xtrabackup_backup_func() } msg("cd to %s", mysql_real_data_home); encryption_plugin_backup_init(mysql_connection); - if (innodb_log_checkpoint_now != false && mysql_send_query( - mysql_connection, + if (innodb_log_checkpoint_now) { + msg("Initiating checkpoint"); + if (mysql_send_query(mysql_connection, C_STRING_WITH_LEN("SET GLOBAL " "innodb_log_checkpoint_now=ON;"))) { - msg("initiating checkpoint failed"); - return(false); + msg("initiating checkpoint failed"); + return(false); + } } msg("open files limit requested %lu, set to %lu", @@ -5536,12 +5567,14 @@ static bool xtrabackup_backup_func() if (fil_system.is_initialised()) { innodb_shutdown(); } + backup_datasinks.destroy(); return(false); } srv_thread_pool_init(); /* Reset the system variables in the recovery module. */ trx_pool_init(); + btr_search_sys_create(); recv_sys.create(); xb_filters_init(); @@ -5609,6 +5642,7 @@ static bool xtrabackup_backup_func() server does not support this */ if (innodb_log_checkpoint_now != false) { mysql_read_query_result(mysql_connection); + msg("Finished waiting for checkpoint"); } if (!select_history()) { @@ -5646,9 +5680,10 @@ static bool xtrabackup_backup_func() /* copy log file by current position */ mysql_mutex_lock(&recv_sys.mutex); + backup_log_parse = recv_sys.get_backup_parser(); recv_sys.lsn = log_sys.next_checkpoint_lsn; - const bool log_copy_failed = xtrabackup_copy_logfile(); + const bool log_copy_failed = xtrabackup_copy_logfile(true); mysql_mutex_unlock(&recv_sys.mutex); @@ -5875,7 +5910,7 @@ void CorruptedPages::backup_fix_ddl(ds_ctxt *ds_data, ds_ctxt *ds_meta) } /* Mariabackup doesn't detect any FILE_OP for the deferred - tablespace. There is a possiblity that page0 could've + tablespace. There is a possibility that page0 could've been corrupted persistently in the disk */ for (auto space_name: defer_space_names) { if (!check_if_skip_table(space_name.c_str())) { @@ -5906,6 +5941,8 @@ void CorruptedPages::backup_fix_ddl(ds_ctxt *ds_data, ds_ctxt *ds_meta) node, 0, dest_name.c_str(), wf_write_through, *this); } + + DBUG_MARIABACKUP_EVENT("after_backup_fix_ddl", {}); } @@ -6149,16 +6186,12 @@ xb_delta_open_matching_space( ut_ad(fil_space_t::physical_size(flags) == info.page_size); mysql_mutex_lock(&fil_system.mutex); - fil_space_t* space = fil_space_t::create(uint32_t(info.space_id), - flags, false, 0, - FIL_ENCRYPTION_DEFAULT, true); + std::ignore = fil_space_t::create(uint32_t(info.space_id), + flags, false, 0, + FIL_ENCRYPTION_DEFAULT, true); mysql_mutex_unlock(&fil_system.mutex); - if (space) { - *success = xb_space_create_file(real_name, info.space_id, - flags, &file); - } else { - msg("Can't create tablespace %s\n", dest_space_name); - } + *success = xb_space_create_file(real_name, info.space_id, + flags, &file); goto exit; } @@ -6687,7 +6720,6 @@ void innodb_free_param() { srv_sys_space.shutdown(); - free_tmpdir(&mysql_tmpdir_list); } @@ -7336,6 +7368,8 @@ void setup_error_messages() void handle_options(int argc, char **argv, char ***argv_server, char ***argv_client, char ***argv_backup) { + char **save_argv_server, **save_argv_client, **save_argv_backup; + /* Setup some variables for Innodb.*/ srv_operation = SRV_OPERATION_RESTORE; @@ -7453,6 +7487,7 @@ void handle_options(int argc, char **argv, char ***argv_server, load_defaults_or_exit(conf_file, &server_default_groups[0], &argc_server, argv_server); + save_argv_server= *argv_server; int n; for (n = 0; (*argv_server)[n]; n++) {}; @@ -7498,6 +7533,7 @@ void handle_options(int argc, char **argv, char ***argv_server, load_defaults_or_exit(conf_file, xb_client_default_groups, &argc_client, argv_client); + save_argv_client= *argv_client; for (n = 0; (*argv_client)[n]; n++) {}; argc_client = n; @@ -7518,6 +7554,8 @@ void handle_options(int argc, char **argv, char ***argv_server, load_defaults_or_exit(conf_file, backup_default_groups, &argc_backup, argv_backup); + save_argv_backup= *argv_backup; + for (n= 0; (*argv_backup)[n]; n++) { }; @@ -7545,12 +7583,13 @@ void handle_options(int argc, char **argv, char ***argv_server, xb_client_options, xb_get_one_option))) exit(ho_error); - if (opt_password) + if (opt_password && strlen(opt_password)) { char *argument= (char*) opt_password; char *start= (char*) opt_password; opt_password= my_strdup(PSI_NOT_INSTRUMENTED, opt_password, MYF(MY_FAE)); + free_opt_password= 1; while (*argument) *argument++= 'x'; // Destroy argument if (*start) @@ -7598,6 +7637,14 @@ void handle_options(int argc, char **argv, char ***argv_server, } } } + /* + Restore load defaults argument to the value after + load_defaults_or_exit(). This is needed for caller + when calling free_defaults() + */ + *argv_server= save_argv_server; + *argv_client= save_argv_client; + *argv_backup= save_argv_backup; } static int main_low(char** argv); @@ -7702,10 +7749,23 @@ int main(int argc, char **argv) cleanup_errmsgs(); free_error_messages(); mysql_mutex_destroy(&LOCK_error_log); + free_tmpdir(&mysql_tmpdir_list); + if (free_opt_password) + my_free((char*) opt_password); + plugin_shutdown(); + free_list(opt_plugin_load_list_ptr); + if (free_opt_binlog_directory) + my_free(const_cast(opt_binlog_directory)); + mysql_server_end(); + sys_var_end(); if (status == EXIT_SUCCESS) { - msg("completed OK!"); + msg("completed OK!"); } + my_end(MY_CHECK_ERROR); + sf_leaking_memory= 0; + if (SAFEMALLOC_HAVE_MEMORY_LEAK) + status= EXIT_FAILURE; return status; } diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index 38d7e5fdd03d1..d7f3435871f4c 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -151,6 +151,7 @@ extern char *opt_incremental_history_uuid; extern char *opt_user; extern const char *opt_password; +extern bool free_opt_binlog_directory; extern char *opt_host; extern char *opt_defaults_group; extern char *opt_socket; @@ -178,6 +179,7 @@ extern const char *opt_history; enum binlog_info_enum { BINLOG_INFO_OFF, BINLOG_INFO_LOCKLESS, BINLOG_INFO_ON, BINLOG_INFO_AUTO}; +extern bool backup_binlog; extern ulong opt_binlog_info; extern ulong xtrabackup_innodb_force_recovery; diff --git a/extra/perror.c b/extra/perror.c index 83b8d6eb8cd94..3b7e9663f2d70 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -354,7 +354,8 @@ int main(int argc,char *argv[]) found= 1; if (verbose) printf("MariaDB error code %3d (%s): %s\n" - "Learn more: https://mariadb.com/kb/en/e%3d/\n", code, name, msg, code); + "Learn more: https://err.mariadb.com/%3d\n", + code, name, msg, code); else puts(msg); } diff --git a/extra/wolfssl/wolfssl b/extra/wolfssl/wolfssl index b077c81eb6353..59f4fa5686153 160000 --- a/extra/wolfssl/wolfssl +++ b/extra/wolfssl/wolfssl @@ -1 +1 @@ -Subproject commit b077c81eb635392e694ccedbab8b644297ec0285 +Subproject commit 59f4fa568615396fbf381b073b220d1e8d61e4c2 diff --git a/include/aria_backup.h b/include/aria_backup.h index f399f6a6f40d9..dc931dbd33c48 100644 --- a/include/aria_backup.h +++ b/include/aria_backup.h @@ -15,11 +15,15 @@ /* Interfaces for doing backups of Aria tables */ +#ifndef ARIA_BACKUP_INCLUDED + C_MODE_START typedef struct st_aria_table_capabilities { my_off_t header_size; + MARIA_CRYPT_DATA *crypt_data; + uint crypt_page_header_space; ulong bitmap_pages_covered; uint block_size; uint keypage_header; @@ -32,11 +36,15 @@ typedef struct st_aria_table_capabilities /* s3 capabilities */ ulong s3_block_size; uint8 compression; + char filename[FN_REFLEN]; } ARIA_TABLE_CAPABILITIES; -int aria_get_capabilities(File kfile, ARIA_TABLE_CAPABILITIES *cap); +int aria_get_capabilities(File kfile, const char *table_name, ARIA_TABLE_CAPABILITIES *cap); +void aria_free_capabilities(ARIA_TABLE_CAPABILITIES *cap); int aria_read_index(File kfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, uchar *buffer); int aria_read_data(File dfile, ARIA_TABLE_CAPABILITIES *cap, ulonglong block, uchar *buffer, size_t *bytes_read); C_MODE_END + +#endif /* ARIA_BACKUP_INCLUDED */ diff --git a/include/handler_binlog_reader.h b/include/handler_binlog_reader.h new file mode 100644 index 0000000000000..be97c14111fa4 --- /dev/null +++ b/include/handler_binlog_reader.h @@ -0,0 +1,97 @@ +#ifndef HANDLER_BINLOG_READER_INCLUDED +#define HANDLER_BINLOG_READER_INCLUDED + +/* Copyright (c) 2025, Kristian Nielsen. + + 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 */ + + +class String; +class THD; +struct slave_connection_state; +struct rpl_binlog_state_base; + + +/* + Class for reading a binlog implemented in an engine. +*/ +class handler_binlog_reader { +public: + /* + Approximate current position (from which next call to read_binlog_data() + will need to read). Updated by the engine. Used to know which binlog files + the active dump threads are currently reading from, to avoid purging + actively used binlogs. + */ + uint64_t cur_file_no; + uint64_t cur_file_pos; + +private: + /* Position and length of any remaining data in buf[]. */ + uint32_t buf_data_pos; + uint32_t buf_data_remain; + /* Buffer used when reading data out via read_binlog_data(). */ + static constexpr size_t BUF_SIZE= 32768; + uchar *buf; + +public: + handler_binlog_reader() + : cur_file_no(~(uint64_t)0), cur_file_pos(~(uint64_t)0), + buf_data_pos(0), buf_data_remain(0) + { + buf= (uchar *)my_malloc(PSI_INSTRUMENT_ME, BUF_SIZE, MYF(0)); + } + virtual ~handler_binlog_reader() { + my_free(buf); + }; + virtual int read_binlog_data(uchar *buf, uint32_t len) = 0; + virtual bool data_available()= 0; + /* + Wait for data to be available to read, for kill, or for timeout. + Returns true in case of timeout reached, false otherwise. + Caller should check for kill before calling again (to avoid busy-loop). + */ + virtual bool wait_available(THD *thd, const struct timespec *abstime) = 0; + /* + This initializes the current read position to the point of the slave GTID + position passed in as POS. It is permissible to start at a position a bit + earlier in the binlog, only cost is the extra read cost of reading not + needed event data. + + If position is found, must return the corresponding binlog state in the + STATE output parameter and initialize cur_file_no and cur_file_pos members. + + Returns: + -1 Error + 0 The requested GTID position not found, needed binlogs have been purged + 1 Ok, position found and returned. + */ + virtual int init_gtid_pos(THD *thd, slave_connection_state *pos, + rpl_binlog_state_base *state) = 0; + /* + Initialize to a legacy-type position (filename, offset). This mostly to + support legacy SHOW BINLOG EVENTS. + */ + virtual int init_legacy_pos(THD *thd, const char *filename, + ulonglong offset) = 0; + /* + Can be called after init_gtid_pos() or init_legacy_pos() to make the reader + stop (return EOF) at the end of the binlog file. Used for SHOW BINLOG + EVENTS, which has a file-based interface based on legacy file name. + */ + virtual void enable_single_file() = 0; + int read_log_event(String *packet, uint32_t ev_offset, size_t max_allowed); +}; + +#endif /* HANDLER_BINLOG_READER_INCLUDED */ diff --git a/include/ilist.h b/include/ilist.h index 3349959e17e0e..46f706eaef9f3 100644 --- a/include/ilist.h +++ b/include/ilist.h @@ -189,6 +189,9 @@ template class ilist ListNode *prev= pos.node_->prev; ListNode *next= pos.node_->next; + DBUG_ASSERT(prev->next == pos.node_); + DBUG_ASSERT(next->prev == pos.node_); + prev->next= next; next->prev= prev; @@ -202,7 +205,7 @@ template class ilist } void push_back(reference value) noexcept { insert(end(), value); } - void pop_back() noexcept { erase(end()); } + void pop_back() noexcept { erase(--end()); } void push_front(reference value) noexcept { insert(begin(), value); } void pop_front() noexcept { erase(begin()); } diff --git a/include/json_lib.h b/include/json_lib.h index c619ad9d91574..13fbfed0186f6 100644 --- a/include/json_lib.h +++ b/include/json_lib.h @@ -7,8 +7,27 @@ extern "C" { #endif -#define JSON_DEPTH_LIMIT 32 +#define JSON_DEPTH_DEFAULT 32 +#define JSON_DEPTH_LIMIT 32 /* Still used in columnstore. */ +#define JSON_DEPTH_INC JSON_DEPTH_DEFAULT*100 +/* + Because this array will store approximate two arrays of + type json_path_step_t and one or two integer arrays, + each of average 70 elements. So this size should suffice. +*/ +#define BLOCK_SIZE_JSON_DYN_ARRAY 4096 + +#define get_json_step(p,s) if (p->last_step_idx < (int)(p->steps.max_element)) \ + s= ((json_path_step_t*)(p->steps.buffer))+p->last_step_idx; \ + else \ + s= (json_path_step_t*) mem_root_dynamic_array_resize_and_get_val(&p->steps, p->last_step_idx); + +#define set_json_array_value_ptr(idx, max_element, dyn_arr_ptr, val) \ + if ((size_t)(idx) < (max_element)) \ + memcpy((dyn_arr_ptr)->buffer + (dyn_arr_ptr)->size_of_element * (idx), &(val), sizeof(val)); \ + else \ + mem_root_dynamic_array_resize_and_set_val((dyn_arr_ptr), &(val), (idx)); /* When error happens, the c_next of the JSON engine contains the character that caused the error, and the c_str is the position @@ -28,7 +47,7 @@ enum json_errors { JE_ESCAPING= -6, /* Error in the escaping. */ - JE_DEPTH= -7, /* The limit on the JSON depth was overrun. */ + JE_DEPTH= -7, /* The limit on the JSON depth was overrun. Still used in columnstore*/ }; @@ -104,8 +123,8 @@ typedef struct st_json_path_step_t typedef struct st_json_path_t { json_string_t s; /* The string to be parsed. */ - json_path_step_t steps[JSON_DEPTH_LIMIT]; /* Steps of the path. */ - json_path_step_t *last_step; /* Points to the last step. */ + MEM_ROOT_DYNAMIC_ARRAY steps; /* Steps of the path. */ + int last_step_idx; int mode_strict; /* TRUE if the path specified as 'strict' */ enum json_path_step_types types_used; /* The '|' of all step's 'type'-s */ @@ -225,8 +244,8 @@ typedef struct st_json_engine_t const uchar *value_end; /* Points to the next character after the value. */ int value_len; /* The length of the value. Does not count quotations for */ /* string constants. */ - - int stack[JSON_DEPTH_LIMIT]; /* Keeps the stack of nested JSON structures. */ + /* Keeps the stack of nested JSON structures. */ + MEM_ROOT_DYNAMIC_ARRAY stack; int stack_p; /* The 'stack' pointer. */ volatile uchar *killed_ptr; } json_engine_t; @@ -341,6 +360,13 @@ int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped); */ #define json_value_scalar(je) ((je)->value_type > JSON_VALUE_ARRAY) +#define report_json_error(js, je, n_param) \ + report_json_error_ex(js->ptr(), je, func_name(), n_param, \ + Sql_condition::WARN_LEVEL_WARN) + +#define report_path_error(js, je, n_param) \ + report_path_error_ex(js->ptr(), je, func_name(), n_param,\ + Sql_condition::WARN_LEVEL_WARN) /* Look for the JSON PATH in the json string. @@ -350,7 +376,7 @@ int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped); initialized with the JSON string, and the json_path_t with the JSON path appropriately. The 'p_cur_step' should point at the first step of the path. - The 'array_counters' is the array of JSON_DEPTH_LIMIT size. + The 'array_counters' is the array of 'curr_json_depth_limit' size. It stores the array counters of the parsed JSON. If function returns 0, it means it found the match. The position of the match is je->s.c_str. Then we can call the json_find_path() @@ -360,7 +386,7 @@ int json_skip_level_and_count(json_engine_t *j, int *n_items_skipped); */ int json_find_path(json_engine_t *je, json_path_t *p, json_path_step_t **p_cur_step, - int *array_counters); + MEM_ROOT_DYNAMIC_ARRAY *array_counters); typedef struct st_json_find_paths_t @@ -369,7 +395,7 @@ typedef struct st_json_find_paths_t json_path_t *paths; uint cur_depth; uint *path_depths; - int array_counters[JSON_DEPTH_LIMIT]; + MEM_ROOT_DYNAMIC_ARRAY array_counters; } json_find_paths_t; @@ -431,17 +457,22 @@ int json_get_path_start(json_engine_t *je, CHARSET_INFO *i_cs, int json_get_path_next(json_engine_t *je, json_path_t *p); int json_path_compare(const json_path_t *a, const json_path_t *b, - enum json_value_types vt, const int* array_size_counter); + enum json_value_types vt, + MEM_ROOT_DYNAMIC_ARRAY* array_size_counter); -int json_valid(const char *js, size_t js_len, CHARSET_INFO *cs); +int json_valid(const char *js, size_t js_len, + CHARSET_INFO *cs, json_engine_t *je); -int json_locate_key(const char *js, const char *js_end, +int json_locate_key(json_engine_t *je, const char *js, const char *js_end, const char *kname, const char **key_start, const char **key_end, int *comma_pos); int json_normalize(DYNAMIC_STRING *result, - const char *s, size_t size, CHARSET_INFO *cs); + const char *s, size_t size, CHARSET_INFO *cs, + MEM_ROOT *current_mem_root, + json_engine_t *temp_je, + MEM_ROOT_DYNAMIC_ARRAY *stack); int json_skip_array_and_count(json_engine_t *j, int* n_item); @@ -450,6 +481,8 @@ inline static int json_scan_ended(json_engine_t *j) return (j->state == JST_ARRAY_END && j->stack_p == 0); } +void initJsonArray(MEM_ROOT *mem_root, MEM_ROOT_DYNAMIC_ARRAY *mem_root_array, size_t size, void *buffer, myf myflag); + #ifdef __cplusplus } #endif diff --git a/include/m_ctype.h b/include/m_ctype.h index c029f36c5bf32..d8e11012d5e3e 100644 --- a/include/m_ctype.h +++ b/include/m_ctype.h @@ -23,6 +23,8 @@ #include #include +/* Provides portable uint64 type uint64_t */ +#include enum loglevel { ERROR_LEVEL= 0, @@ -186,6 +188,15 @@ typedef struct my_uca_level_booster_t This array is used for prefix optimization. */ MY_UCA_WEIGHT2 weight_strings_2bytes_to_1_or_2_weights[0x10000]; + + /* + A helper array to process one-character ASCII strings. + Suitable only for stand-alone characters, + which are known not to be contraction parts, + e.g. the very last character of a string. + */ + uint16 weight_1byte_to_1weight_standalone[0x100]; + } MY_UCA_LEVEL_BOOSTER; @@ -495,13 +506,58 @@ typedef struct my_charset_loader_st extern int (*my_string_stack_guard)(int); +typedef struct my_hasher_st +{ + union { + struct { + ulong m_nr1; /* mysql5x hash value */ + ulong m_nr2; /* mysql5x aux value */ + }; + uint64_t m_nr; /* The hash value */ + }; + /* Whether a streaming algorithm has been in use */ + my_bool m_streaming; + /* One-shot string hash function */ + void (*m_hash_str)(struct my_hasher_st *hasher, const uchar* str, + size_t len); + /* + Byte-streaming hash function, fallback to m_hash_str on one byte + if NULL + */ + void (*m_hash_byte)(struct my_hasher_st *hasher, uchar value); + /* + One-shot number hash function. This is for backward compatibility: + mysql5x algorithms hashes numerical fields as if they are strings + (by using my_charset_latin1's hash_sort function), but new + algorithms should use the default my_hasher_hash_num which uses + my_charset_bin's hash_sort function + */ + void (*m_hash_num)(struct my_hasher_st *hasher, const uchar* num, + size_t binary_size); + /* Function to clean up and return the hash value */ + uint64_t (*m_finalize)(struct my_hasher_st *hasher); + /* Custom pointer e.g. to a state */ + void *m_specific; +} my_hasher_st; + +/* Defined in hasher-xxx.c files */ +extern my_hasher_st my_hasher_mysql5x(void); +extern my_hasher_st my_hasher_mysql5x_for_unique(void); +extern my_hasher_st my_hasher_base31(void); +extern my_hasher_st my_hasher_crc32c(void); +extern my_hasher_st my_hasher_xxh32(void); +extern my_hasher_st my_hasher_xxh3(void); + +#define MY_HASH_ADD_MARIADB(A, B, value) \ + do { A^= (((A & 63)+B)*((value)))+ (A << 8); B+=3; } while(0) + /* See strings/CHARSET_INFO.txt for information about this structure */ struct my_collation_handler_st { my_bool (*init)(struct charset_info_st *, MY_CHARSET_LOADER *); /* Collation routines */ int (*strnncoll)(CHARSET_INFO *, - const uchar *, size_t, const uchar *, size_t, my_bool); + const uchar *, size_t, const uchar *, size_t, my_bool*); int (*strnncollsp)(CHARSET_INFO *, const uchar *, size_t, const uchar *, size_t); /* @@ -580,8 +636,8 @@ struct my_collation_handler_st my_match_t *match, uint nmatch); /* Hash calculation */ - void (*hash_sort)(CHARSET_INFO *cs, const uchar *key, size_t len, - ulong *nr1, ulong *nr2); + void (*hash_sort)(my_hasher_st *hasher, CHARSET_INFO *cs, const uchar *key, + size_t len); my_bool (*propagate)(CHARSET_INFO *cs, const uchar *str, size_t len); /* Make minimum and maximum strings for the collation. @@ -660,6 +716,7 @@ struct my_charset_handler_st size_t (*numchars)(CHARSET_INFO *, const char *b, const char *e); size_t (*charpos)(CHARSET_INFO *, const char *b, const char *e, size_t pos); + /* Length without trailing space */ size_t (*lengthsp)(CHARSET_INFO *, const char *ptr, size_t length); size_t (*numcells)(CHARSET_INFO *, const char *b, const char *e); @@ -1090,22 +1147,23 @@ struct charset_info_st } int strnncoll(const LEX_CSTRING a, const LEX_CSTRING b, - my_bool b_is_prefix= FALSE) const + my_bool *b_is_prefix= 0) const { DBUG_ASSERT(is_valid_string(a)); DBUG_ASSERT(is_valid_string(b)); return (coll->strnncoll)(this, (const uchar *) a.str, a.length, - (const uchar *) b.str, b.length, b_is_prefix); + (const uchar *) b.str, b.length, + b_is_prefix); } int strnncoll(const uchar *a, size_t alen, - const uchar *b, size_t blen, my_bool b_is_prefix= FALSE) const + const uchar *b, size_t blen, my_bool *b_is_prefix= 0) const { return (coll->strnncoll)(this, a, alen, b, blen, b_is_prefix); } int strnncoll(const char *a, size_t alen, - const char *b, size_t blen, my_bool b_is_prefix= FALSE) const + const char *b, size_t blen, my_bool *b_is_prefix= 0) const { return (coll->strnncoll)(this, (const uchar *) a, alen, @@ -1182,9 +1240,9 @@ struct charset_info_st return (coll->instr)(this, b, b_length, s, s_length, match, nmatch); } - void hash_sort(const uchar *key, size_t len, ulong *nr1, ulong *nr2) const + void hash_sort(my_hasher_st *hasher, const uchar *key, size_t len) const { - (coll->hash_sort)(this, key, len, nr1, nr2); + (coll->hash_sort)(hasher, this, key, len); } my_bool propagate(const uchar *str, size_t len) const @@ -1422,7 +1480,7 @@ static inline int my_ci_strnncoll(CHARSET_INFO *ci, const uchar *a, size_t alen, const uchar *b, size_t blen, - my_bool b_is_prefix) + my_bool *b_is_prefix) { return (ci->coll->strnncoll)(ci, a, alen, b, blen, b_is_prefix); } @@ -1435,6 +1493,16 @@ my_ci_strnncollsp(CHARSET_INFO *ci, return (ci->coll->strnncollsp)(ci, a, alen, b, blen); } +static inline int +my_ci_strnncollsp_nchars(CHARSET_INFO *ci, + const uchar *a, size_t alen, + const uchar *b, size_t blen, + size_t nchars, + uint flags) +{ + return (ci->coll->strnncollsp_nchars)(ci, a, alen, b, blen, nchars, flags); +} + static inline my_bool my_ci_like_range(CHARSET_INFO *ci, @@ -1462,11 +1530,10 @@ my_ci_instr(CHARSET_INFO *ci, static inline void -my_ci_hash_sort(CHARSET_INFO *ci, - const uchar *key, size_t len, - ulong *nr1, ulong *nr2) +my_ci_hash_sort(my_hasher_st *hasher, CHARSET_INFO *ci, + const uchar *key, size_t len) { - (ci->coll->hash_sort)(ci, key, len, nr1, nr2); + (ci->coll->hash_sort)(hasher, ci, key, len); } @@ -1580,22 +1647,24 @@ const uint16 *my_cs_contraction2_weight(CHARSET_INFO *cs, my_wc_t wc1, /* declarations for simple charsets */ extern int my_strnncoll_simple(CHARSET_INFO *, const uchar *, size_t, - const uchar *, size_t, my_bool); + const uchar *, size_t, my_bool*); extern int my_strnncollsp_simple(CHARSET_INFO *, const uchar *, size_t, const uchar *, size_t); -extern void my_hash_sort_simple(CHARSET_INFO *cs, - const uchar *key, size_t len, - ulong *nr1, ulong *nr2); +extern void my_hash_sort_simple(my_hasher_st *hasher, + CHARSET_INFO *cs, + const uchar *key, size_t len); + +extern void my_hash_sort_simple_nopad(my_hasher_st *hasher, + CHARSET_INFO *cs, + const uchar *key, size_t len); -extern void my_hash_sort_simple_nopad(CHARSET_INFO *cs, - const uchar *key, size_t len, - ulong *nr1, ulong *nr2); +extern void my_hash_sort_bin(my_hasher_st *hasher, CHARSET_INFO *cs, + const uchar *key, size_t len); -extern void my_hash_sort_bin(CHARSET_INFO *cs, - const uchar *key, size_t len, ulong *nr1, - ulong *nr2); +extern void my_hasher_hash_num(struct my_hasher_st *hasher, + const uchar* num, size_t binary_size); /** Compare a string to an array of spaces, for PAD SPACE comparison. @@ -1761,12 +1830,13 @@ int my_wildcmp_mb_bin(CHARSET_INFO *cs, const char *wildstr,const char *wildend, int escape, int w_one, int w_many); -void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)), - const uchar *key, size_t len,ulong *nr1, ulong *nr2); +void my_hash_sort_mb_bin(my_hasher_st *hasher, + CHARSET_INFO *cs __attribute__((unused)), + const uchar *key, size_t len); -void my_hash_sort_mb_nopad_bin(CHARSET_INFO *cs __attribute__((unused)), - const uchar *key, size_t len, - ulong *nr1, ulong *nr2); +void my_hash_sort_mb_nopad_bin(my_hasher_st *hasher, + CHARSET_INFO *cs __attribute__((unused)), + const uchar *key, size_t len); extern my_bool my_parse_charset_xml(MY_CHARSET_LOADER *loader, @@ -1997,6 +2067,10 @@ class Well_formed_prefix: public Well_formed_prefix_status :Well_formed_prefix_status(cs, str.str, str.str + str.length, nchars), m_str(str.str) { } + Well_formed_prefix(CHARSET_INFO *cs, LEX_CSTRING str) + :Well_formed_prefix_status(cs, str.str, str.str + str.length, str.length), + m_str(str.str) + { } size_t length() const { return m_source_end_pos - m_str; } }; diff --git a/include/m_string.h b/include/m_string.h index 060ab2c21d1f8..04b1a70ad40eb 100644 --- a/include/m_string.h +++ b/include/m_string.h @@ -80,12 +80,6 @@ extern const char _dig_vec_lower[]; extern char *strmov_overlapp(char *dest, const char *src); -#if defined(_lint) || defined(FORCE_INIT_OF_VARS) -#define LINT_INIT_STRUCT(var) bzero(&var, sizeof(var)) /* No uninitialize-warning */ -#else -#define LINT_INIT_STRUCT(var) -#endif - /* Prototypes for string functions */ extern void bmove_upp(uchar *dst,const uchar *src,size_t len); @@ -325,6 +319,9 @@ static inline int safe_strcat(char *dst, size_t dst_size, const char *src) #ifdef __cplusplus static inline char *safe_str(char *str) { return str ? str : const_cast(""); } + +static inline const char *safe_str(const LEX_CSTRING *lcs) +{ return lcs && lcs->str ? lcs->str : ""; } #endif static inline const char *safe_str(const char *str) diff --git a/include/maria.h b/include/maria.h index 0fe5d76598f78..68e278f98453b 100644 --- a/include/maria.h +++ b/include/maria.h @@ -147,6 +147,8 @@ extern int maria_create(const char *name, enum data_file_type record_type, uint uniques, MARIA_UNIQUEDEF *uniquedef, MARIA_CREATE_INFO *create_info, uint flags); +extern void aria_reset_pagecache_counters(); + #ifdef __cplusplus } #endif diff --git a/include/my_base.h b/include/my_base.h index 21f6e1dfcb5e1..8fdd1397ff09d 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -51,6 +51,13 @@ #define HA_OPEN_FOR_DROP (1U << 13) /* Open part of drop */ #define HA_OPEN_GLOBAL_TMP_TABLE (1U << 14) /* TMP table used by repliction */ #define HA_OPEN_SIZE_TRACKING (1U << 15) +/* + This is to signal that the table will not be cached by the caller + and the table should be open in read-only mode if the tool requests + that +*/ +#define HA_OPEN_FORCE_MODE (1U << 16) /* Force open mode */ +#define HA_OPEN_DATA_READONLY (1U << 17) /* Use readonly for data */ /* Allow opening even if table is incompatible as this is for ALTER TABLE which diff --git a/include/my_bit.h b/include/my_bit.h index 9179e0a85efdd..64097a750ac24 100644 --- a/include/my_bit.h +++ b/include/my_bit.h @@ -221,4 +221,72 @@ static inline uint my_find_first_bit(ulonglong n) } C_MODE_END +/* +The helper function my_nlz(x) calculates the number of leading zeros +in the binary representation of the number "x", either using a +built-in compiler function or a substitute trick based on the use +of the multiplication operation and a table indexed by the prefix +of the multiplication result: + +Moved to mysys from ha_innodb.cc to be able to use in non-InnoDB code. +*/ +#ifdef __GNUC__ +#define my_nlz(x) __builtin_clzll(x) +#elif defined(_MSC_VER) && !defined(_M_CEE_PURE) && \ + (defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64)) +#ifndef __INTRIN_H_ +#pragma warning(push, 4) +#pragma warning(disable: 4255 4668) +#include +#pragma warning(pop) +#endif +__forceinline unsigned int my_nlz (unsigned long long x) +{ +#if defined(_M_IX86) || defined(_M_X64) + unsigned long n; +#ifdef _M_X64 + _BitScanReverse64(&n, x); + return (unsigned int) n ^ 63; +#else + unsigned long y = (unsigned long) (x >> 32); + unsigned int m = 31; + if (y == 0) + { + y = (unsigned long) x; + m = 63; + } + _BitScanReverse(&n, y); + return (unsigned int) n ^ m; +#endif +#elif defined(_M_ARM64) + return _CountLeadingZeros64(x); +#endif +} +#else +inline unsigned int my_nlz (unsigned long long x) +{ + static unsigned char table [48] = { + 32, 6, 5, 0, 4, 12, 0, 20, + 15, 3, 11, 0, 0, 18, 25, 31, + 8, 14, 2, 0, 10, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 19, 26, + 7, 0, 13, 0, 16, 1, 22, 27, + 9, 0, 17, 23, 28, 24, 29, 30 + }; + unsigned int y= (unsigned int) (x >> 32); + unsigned int n= 0; + if (y == 0) { + y= (unsigned int) x; + n= 32; + } + y = y | (y >> 1); // Propagate leftmost 1-bit to the right. + y = y | (y >> 2); + y = y | (y >> 4); + y = y | (y >> 8); + y = y & ~(y >> 16); + y = y * 0x3EF5D037; + return n + table[y >> 26]; +} +#endif + #endif /* MY_BIT_INCLUDED */ diff --git a/include/my_bitmap.h b/include/my_bitmap.h index d54670653f3ec..0b519e0531174 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -61,8 +61,10 @@ extern my_bool bitmap_exists_intersection(MY_BITMAP **bitmap_array, extern uint bitmap_set_next(MY_BITMAP *map); extern uint bitmap_get_first_clear(const MY_BITMAP *map); extern uint bitmap_get_first_set(const MY_BITMAP *map); +extern uint bitmap_get_last_set(const MY_BITMAP *map); extern uint bitmap_bits_set(const MY_BITMAP *map); extern uint bitmap_get_next_set(const MY_BITMAP *map, uint bitmap_bit); +extern uint bitmap_get_prev_set(const MY_BITMAP *map, uint bitmap_bit); extern void my_bitmap_free(MY_BITMAP *map); extern void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit); extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size); diff --git a/include/my_compare.h b/include/my_compare.h index 44ae7022a2c65..8155d9dfc587c 100644 --- a/include/my_compare.h +++ b/include/my_compare.h @@ -140,7 +140,7 @@ static inline int ha_compare_char_varying(CHARSET_INFO *charset_info, b, b_length); return charset_info->coll->strnncoll(charset_info, a, a_length, - b, b_length, TRUE/*prefix*/); + b, b_length, &b_is_prefix); } @@ -190,7 +190,7 @@ static inline int ha_compare_char_fixed(CHARSET_INFO *charset_info, MY_STRNNCOLLSP_NCHARS_EMULATE_TRIMMED_TRAILING_SPACES); return charset_info->coll->strnncoll(charset_info, a, a_length, - b, b_length, TRUE/*prefix*/); + b, b_length, &b_is_prefix); } @@ -218,10 +218,11 @@ static inline int ha_compare_word_prefix(CHARSET_INFO *charset_info, const uchar *a, size_t a_length, const uchar *b, size_t b_length) { + my_bool b_is_prefix; return charset_info->coll->strnncoll(charset_info, a, a_length, b, b_length, - TRUE/*b_is_prefix*/); + &b_is_prefix); } diff --git a/include/my_compr_int.h b/include/my_compr_int.h new file mode 100644 index 0000000000000..5e58ba5366369 --- /dev/null +++ b/include/my_compr_int.h @@ -0,0 +1,72 @@ +/***************************************************************************** + +Copyright (c) 2024 Kristian Nielsen. + +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 + +*****************************************************************************/ + +/* + Reading and writing of compressed integers. + + Created 2024-10-01 Kristian Nielsen +*/ + +#ifndef MY_COMPR_INT_H +#define MY_COMPR_INT_H + +#include "my_bit.h" +#include +#include + + +/* + Read and write compressed (up to) 64-bit integers. + + A 64-bit number is encoded with 1-9 bytes. The 3 first bits stores a tag + that determines the number of bytes used, and the encoding is written in + little-endian format as (TAG | (NUMBER << 3)). The tag is the number of + bytes used minus 1, except that 7 denotes 9 bytes used (numbers are never + encoded with 8 bytes). For example: + + Number Encoding + 0 0x00 + 0x1f 0xf8 (0 | (0x1f << 3)) + 0x20 0x01 0x01 + 0xf6 0xb1 0x07 + 0xd34a 0x52 0x9a 0x06 + 0x1fffffffffffff 0xfe 0xff 0xff 0xff 0xff 0xff 0xff + 0x20000000000000 0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 + 0xffffffffffffffff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x07 + + The main advantage over something like base-128 compression (also called + varint) is that the encoding and decoding can happen with just a single + conditional jump to determine if one or two 64-bit words are involved (or + even no or only well-predicted conditional jump if unaligned reads/writes + and buffer padding can be assumed). +*/ + +#define COMPR_INT_MAX32 5 +#define COMPR_INT_MAX64 9 +#define COMPR_INT_MAX COMPR_INT_MAX64 + +/* Write compressed unsigned integer */ +extern unsigned char *compr_int_write(unsigned char *p, uint64_t v); +/* + Read compressed integer. + Returns a pair of the value read and the incremented pointer. +*/ +extern std::pair + compr_int_read(const unsigned char *p); + +#endif /* MY_COMPR_INT_H */ diff --git a/include/my_dbug.h b/include/my_dbug.h index 0c0dabef64e18..e1b3d20478987 100644 --- a/include/my_dbug.h +++ b/include/my_dbug.h @@ -24,7 +24,7 @@ #ifdef __cplusplus extern "C" { #endif -#if !defined(DBUG_OFF) && !defined(_lint) +#if !defined(DBUG_OFF) struct _db_stack_frame_ { const char *func; /* function name of the previous stack frame */ @@ -75,6 +75,7 @@ extern int (*dbug_sanity)(void); #define DBUG_PRINT(keyword,arglist) \ do if (_db_pargs_(__LINE__,keyword)) _db_doprnt_ arglist; while(0) +#define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2) #ifdef HAVE_ATTRIBUTE_CLEANUP #define DBUG_ENTER(a) struct _db_stack_frame_ _db_stack_frame_ __attribute__((cleanup(_db_return_))); \ @@ -94,6 +95,7 @@ extern int (*dbug_sanity)(void); #define DBUG_RETURN(a1) return(a1) #define DBUG_VOID_RETURN return #define DBUG_PRINT(keyword,arglist) do{} while(0) +#define DBUG_DUMP(keyword,a1,a2) do{} while(0) #endif #define DBUG_EXECUTE(keyword,a1) \ @@ -111,7 +113,6 @@ extern int (*dbug_sanity)(void); #define DBUG_SET_INITIAL(a1) _db_set_init_ (a1) #define DBUG_PROCESS(a1) _db_process_(a1) #define DBUG_FILE _db_fp_() -#define DBUG_DUMP(keyword,a1,a2) _db_dump_(__LINE__,keyword,a1,a2) #define DBUG_END() _db_end_ () #define DBUG_LOCK_FILE _db_lock_file_() #define DBUG_UNLOCK_FILE _db_unlock_file_() @@ -206,7 +207,7 @@ extern void (*my_dbug_assert_failed)(const char *assert_expr, const char* file, #define DBUG_ASSERT(A) do { } while(0) #define IF_DBUG_ASSERT(A,B) B #endif /* DBUG_ASSERT_AS_PRINTF */ -#endif /* !defined(DBUG_OFF) && !defined(_lint) */ +#endif /* !defined(DBUG_OFF) */ #ifdef EXTRA_DEBUG /** @@ -230,7 +231,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout); one should #include . We intentionally avoid including it here to save compilation time. */ -# ifdef DBUG_OFF +# if defined DBUG_OFF || !defined DBUG_TRACE # define DBUG_LOG(keyword, v) do {} while (0) # else # define DBUG_LOG(keyword, v) do { \ diff --git a/include/my_global.h b/include/my_global.h index e9b68bd21d0cc..9a6117ad973a4 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -281,10 +281,6 @@ C_MODE_END #error "Please add -fno-exceptions to CXXFLAGS and reconfigure/recompile" #endif -#if defined(_lint) && !defined(lint) -#define lint -#endif - #ifndef stdin #include #endif @@ -448,22 +444,18 @@ extern "C" int madvise(void *addr, size_t len, int behav); /* Suppress uninitialized variable warning without generating code. */ -#if defined(__GNUC__) -/* GCC specific self-initialization which inhibits the warning. */ +#if defined(__GNUC__) && !defined(__clang__) +/* + GCC specific self-initialization which inhibits the warning. + clang and static analysis will complain loudly about this. +*/ #define UNINIT_VAR(x) x= x -#elif defined(_lint) || defined(FORCE_INIT_OF_VARS) +#elif defined(FORCE_INIT_OF_VARS) #define UNINIT_VAR(x) x= 0 #else #define UNINIT_VAR(x) x #endif -/* This is only to be used when resetting variables in a class constructor */ -#if defined(_lint) || defined(FORCE_INIT_OF_VARS) -#define LINT_INIT(x) x= 0 -#else -#define LINT_INIT(x) -#endif - #if !defined(HAVE_UINT) #undef HAVE_UINT #define HAVE_UINT @@ -505,7 +497,7 @@ C_MODE_END #endif /* We might be forced to turn debug off, if not turned off already */ -#if (defined(FORCE_DBUG_OFF) || defined(_lint)) && !defined(DBUG_OFF) +#if defined(FORCE_DBUG_OFF) && !defined(DBUG_OFF) # define DBUG_OFF # ifdef DBUG_ON # undef DBUG_ON @@ -527,7 +519,7 @@ typedef int my_socket; /* File descriptor for sockets */ #endif /* Type for functions that handles signals */ #define sig_handler RETSIGTYPE -#if defined(__GNUC__) && !defined(_lint) +#if defined(__GNUC__) typedef char pchar; /* Mixed prototypes can take char */ typedef char puchar; /* Mixed prototypes can take char */ typedef char pbool; /* Mixed prototypes can take char */ @@ -689,9 +681,11 @@ typedef SOCKET_SIZE_TYPE size_socket; /* Typical record cache */ #define RECORD_CACHE_SIZE (uint) (128*1024) /* Typical key cache */ -#define KEY_CACHE_SIZE (uint) (128L*1024L*1024L) +#define KEY_CACHE_SIZE (ulong) (128L*1024L*1024L) /* Default size of a key cache block */ #define KEY_CACHE_BLOCK_SIZE (uint) 1024 + /* Min resonable key cache size, only for testing */ +#define MIN_KEY_CACHE_SIZE 8192*16L /* Some things that this system doesn't have */ @@ -1035,7 +1029,7 @@ typedef ulong myf; /* Type of MyFlags in my_funcs */ #define YESNO(X) ((X) ? "yes" : "no") #define MY_HOW_OFTEN_TO_ALARM 2 /* How often we want info on screen */ -#define MY_HOW_OFTEN_TO_WRITE 10000 /* How often we want info on screen */ +#define MY_HOW_OFTEN_TO_WRITE 100000 /* How often we want info on screen */ #include diff --git a/include/my_sys.h b/include/my_sys.h index faf2e7ec5c8ed..3fd85988a7619 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -89,6 +89,7 @@ C_MODE_START #define MY_FREE_ON_ERROR 128U /* my_realloc() ; Free old ptr on error */ #define MY_DONT_OVERWRITE_FILE 2048U /* my_copy: Don't overwrite file */ #define MY_THREADSAFE 2048U /* my_seek(): lock fd mutex */ +#define MY_BUFFER_NO_RESIZE 512U #define MY_SYNC 4096U /* my_copy(): sync dst file */ #define MY_SYNC_DIR 32768U /* my_create/delete/rename: sync directory */ #define MY_THREAD_SPECIFIC 0x10000U /* my_malloc(): thread specific */ @@ -154,12 +155,15 @@ char *guess_malloc_library(); /* If we have our own safemalloc (for debugging) */ #if defined(SAFEMALLOC) -void sf_report_leaked_memory(my_thread_id id); +my_bool sf_report_leaked_memory(my_thread_id id); int sf_sanity(); +my_bool sf_have_memory_leak(); extern my_thread_id (*sf_malloc_dbug_id)(void); #define SAFEMALLOC_REPORT_MEMORY(X) if (!sf_leaking_memory) sf_report_leaked_memory(X) +#define SAFEMALLOC_HAVE_MEMORY_LEAK sf_have_memory_leak() #else #define SAFEMALLOC_REPORT_MEMORY(X) do {} while(0) +#define SAFEMALLOC_HAVE_MEMORY_LEAK 0 #endif typedef void (*MALLOC_SIZE_CB) (long long size, my_bool is_thread_specific); @@ -362,6 +366,17 @@ typedef struct st_dynamic_array myf malloc_flags; } DYNAMIC_ARRAY; +typedef struct st_mem_root_dynamic_array +{ + MEM_ROOT *mem_root; + uchar *buffer; + size_t elements, max_element; + size_t alloc_increment; + size_t size_of_element; + PSI_memory_key m_psi_key; + myf malloc_flags; +} MEM_ROOT_DYNAMIC_ARRAY; + typedef struct st_dynamic_array_append { @@ -1176,6 +1191,74 @@ extern void thd_increment_bytes_sent(void *thd, size_t length); extern void thd_increment_bytes_received(void *thd, size_t length); extern void thd_increment_net_big_packet_count(void *thd, size_t length); +extern int mem_root_dynamic_array_init(MEM_ROOT *mem_root, + PSI_memory_key psi_key, + MEM_ROOT_DYNAMIC_ARRAY *array, + size_t element_size, void *init_buffer, + size_t init_alloc, + size_t alloc_increment, + myf my_flags); +int mem_root_allocate_dynamic(MEM_ROOT *mem_root, + MEM_ROOT_DYNAMIC_ARRAY *array, + size_t idx); +extern void* mem_root_dynamic_array_get_val(MEM_ROOT_DYNAMIC_ARRAY *array, size_t idx); +extern void mem_root_dynamic_array_reset(MEM_ROOT_DYNAMIC_ARRAY *array); +extern int mem_root_dynamic_array_resize_not_allowed(MEM_ROOT_DYNAMIC_ARRAY *array); +extern void mem_root_dynamic_array_copy_values(MEM_ROOT_DYNAMIC_ARRAY *dest, MEM_ROOT_DYNAMIC_ARRAY *src); +static inline int mem_root_dynamic_array_set_val(MEM_ROOT_DYNAMIC_ARRAY *array, + const void *element, size_t idx) +{ + DBUG_ASSERT(idx < array->max_element); + + memcpy(array->buffer+(idx * array->size_of_element), element, + array->size_of_element); + return TRUE; +} +static inline int mem_root_dynamic_array_resize_and_set_val(MEM_ROOT_DYNAMIC_ARRAY *array, + const void *element, size_t idx) +{ + if (array->malloc_flags & MY_BUFFER_NO_RESIZE) + return TRUE; + + if (idx >= array->max_element) + { + if (mem_root_allocate_dynamic(array->mem_root, array, idx)) + return 1; + array->elements++; + } + + /* + Ensure the array size has increased and the index is + now well within the array bounds. + */ + DBUG_ASSERT(idx < array->max_element); + + memcpy(array->buffer+(idx * array->size_of_element), element, + array->size_of_element); + + return FALSE; +} + +static inline void* mem_root_dynamic_array_resize_and_get_val(MEM_ROOT_DYNAMIC_ARRAY *array, size_t idx) +{ + if (array->malloc_flags & MY_BUFFER_NO_RESIZE) + return NULL; + + if (idx >= array->max_element) + { + if (mem_root_allocate_dynamic(array->mem_root, array, idx)) + return NULL; + } + + /* + Ensure the array size has increased and the index is + now well within the array bounds. + */ + DBUG_ASSERT(idx < array->max_element); + + return mem_root_dynamic_array_get_val(array, idx); +} + #include #ifdef HAVE_PSI_INTERFACE diff --git a/include/my_time.h b/include/my_time.h index 97fd81e4acc78..08fef1b5c6d9a 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -176,9 +176,18 @@ double TIME_to_double(const MYSQL_TIME *my_time); int check_time_range(struct st_mysql_time *my_time, uint dec, int *warning); my_bool check_datetime_range(const MYSQL_TIME *ltime); +/* + Accurate only for the past couple of centuries. + Also works with 2 digit year 01-99 (1971-2069) + Year 0 is ignored as MariaDB uses year 0 as 'not specifed'. This + matches how things how leap year was calculated in calc_days_in_year(). +*/ + +#define isleap(y) (((y) & 3) == 0 && (((y) % 100) != 0 || (((y) % 400) == 0 && y != 0))) long calc_daynr(uint year,uint month,uint day); uint calc_days_in_year(uint year); +uint calc_days_in_month(uint year, uint month); uint year_2000_handling(uint year); void my_init_time(void); diff --git a/include/myisamchk.h b/include/myisamchk.h index d1702357250f7..af23a4de7f65b 100644 --- a/include/myisamchk.h +++ b/include/myisamchk.h @@ -117,7 +117,7 @@ typedef struct st_handler_check_param void (*init_repair_thread)(void *); void *init_repair_thread_arg; mysql_mutex_t print_msg_mutex; - my_bool need_print_msg_lock; + my_bool need_print_msg_lock, status_reporting; myf malloc_flags; } HA_CHECK; diff --git a/include/mysql.h b/include/mysql.h index da9371afeca21..b9735a15d8f1b 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -146,6 +146,7 @@ typedef unsigned long long my_ulonglong; #define ER_SPATIAL_CANT_HAVE_NULL ER_INDEX_CANNOT_HAVE_NULL #define ER_INNODB_NO_FT_TEMP_TABLE ER_NO_INDEX_ON_TEMPORARY #define ER_CANT_CHANGE_TX_CHARACTERISTICS ER_CANT_SET_IN_TRANSACTION +#define ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRIGGER ER_VARIABLE_NOT_SETTABLE_IN_SF_OR_TRG typedef struct st_mysql_rows { struct st_mysql_rows *next; /* list of rows */ diff --git a/include/mysql/client_plugin.h.pp b/include/mysql/client_plugin.h.pp index ff35364bd44f3..37a7c5391d58e 100644 --- a/include/mysql/client_plugin.h.pp +++ b/include/mysql/client_plugin.h.pp @@ -8,6 +8,7 @@ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET, MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol; int socket; + int tls; } MYSQL_PLUGIN_VIO_INFO; typedef struct st_plugin_vio { diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h index 2bf5455cdeabc..ef70b36f497fd 100644 --- a/include/mysql/plugin.h +++ b/include/mysql/plugin.h @@ -81,7 +81,7 @@ typedef struct st_mysql_xid MYSQL_XID; */ /** MySQL plugin interface version */ -#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0104 +#define MYSQL_PLUGIN_INTERFACE_VERSION 0x0105 /** MariaDB plugin interface version */ #define MARIA_PLUGIN_INTERFACE_VERSION 0x010f diff --git a/include/mysql/plugin_audit.h.pp b/include/mysql/plugin_audit.h.pp index 93efe24f4a163..2aeb19207de54 100644 --- a/include/mysql/plugin_audit.h.pp +++ b/include/mysql/plugin_audit.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_auth.h b/include/mysql/plugin_auth.h index 3827db3343106..84dc83b1ad337 100644 --- a/include/mysql/plugin_auth.h +++ b/include/mysql/plugin_auth.h @@ -27,7 +27,7 @@ #include -#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0202 +#define MYSQL_AUTHENTICATION_INTERFACE_VERSION 0x0203 #include diff --git a/include/mysql/plugin_auth.h.pp b/include/mysql/plugin_auth.h.pp index 4e9bfcfd10348..08e6b91ed9044 100644 --- a/include/mysql/plugin_auth.h.pp +++ b/include/mysql/plugin_auth.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { @@ -707,6 +717,7 @@ enum { MYSQL_VIO_INVALID, MYSQL_VIO_TCP, MYSQL_VIO_SOCKET, MYSQL_VIO_PIPE, MYSQL_VIO_MEMORY } protocol; int socket; + int tls; } MYSQL_PLUGIN_VIO_INFO; typedef struct st_plugin_vio { diff --git a/include/mysql/plugin_auth_common.h b/include/mysql/plugin_auth_common.h index cba0257fa27bb..c57850bb7d31f 100644 --- a/include/mysql/plugin_auth_common.h +++ b/include/mysql/plugin_auth_common.h @@ -98,6 +98,7 @@ typedef struct st_plugin_vio_info #ifdef _WIN32 HANDLE handle; /**< it's set, if the protocol is PIPE or MEMORY */ #endif + int tls; } MYSQL_PLUGIN_VIO_INFO; /** diff --git a/include/mysql/plugin_data_type.h.pp b/include/mysql/plugin_data_type.h.pp index 35641802e0371..41b68c66fab42 100644 --- a/include/mysql/plugin_data_type.h.pp +++ b/include/mysql/plugin_data_type.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_encryption.h.pp b/include/mysql/plugin_encryption.h.pp index e8b7f7b3e6026..bbe46404fa15d 100644 --- a/include/mysql/plugin_encryption.h.pp +++ b/include/mysql/plugin_encryption.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_ftparser.h.pp b/include/mysql/plugin_ftparser.h.pp index 4de3fc3a9e624..06de1668e7658 100644 --- a/include/mysql/plugin_ftparser.h.pp +++ b/include/mysql/plugin_ftparser.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_function.h.pp b/include/mysql/plugin_function.h.pp index 63c63cefa10c7..d56255818bfd2 100644 --- a/include/mysql/plugin_function.h.pp +++ b/include/mysql/plugin_function.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/plugin_password_validation.h.pp b/include/mysql/plugin_password_validation.h.pp index 6cc728a852957..529f50e26894c 100644 --- a/include/mysql/plugin_password_validation.h.pp +++ b/include/mysql/plugin_password_validation.h.pp @@ -128,26 +128,36 @@ void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) __attribute__((format(printf, 2, 0))); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) __attribute__((format(printf, 2, 3))); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); } extern "C" { extern struct my_md5_service_st { diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h index 096815ed02da1..36d073c32e233 100644 --- a/include/mysql/psi/mysql_file.h +++ b/include/mysql/psi/mysql_file.h @@ -775,7 +775,7 @@ inline_mysql_file_stat( #ifdef HAVE_PSI_FILE_INTERFACE struct PSI_file_locker *locker; PSI_file_locker_state state; - locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_STAT, path, &locker); + locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_STAT, path, NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line); @@ -1025,7 +1025,7 @@ inline_mysql_file_create( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_CREATE, filename, - &locker); + NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line); @@ -1051,7 +1051,7 @@ inline_mysql_file_create_temp( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker) - (&state, key, PSI_FILE_CREATE, NULL, &locker); + (&state, key, PSI_FILE_CREATE, NULL, NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line); @@ -1078,7 +1078,7 @@ inline_mysql_file_open( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_OPEN, filename, - &locker); + NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line); @@ -1298,7 +1298,7 @@ inline_mysql_file_delete( #ifdef HAVE_PSI_FILE_INTERFACE struct PSI_file_locker *locker; PSI_file_locker_state state; - locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_DELETE, name, &locker); + locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_DELETE, name, NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line); @@ -1324,7 +1324,7 @@ inline_mysql_file_rename( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker) - (&state, key, PSI_FILE_RENAME, from, &locker); + (&state, key, PSI_FILE_RENAME, from, NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line); @@ -1352,7 +1352,7 @@ inline_mysql_file_create_with_symlink( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_CREATE, filename, - &locker); + NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line); @@ -1383,7 +1383,7 @@ inline_mysql_file_delete_with_symlink( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker)(&state, key, PSI_FILE_DELETE, fullname, - &locker); + NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line); @@ -1410,7 +1410,7 @@ inline_mysql_file_rename_with_symlink( struct PSI_file_locker *locker; PSI_file_locker_state state; locker= PSI_FILE_CALL(get_thread_file_name_locker) - (&state, key, PSI_FILE_RENAME, from, &locker); + (&state, key, PSI_FILE_RENAME, from, NULL); if (psi_likely(locker != NULL)) { PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line); diff --git a/include/mysql/service_logger.h b/include/mysql/service_logger.h index 35c2eb1e3a959..d11dd4291ae32 100644 --- a/include/mysql/service_logger.h +++ b/include/mysql/service_logger.h @@ -64,41 +64,58 @@ extern struct logger_service_st { void (*logger_init_mutexes)(); LOGGER_HANDLE* (*open)(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int (*close)(LOGGER_HANDLE *log); int (*vprintf)(LOGGER_HANDLE *log, const char *fmt, va_list argptr) ATTRIBUTE_FORMAT_FPTR(printf, 2, 0); int (*printf)(LOGGER_HANDLE *log, const char *fmt, ...) ATTRIBUTE_FORMAT_FPTR(printf, 2, 3); - int (*write)(LOGGER_HANDLE *log, const char *buffer, size_t size); + int (*write)(LOGGER_HANDLE *log, const void *data, size_t size); int (*rotate)(LOGGER_HANDLE *log); + int (*sync)(LOGGER_HANDLE *log); + int (*resize_buffer)(LOGGER_HANDLE *log, size_t new_buffer_size); + int (*set_filesize_limit)(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int (*set_rotations)(LOGGER_HANDLE *log, unsigned int new_rotations); } *logger_service; #ifdef MYSQL_DYNAMIC_PLUGIN #define logger_init_mutexes logger_service->logger_init_mutexes -#define logger_open(path, size_limit, rotations) \ - (logger_service->open(path, size_limit, rotations)) +#define logger_open(path, size_limit, rotations, buffer_size) \ + (logger_service->open(path, size_limit, rotations, buffer_size)) #define logger_close(log) (logger_service->close(log)) #define logger_rotate(log) (logger_service->rotate(log)) #define logger_vprintf(log, fmt, argptr) (logger_service->\ vprintf(log, fmt, argptr)) #define logger_printf (*logger_service->printf) -#define logger_write(log, buffer, size) \ - (logger_service->write(log, buffer, size)) +#define logger_write(log, data, size) \ + (logger_service->write(log, data, size)) +#define logger_sync(log) (logger_service->sync(log)) +#define logger_resize_buffer(log, new_buffer_size) \ + (logger_service->resize_buffer(log, new_buffer_size)) +#define logger_set_filesize_limit(log, new_file_limit) \ + (logger_service->set_filesize_limit(log, new_file_limit)) +#define logger_set_rotations(log, new_rotations) \ + (logger_service->set_rotations(log, new_rotations)) #else void logger_init_mutexes(); LOGGER_HANDLE *logger_open(const char *path, unsigned long long size_limit, - unsigned int rotations); + unsigned int rotations, size_t buffer_size); int logger_close(LOGGER_HANDLE *log); int logger_vprintf(LOGGER_HANDLE *log, const char *fmt, va_list argptr) ATTRIBUTE_FORMAT(printf, 2, 0); int logger_printf(LOGGER_HANDLE *log, const char *fmt, ...) ATTRIBUTE_FORMAT(printf, 2, 3); - int logger_write(LOGGER_HANDLE *log, const char *buffer, size_t size); + int logger_write(LOGGER_HANDLE *log, const void *data, size_t size); int logger_rotate(LOGGER_HANDLE *log); + int logger_sync(LOGGER_HANDLE *log); + int logger_resize_buffer(LOGGER_HANDLE *log, size_t new_buffer_size); + int logger_set_filesize_limit(LOGGER_HANDLE *log, + unsigned long long new_file_limit); + int logger_set_rotations(LOGGER_HANDLE *log, unsigned int new_rotations); #endif diff --git a/include/mysql/service_wsrep.h b/include/mysql/service_wsrep.h index cf94364c1cf82..8c001ca147063 100644 --- a/include/mysql/service_wsrep.h +++ b/include/mysql/service_wsrep.h @@ -9,6 +9,11 @@ enum Wsrep_service_key_type WSREP_SERVICE_KEY_EXCLUSIVE }; + +/* the bits in the bitmask for disabling temporarily some asserts */ +#define WSREP_ASSERT_INNODB_TRX 1 + + #if (defined (MYSQL_DYNAMIC_PLUGIN) && defined(MYSQL_SERVICE_WSREP_DYNAMIC_INCLUDED)) || (!defined(MYSQL_DYNAMIC_PLUGIN) && defined(MYSQL_SERVICE_WSREP_STATIC_INCLUDED)) #else @@ -64,6 +69,7 @@ extern struct wsrep_service_st { bool (*wsrep_thd_ignore_table_func)(MYSQL_THD thd); long long (*wsrep_thd_trx_seqno_func)(const MYSQL_THD thd); my_bool (*wsrep_thd_is_aborting_func)(const MYSQL_THD thd); + my_bool (*wsrep_thd_in_rollback_func)(const THD *thd); void (*wsrep_set_data_home_dir_func)(const char *data_dir); my_bool (*wsrep_thd_is_BF_func)(const MYSQL_THD thd, my_bool sync); my_bool (*wsrep_thd_is_local_func)(const MYSQL_THD thd); @@ -123,6 +129,7 @@ extern struct wsrep_service_st { #define wsrep_set_data_home_dir(A) wsrep_service->wsrep_set_data_home_dir_func(A) #define wsrep_thd_is_BF(T,S) wsrep_service->wsrep_thd_is_BF_func(T,S) #define wsrep_thd_is_aborting(T) wsrep_service->wsrep_thd_is_aborting_func(T) +#define wsrep_thd_in_rollback_func(T) wsrep_service->wsrep_thd_in_rollback_func(T) #define wsrep_thd_is_local(T) wsrep_service->wsrep_thd_is_local_func(T) #define wsrep_thd_self_abort(T) wsrep_service->wsrep_thd_self_abort_func(T) #define wsrep_thd_append_key(T,W,N,K) wsrep_service->wsrep_thd_append_key_func(T,W,N,K) @@ -225,6 +232,8 @@ extern "C" my_bool wsrep_thd_order_before(const MYSQL_THD left, const MYSQL_THD extern "C" my_bool wsrep_thd_skip_locking(const MYSQL_THD thd); /* Return true if thd is aborting */ extern "C" my_bool wsrep_thd_is_aborting(const MYSQL_THD thd); +/* Return true if thd is a WSREP applier rolling back a transaction locally */ +extern "C" my_bool wsrep_thd_in_rollback(const MYSQL_THD thd); struct wsrep_key; struct wsrep_key_array; diff --git a/include/mysql_com.h b/include/mysql_com.h index b9fae54e7f476..9ef905ab39140 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -214,7 +214,7 @@ enum enum_indicator_type #define REFRESH_QUERY_CACHE (1ULL << 16) /* clear the query cache */ #define REFRESH_QUERY_CACHE_FREE (1ULL << 17) /* pack query cache */ -#define REFRESH_DES_KEY_FILE (1ULL << 18) +/* unused (1ULL << 18) */ #define REFRESH_USER_RESOURCES (1ULL << 19) #define REFRESH_FOR_EXPORT (1ULL << 20) /* FLUSH TABLES ... FOR EXPORT */ #define REFRESH_SSL (1ULL << 21) @@ -406,6 +406,13 @@ enum mariadb_field_attr_t #define SERVER_STATUS_ANSI_QUOTES 32768U +/* + Set for stored procedures if the select query returned a row + To check for an empty query, one must also check thd::get_sent_row_count() +*/ + +#define SERVER_STATUS_RETURNED_ROW (1U << 16) + /** Server status flags that must be cleared when starting execution of a new SQL statement. @@ -422,7 +429,8 @@ enum mariadb_field_attr_t SERVER_STATUS_DB_DROPPED |\ SERVER_STATUS_CURSOR_EXISTS|\ SERVER_STATUS_LAST_ROW_SENT|\ - SERVER_SESSION_STATE_CHANGED) + SERVER_SESSION_STATE_CHANGED|\ + SERVER_STATUS_RETURNED_ROW) #define MYSQL_ERRMSG_SIZE 512 #define NET_READ_TIMEOUT 30 /* Timeout on read */ diff --git a/include/rpl_gtid_base.h b/include/rpl_gtid_base.h new file mode 100644 index 0000000000000..e197c71a4f6ab --- /dev/null +++ b/include/rpl_gtid_base.h @@ -0,0 +1,130 @@ +/* Copyright (c) 2013,2024, Kristian Nielsen and MariaDB Services Ab. + + 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 */ + +#ifndef RPL_GTID_BASE_H +#define RPL_GTID_BASE_H + +#include "hash.h" + + +/* Definitions for MariaDB global transaction ID (GTID). */ + +struct slave_connection_state; + +struct rpl_gtid +{ + uint32 domain_id; + uint32 server_id; + uint64 seq_no; +}; + +/* + Binlog state. + + A binlog state records the last GTID written to the binlog for every + distinct (domain_id, server_id) pair. Thus, each point in the binlog + corresponds to a specific binlog state. + + When starting replication from a specific GTID position, the starting point + is identified as the most recent one where the binlog state has no higher + seq_no than the GTID position for any (domain_id, server_id) combination. + + We also remember the most recent logged GTID for every domain_id. This is + used to know where to start when a master is changed to a slave. As a side + effect, it also allows to skip a hash lookup in the very common case of + logging a new GTID with same server id as last GTID. + + This base class rpl_binlog_state_base contains just be basic data operations + to insert/update GTIDs, and is used eg. from Gtid_index_*. +*/ +struct rpl_binlog_state_base +{ + struct element { + uint32 domain_id; + HASH hash; /* Containing all server_id for one domain_id */ + /* The most recent entry in the hash. */ + rpl_gtid *last_gtid; + /* Counter to allocate next seq_no for this domain. */ + uint64 seq_no_counter; + + int update_element(const rpl_gtid *gtid); + }; + + /* Mapping from domain_id to collection of elements. */ + HASH hash; + my_bool initialized; + + rpl_binlog_state_base() : initialized(0) {} + ~rpl_binlog_state_base(); + void init(); + void reset_nolock(); + void free(); + bool load_nolock(struct rpl_gtid *list, uint32 count); + bool load_nolock(rpl_binlog_state_base *orig_state); + int update_nolock(const struct rpl_gtid *gtid); + int alloc_element_nolock(const rpl_gtid *gtid); + uint32 count_nolock(); + int get_gtid_list_nolock(rpl_gtid *gtid_list, uint32 list_size); + rpl_gtid *find_nolock(uint32 domain_id, uint32 server_id); + bool is_before_pos(slave_connection_state *pos); + + /* + Inline iterator over a binlog state, most recent GTID comes last for each + domain just like get_gtid_list_nolock(). + + The ITERATOR_FUNC should have signature bool f(const rpl_gtid *), and + return true in case of error (in which case iterate() aborts and also + returns true). + + Intended to do custom GTID state processing without requiring the overhead + of an intermediate list, and where the extra code generation is justified. + */ + template bool iterate(F iterator_func) + { + uint32 i, j; + ulong outer_records= hash.records; + + for (i= 0; i < outer_records; ++i) + { + element *e= (element *)my_hash_element(&hash, i); + ulong inner_records= e->hash.records; + const rpl_gtid *last_gtid= e->last_gtid; + if (unlikely(!last_gtid)) + { + DBUG_ASSERT(inner_records==0); + continue; + } + for (j= 0; j <= inner_records; ++j) + { + const rpl_gtid *gtid; + if (j < inner_records) + { + gtid= (rpl_gtid *)my_hash_element(&e->hash, j); + if (gtid == last_gtid) + continue; + } + else + gtid= e->last_gtid; + if (iterator_func(gtid)) + return true; + } + } + + return false; // No error + } +}; + + +#endif /* RPL_GTID_BASE_H */ diff --git a/include/service_versions.h b/include/service_versions.h index 40e668ea84366..45cad4d86ae06 100644 --- a/include/service_versions.h +++ b/include/service_versions.h @@ -26,7 +26,7 @@ #define VERSION_base64 0x0100 #define VERSION_encryption 0x0300 #define VERSION_encryption_scheme 0x0100 -#define VERSION_logger 0x0200 +#define VERSION_logger 0x0300 #define VERSION_my_crypt 0x0101 #define VERSION_my_md5 0x0100 #define VERSION_my_print_error 0x0200 diff --git a/include/thr_timer.h b/include/thr_timer.h index 6bca815480b4a..233a66bc6fa87 100644 --- a/include/thr_timer.h +++ b/include/thr_timer.h @@ -24,6 +24,7 @@ extern "C" { typedef struct st_timer { struct timespec expire_time; ulonglong period; + ulonglong timeout; /* Timeout value in microseconds */ my_bool expired; uint index_in_queue; void (*func)(void*); diff --git a/include/typelib.h b/include/typelib.h index 9a8ee802cae59..091e58d04c886 100644 --- a/include/typelib.h +++ b/include/typelib.h @@ -25,9 +25,16 @@ typedef struct st_typelib { /* Different types saved here */ const char *name; /* Name of typelib */ const char **type_names; unsigned int *type_lengths; + /* + An array of indexes of enum values that are no longer supported and so are + hidden. One cannot specify hidden values, an attempt to do so will produce + a warning (while an attempt to use a name that was never part of this set + will produce an error). + */ + const int *hidden_values; } TYPELIB; -#define CREATE_TYPELIB_FOR(X) { (unsigned int)(sizeof(X)/sizeof(X[0])) - 1, "", X, NULL } +#define CREATE_TYPELIB_FOR(X) { (unsigned int)(sizeof(X)/sizeof(X[0])) - 1, "", X, NULL, NULL } extern my_ulonglong find_typeset(const char *x, TYPELIB *typelib, int *error_position); diff --git a/libmariadb b/libmariadb index b790c6c149c91..7bb4e6cdf787b 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit b790c6c149c9119fb73c416e993af1c7ef256b34 +Subproject commit 7bb4e6cdf787b32907429287a636857e3b31e6a1 diff --git a/libmysqld/CMakeLists.txt b/libmysqld/CMakeLists.txt index e6f4462ad089a..f59354625b345 100644 --- a/libmysqld/CMakeLists.txt +++ b/libmysqld/CMakeLists.txt @@ -57,13 +57,14 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/field.cc ../sql/field_conv.cc ../sql/field_comp.cc ../sql/filesort_utils.cc ../sql/sql_digest.cc ../sql/filesort.cc ../sql/grant.cc - ../sql/gstream.cc ../sql/slave.cc + ../sql/gstream.cc ../sql/signal_handler.cc ../sql/handler.cc ../sql/hash_filo.cc ../sql/hostname.cc ../sql/init.cc ../sql/item_buff.cc ../sql/item_cmpfunc.cc ../sql/item.cc ../sql/item_create.cc ../sql/item_func.cc ../sql/item_geofunc.cc ../sql/item_row.cc ../sql/item_strfunc.cc ../sql/item_subselect.cc ../sql/item_sum.cc ../sql/item_timefunc.cc + ../sql/item_numconvfunc.cc ../sql/item_xmlfunc.cc ../sql/item_jsonfunc.cc ../sql/json_schema.cc ../sql/json_schema_helper.cc ../sql/key.cc ../sql/lock.cc ../sql/log.cc ../sql/log_cache.cc @@ -78,7 +79,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/opt_vcol_substitution.cc ../sql/parse_file.cc ../sql/procedure.cc ../sql/protocol.cc ../sql/records.cc ../sql/repl_failsafe.cc ../sql/rpl_filter.cc - ../sql/rpl_record.cc ../sql/des_key_file.cc + ../sql/rpl_record.cc ../sql/rpl_injector.cc ../sql/set_var.cc ../sql/spatial.cc ../sql/sp_cache.cc ../sql/sp.cc ../sql/sp_head.cc ../sql/sp_pcontext.cc ../sql/sp_rcontext.cc ../sql/sql_acl.cc @@ -92,6 +93,7 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/sql_lex.cc ../sql/keycaches.cc ../sql/sql_list.cc ../sql/sql_load.cc ../sql/sql_locale.cc ../sql/sql_binlog.cc ../sql/sql_manager.cc + ../sql/sql_oracle_outer_join.cc ../sql/sql_parse.cc ../sql/sql_bootstrap.cc ../sql/sql_partition.cc ../sql/sql_plugin.cc ../sql/debug_sync.cc ../sql/debug.cc @@ -135,6 +137,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/sql_schema.cc ../sql/lex_charset.cc ../sql/charset_collations.cc ../sql/sql_type.cc ../sql/sql_type.h + ../sql/sql_type_composite.cc ../sql/item_composite.cc + ../sql/sql_type_row.cc ../sql/sql_mode.cc ../sql/sql_type_string.cc ../sql/sql_type_json.cc @@ -160,6 +164,8 @@ SET(SQL_EMBEDDED_SOURCES emb_qcache.cc libmysqld.c lib_sql.cc ../sql/opt_hints_parser.cc ../sql/opt_hints_parser.h ../sql/scan_char.h ../sql/opt_hints.cc ../sql/opt_hints.h + ../sql/opt_trace_ddl_info.cc ../sql/opt_trace_ddl_info.h + ../sql/sql_path.cc ${GEN_SOURCES} ${MYSYS_LIBWRAP_SOURCE} ) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index cf958c4e9a0be..4f1d98293aaa1 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -789,9 +789,21 @@ int check_embedded_connection(MYSQL *mysql, const char *db) sctx->proxy_user[0]= 0; sctx->master_access= GLOBAL_ACLS; // Full rights emb_transfer_connect_attrs(mysql); + /* Change database if necessary */ - if (!(result= (db && db[0] && mysql_change_db(thd, &db_str, FALSE)))) + result = 0; + if (db && db[0]) + { + result = mysql_change_db(thd, db_str, FALSE); + if (!result) + { + my_free(mysql->db); + mysql->db = my_strdup(PSI_NOT_INSTRUMENTED, db, MYF(0)); + } + } + if (!result) my_ok(thd); + thd->protocol->end_statement(); emb_read_query_result(mysql); return result; diff --git a/man/aria_chk.1 b/man/aria_chk.1 index 435dac75d702a..e9e09fd15b345 100644 --- a/man/aria_chk.1 +++ b/man/aria_chk.1 @@ -241,4 +241,4 @@ Read this file after the global files are read. .SH "SEE ALSO" \fBmyisamchk(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_dump_log.1 b/man/aria_dump_log.1 index 16463fc222da2..86cec5a33b956 100644 --- a/man/aria_dump_log.1 +++ b/man/aria_dump_log.1 @@ -50,6 +50,6 @@ Only read default options from the given file #. Read this file after the global files are read. .PP .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/aria_ftdump.1 b/man/aria_ftdump.1 index 7b5ba5f5211a6..ddbc572167fe8 100644 --- a/man/aria_ftdump.1 +++ b/man/aria_ftdump.1 @@ -25,4 +25,4 @@ Be verbose. .SH "SEE ALSO" \fBmyisam_ftdump(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_pack.1 b/man/aria_pack.1 index 2557507b999a5..0cd34e6756ffc 100644 --- a/man/aria_pack.1 +++ b/man/aria_pack.1 @@ -72,4 +72,4 @@ Read this file after the global files are read. .SH "SEE ALSO" \fBmyisampack(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/aria_read_log.1 b/man/aria_read_log.1 index db42162c48fb1..355573927a826 100644 --- a/man/aria_read_log.1 +++ b/man/aria_read_log.1 @@ -104,4 +104,4 @@ Read this file after the global files are read. .SH "SEE ALSO" \fBmyisamlog(1)\fR .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/comp_err.1 b/man/comp_err.1 index ba8b2635bb44a..2fcf3d505a622 100644 --- a/man/comp_err.1 +++ b/man/comp_err.1 @@ -256,6 +256,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/galera_recovery.1 b/man/galera_recovery.1 index 7464ff79ccce6..b0199530b15e9 100644 --- a/man/galera_recovery.1 +++ b/man/galera_recovery.1 @@ -13,4 +13,4 @@ galera_recovery \- recover from non\-graceful shutdown .SH DESCRIPTION Use: Recover from non\-graceful shutdown\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/innochecksum.1 b/man/innochecksum.1 index 940e059a29dac..c47702a41d953 100644 --- a/man/innochecksum.1 +++ b/man/innochecksum.1 @@ -312,6 +312,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-access.1 b/man/mariadb-access.1 index d0aa39aae1096..f23680c9af40e 100644 --- a/man/mariadb-access.1 +++ b/man/mariadb-access.1 @@ -424,6 +424,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-admin.1 b/man/mariadb-admin.1 index 2f2993aaf9357..b0cbf59a3d52f 100644 --- a/man/mariadb-admin.1 +++ b/man/mariadb-admin.1 @@ -1531,6 +1531,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-backup.1 b/man/mariadb-backup.1 index 531dc24b020b6..3973032929518 100644 --- a/man/mariadb-backup.1 +++ b/man/mariadb-backup.1 @@ -13,4 +13,4 @@ mariabackup \- Backup tool .SH DESCRIPTION Use \fBmariabackup \-\-help\fR for details on usage\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/mariadb-binlog.1 b/man/mariadb-binlog.1 index 4a2aaa08f9e57..dcf98a93ae57c 100644 --- a/man/mariadb-binlog.1 +++ b/man/mariadb-binlog.1 @@ -2143,6 +2143,6 @@ Bug#42941 \%http://bugs.mysql.com/bug.php?id=42941 .RE .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-check.1 b/man/mariadb-check.1 index 64902abb1d8cc..2bf4b3053f9e1 100644 --- a/man/mariadb-check.1 +++ b/man/mariadb-check.1 @@ -87,7 +87,7 @@ note : The storage engine for the table doesn't support check .PP If \fBmariadb-check\fR -is unable to repair a table, see the MariaDB Knowledge Base +is unable to repair a table, see the MariaDB Documentation for manual table repair strategies\&. This will be the case, for example, for InnoDB tables, which can be checked with @@ -1152,6 +1152,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-client-test.1 b/man/mariadb-client-test.1 index 0c82aac4902fd..1993c8eeab943 100644 --- a/man/mariadb-client-test.1 +++ b/man/mariadb-client-test.1 @@ -327,6 +327,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-conv.1 b/man/mariadb-conv.1 index a9fa6177207e1..9c75bdab8c233 100644 --- a/man/mariadb-conv.1 +++ b/man/mariadb-conv.1 @@ -99,6 +99,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/en/mariadb-conv/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/server/clients-and-utilities/administrative-tools/mariadb-conv .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-convert-table-format.1 b/man/mariadb-convert-table-format.1 index 63951400ea7e8..eb1183c97e63d 100644 --- a/man/mariadb-convert-table-format.1 +++ b/man/mariadb-convert-table-format.1 @@ -217,6 +217,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-dump.1 b/man/mariadb-dump.1 index 0c8868a9e13a4..4296e91b79155 100644 --- a/man/mariadb-dump.1 +++ b/man/mariadb-dump.1 @@ -2915,6 +2915,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-dumpslow.1 b/man/mariadb-dumpslow.1 index c1b180c025c84..ce7308d316e17 100644 --- a/man/mariadb-dumpslow.1 +++ b/man/mariadb-dumpslow.1 @@ -327,6 +327,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-find-rows.1 b/man/mariadb-find-rows.1 index 0b07401a84aa4..def7d0baae6ab 100644 --- a/man/mariadb-find-rows.1 +++ b/man/mariadb-find-rows.1 @@ -153,6 +153,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-fix-extensions.1 b/man/mariadb-fix-extensions.1 index 4eaee13777bf0..604686aae8358 100644 --- a/man/mariadb-fix-extensions.1 +++ b/man/mariadb-fix-extensions.1 @@ -65,6 +65,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-hotcopy.1 b/man/mariadb-hotcopy.1 index 24ebb54334468..916fab25b8096 100644 --- a/man/mariadb-hotcopy.1 +++ b/man/mariadb-hotcopy.1 @@ -529,6 +529,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-import.1 b/man/mariadb-import.1 index 2a5e6a784367d..ea997d39aa110 100644 --- a/man/mariadb-import.1 +++ b/man/mariadb-import.1 @@ -903,6 +903,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-install-db.1 b/man/mariadb-install-db.1 index 8f93d080a9c5d..705cd910a6536 100644 --- a/man/mariadb-install-db.1 +++ b/man/mariadb-install-db.1 @@ -393,6 +393,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-plugin.1 b/man/mariadb-plugin.1 index d34bb17c86cd0..6bbbe2fee4778 100644 --- a/man/mariadb-plugin.1 +++ b/man/mariadb-plugin.1 @@ -370,6 +370,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-secure-installation.1 b/man/mariadb-secure-installation.1 index 6248838aedbc2..ab0da2b49096f 100644 --- a/man/mariadb-secure-installation.1 +++ b/man/mariadb-secure-installation.1 @@ -162,6 +162,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-service-convert.1 b/man/mariadb-service-convert.1 index 11597340a81c9..451ddb32e5771 100644 --- a/man/mariadb-service-convert.1 +++ b/man/mariadb-service-convert.1 @@ -17,4 +17,4 @@ a user mariadbd-safe settings in the my.cnf files\. .PP Redirect output to user directory like /etc/systemd/system/mariadb.service.d/migrated-from-my.cnf-settings.conf .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/mariadb-setpermission.1 b/man/mariadb-setpermission.1 index 1cfae88408f19..ec45cf9e66290 100644 --- a/man/mariadb-setpermission.1 +++ b/man/mariadb-setpermission.1 @@ -163,6 +163,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-show.1 b/man/mariadb-show.1 index ce0b6939a605b..ada2fe1082269 100644 --- a/man/mariadb-show.1 +++ b/man/mariadb-show.1 @@ -714,6 +714,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-slap.1 b/man/mariadb-slap.1 index a9ff7e89812f7..85aff76eaf721 100644 --- a/man/mariadb-slap.1 +++ b/man/mariadb-slap.1 @@ -1160,6 +1160,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-test.1 b/man/mariadb-test.1 index a94c9c013b26d..8837f4e5b135f 100644 --- a/man/mariadb-test.1 +++ b/man/mariadb-test.1 @@ -1078,6 +1078,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-tzinfo-to-sql.1 b/man/mariadb-tzinfo-to-sql.1 index 8037b16d8e016..742badf4de291 100644 --- a/man/mariadb-tzinfo-to-sql.1 +++ b/man/mariadb-tzinfo-to-sql.1 @@ -118,6 +118,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-upgrade.1 b/man/mariadb-upgrade.1 index 3c1c0d4ab50fc..d294cadbe8f26 100644 --- a/man/mariadb-upgrade.1 +++ b/man/mariadb-upgrade.1 @@ -723,6 +723,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb-waitpid.1 b/man/mariadb-waitpid.1 index f1f70893280b3..70b100111cece 100644 --- a/man/mariadb-waitpid.1 +++ b/man/mariadb-waitpid.1 @@ -122,6 +122,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb.1 b/man/mariadb.1 index ea5fd56e9fa91..73307bd4341df 100644 --- a/man/mariadb.1 +++ b/man/mariadb.1 @@ -3130,6 +3130,6 @@ Bug#25946 \%http://bugs.mysql.com/bug.php?id=25946 .RE .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadb_config.1 b/man/mariadb_config.1 index 6a1c727d6c760..dcb3fb7061365 100644 --- a/man/mariadb_config.1 +++ b/man/mariadb_config.1 @@ -242,6 +242,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadbd-multi.1 b/man/mariadbd-multi.1 index 398045b061ab0..ce1cc67abb9fa 100644 --- a/man/mariadbd-multi.1 +++ b/man/mariadbd-multi.1 @@ -677,6 +677,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadbd-safe-helper.1 b/man/mariadbd-safe-helper.1 index cca851e3eb094..6f383b651f3e6 100644 --- a/man/mariadbd-safe-helper.1 +++ b/man/mariadbd-safe-helper.1 @@ -13,4 +13,4 @@ mariadbd-safe-helper \- helper script (mysqld_safe_helper is now a symlink to ma .SH DESCRIPTION Use: Helper script\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/mariadbd-safe.1 b/man/mariadbd-safe.1 index dea792495d1f4..e579cb20a16c9 100644 --- a/man/mariadbd-safe.1 +++ b/man/mariadbd-safe.1 @@ -866,6 +866,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mariadbd.8 b/man/mariadbd.8 index 3dc9627aef1af..1d794b4c421e5 100644 --- a/man/mariadbd.8 +++ b/man/mariadbd.8 @@ -41,7 +41,7 @@ shell> \fBmariadbd \-\-verbose \-\-help\fR MariaDB Server also has a set of system variables that affect its operation as it runs\&. System variables can be set at server startup, and many of them can be changed at runtime to effect dynamic server reconfiguration\&. MariaDB Server also has a set of status variables that provide information about its operation\&. You can monitor these status variables to access runtime performance characteristics\&. .PP For a full description of MariaDB Server command options, system variables, and status variables, see -the MariaDB Knowledge Base\&. +the MariaDB Documentation\&. .SH "COPYRIGHT" .br .PP @@ -54,6 +54,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mbstream.1 b/man/mbstream.1 index 4053f0eca7e37..142f7c8d99c4c 100644 --- a/man/mbstream.1 +++ b/man/mbstream.1 @@ -13,4 +13,4 @@ mbstream \- Serialize/deserialize files in the XBSTREAM format .SH DESCRIPTION Use \fBmbstream \-\-help\fR for details on usage\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/msql2mysql.1 b/man/msql2mysql.1 index 0a7a0545c70c5..8c1e033910aa3 100644 --- a/man/msql2mysql.1 +++ b/man/msql2mysql.1 @@ -62,6 +62,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/my_print_defaults.1 b/man/my_print_defaults.1 index 6e4648069206f..004a9ff6b0261 100644 --- a/man/my_print_defaults.1 +++ b/man/my_print_defaults.1 @@ -228,6 +228,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/my_safe_process.1 b/man/my_safe_process.1 index 7ac2dbc79cfd3..2af4357b40699 100644 --- a/man/my_safe_process.1 +++ b/man/my_safe_process.1 @@ -13,4 +13,4 @@ my_safe_process \- Utility program that encapsulates process creation, monitorin .SH DESCRIPTION Use: safe_process [options to safe_process] -- progname arg1 \.\.\. argn\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/myisam_ftdump.1 b/man/myisam_ftdump.1 index fcca2cb06a116..7389fc65d987f 100644 --- a/man/myisam_ftdump.1 +++ b/man/myisam_ftdump.1 @@ -244,6 +244,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/myisamchk.1 b/man/myisamchk.1 index 0c46fb83cef31..4270cd4b53a94 100644 --- a/man/myisamchk.1 +++ b/man/myisamchk.1 @@ -2514,6 +2514,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/myisamlog.1 b/man/myisamlog.1 index cd1caf397f995..7726cbae59c43 100644 --- a/man/myisamlog.1 +++ b/man/myisamlog.1 @@ -227,6 +227,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/myisampack.1 b/man/myisampack.1 index 11040b9b1576f..b46270d5aedda 100644 --- a/man/myisampack.1 +++ b/man/myisampack.1 @@ -832,6 +832,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql-stress-test.pl.1 b/man/mysql-stress-test.pl.1 index a7b6e08905814..af1f0ac5b1920 100644 --- a/man/mysql-stress-test.pl.1 +++ b/man/mysql-stress-test.pl.1 @@ -491,6 +491,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql-test-run.pl.1 b/man/mysql-test-run.pl.1 index 0f6e07d42aaee..4a2fa01899a0e 100644 --- a/man/mysql-test-run.pl.1 +++ b/man/mysql-test-run.pl.1 @@ -2313,6 +2313,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mysql.server.1 b/man/mysql.server.1 index 6940f2e3aeadb..4538bfbc248e7 100644 --- a/man/mysql.server.1 +++ b/man/mysql.server.1 @@ -175,6 +175,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/mytop.1 b/man/mytop.1 index d646df1d459e7..2523b65e34ed1 100644 --- a/man/mytop.1 +++ b/man/mytop.1 @@ -2,6 +2,6 @@ .SH NAME mytop \- display MariaDB server performance info like 'top' .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/perror.1 b/man/perror.1 index 772d7ef51f0dd..be87611beae5f 100644 --- a/man/perror.1 +++ b/man/perror.1 @@ -152,6 +152,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/replace.1 b/man/replace.1 index 03568f5e87a73..829674211a895 100644 --- a/man/replace.1 +++ b/man/replace.1 @@ -162,6 +162,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/resolve_stack_dump.1 b/man/resolve_stack_dump.1 index 2ee42345e1a32..2a1d1c161f6a9 100644 --- a/man/resolve_stack_dump.1 +++ b/man/resolve_stack_dump.1 @@ -119,6 +119,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/resolveip.1 b/man/resolveip.1 index f4151af50613f..2c4c66c35a2f5 100644 --- a/man/resolveip.1 +++ b/man/resolveip.1 @@ -101,6 +101,6 @@ This documentation is distributed in the hope that it will be useful, but WITHOU You should have received a copy of the GNU General Public License along with the program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA or see http://www.gnu.org/licenses/. .sp .SH "SEE ALSO" -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ .SH AUTHOR MariaDB Foundation (http://www.mariadb.org/). diff --git a/man/wsrep_sst_backup.1 b/man/wsrep_sst_backup.1 index 2d34f8ce61702..196293ee04d2c 100644 --- a/man/wsrep_sst_backup.1 +++ b/man/wsrep_sst_backup.1 @@ -13,4 +13,4 @@ wsrep_sst_backup \- backup helper script for the MariaDB Galera Cluster .SH DESCRIPTION Use: See source code of script\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_common.1 b/man/wsrep_sst_common.1 index e9d2745599126..a7e159cb91ad4 100644 --- a/man/wsrep_sst_common.1 +++ b/man/wsrep_sst_common.1 @@ -13,4 +13,4 @@ wsrep_sst_common \- common command line parser to be sourced by other SST script .SH DESCRIPTION Use: Common command line parser to be sourced by other SST scripts\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_mariabackup.1 b/man/wsrep_sst_mariabackup.1 index 6df4342372de7..aa6b8295c85d2 100644 --- a/man/wsrep_sst_mariabackup.1 +++ b/man/wsrep_sst_mariabackup.1 @@ -13,4 +13,4 @@ wsrep_sst_mariabackup \- mariabackup\-based state snapshot transfer .SH DESCRIPTION Use: mariabackup-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_mysqldump.1 b/man/wsrep_sst_mysqldump.1 index cab1ae90bc334..a025be61cde2b 100644 --- a/man/wsrep_sst_mysqldump.1 +++ b/man/wsrep_sst_mysqldump.1 @@ -13,4 +13,4 @@ wsrep_sst_mysqldump \- mysqldump\-based state snapshot transfer .SH DESCRIPTION Use: mysqldump-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_rsync.1 b/man/wsrep_sst_rsync.1 index 93ae6086a7efd..684d7aa360918 100644 --- a/man/wsrep_sst_rsync.1 +++ b/man/wsrep_sst_rsync.1 @@ -13,4 +13,4 @@ wsrep_sst_rsync \- rsync-based state snapshot transfer .SH DESCRIPTION Use: rsync-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/man/wsrep_sst_rsync_wan.1 b/man/wsrep_sst_rsync_wan.1 index 9894bda4231ca..bf5b106d6255c 100644 --- a/man/wsrep_sst_rsync_wan.1 +++ b/man/wsrep_sst_rsync_wan.1 @@ -13,4 +13,4 @@ wsrep_sst_rsync_wan \- rsync_wan (rsync with delta transfers)\-based state snaps .SH DESCRIPTION Use: rsync_wan\-based state snapshot transfer\. .PP -For more information, please refer to the MariaDB Knowledge Base, available online at https://mariadb.com/kb/ +For more information, please refer to the MariaDB Documentation, available online at https://mariadb.com/docs/ diff --git a/mariadb-plugin-columnstore.install.generated b/mariadb-plugin-columnstore.install.generated new file mode 100644 index 0000000000000..d987525f2a671 --- /dev/null +++ b/mariadb-plugin-columnstore.install.generated @@ -0,0 +1 @@ +#File is generated by ColumnstoreLibrary.cmake, do not edit diff --git a/mysql-test/collections/buildbot_suites.bat b/mysql-test/collections/buildbot_suites.bat index b1a4a6f0561fd..053057872bf40 100644 --- a/mysql-test/collections/buildbot_suites.bat +++ b/mysql-test/collections/buildbot_suites.bat @@ -8,6 +8,8 @@ plugins,^ mariabackup,^ roles,^ auth_gssapi,^ +mysql_sha2,^ query_response_time,^ +mysql_sha2,^ rocksdb,^ sysschema diff --git a/mysql-test/include/assert_grep.inc b/mysql-test/include/assert_grep.inc index c4f184405a297..a6abc35c1953f 100644 --- a/mysql-test/include/assert_grep.inc +++ b/mysql-test/include/assert_grep.inc @@ -58,7 +58,7 @@ if ($assert_match == '') { if ($assert_count == '') { - --die !!!ERROR IN TEST: you must set either $assert_match or $assert_count + --die !!!ERROR IN TEST: you must set either \$assert_match or \$assert_count } } if ($assert_match != '') @@ -66,7 +66,7 @@ if ($assert_match != '') if ($assert_count != '') { --echo assert_text='$assert_text' assert_count='$assert_count' - --die !!!ERROR IN TEST: you must set only one of $assert_match or $assert_count + --die !!!ERROR IN TEST: you must set only one of \$assert_match or \$assert_count } } diff --git a/mysql-test/include/binlog_start_pos.inc b/mysql-test/include/binlog_start_pos.inc index 5412a7ea75f54..023678f66ff20 100644 --- a/mysql-test/include/binlog_start_pos.inc +++ b/mysql-test/include/binlog_start_pos.inc @@ -22,7 +22,7 @@ ############################################################################## --disable_query_log -set @binlog_start_pos=256 + @@encrypt_binlog * (36 + (@@binlog_checksum != 'NONE') * 4); +set @binlog_start_pos=257 + @@encrypt_binlog * (36 + (@@binlog_checksum != 'NONE') * 4); --enable_query_log let $binlog_start_pos=`select @binlog_start_pos`; diff --git a/mysql-test/include/check_connect.inc b/mysql-test/include/check_connect.inc new file mode 100644 index 0000000000000..e34d3a4a0d12c --- /dev/null +++ b/mysql-test/include/check_connect.inc @@ -0,0 +1,6 @@ +# Check if connect engine is loaded and enabled + +if (`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'CONNECT' AND support IN ('YES', 'DEFAULT', 'ENABLED')`) +{ + --skip Test requires connect engine +} diff --git a/mysql-test/include/common-tests.inc b/mysql-test/include/common-tests.inc index 890309be5e00a..1cc4ae23446eb 100644 --- a/mysql-test/include/common-tests.inc +++ b/mysql-test/include/common-tests.inc @@ -1737,17 +1737,21 @@ select t2.companynr,companyname,count(*) from t2,t4 where t2.companynr=t4.compan select count(*) from t2; select count(*) from t2 where fld1 < 098024; # PS does correct pre-zero here. MySQL can't do it as it returns a number. +--disable_view_protocol --disable_ps_protocol select min(fld1) from t2 where fld1>= 098024; --enable_ps_protocol +--enable_view_protocol select max(fld1) from t2 where fld1>= 098024; select count(*) from t3 where price2=76234234; select count(*) from t3 where companynr=512 and price2=76234234; explain select min(fld1),max(fld1),count(*) from t2; # PS does correct pre-zero here. MySQL can't do it as it returns a number. +--disable_view_protocol --disable_ps_protocol select min(fld1),max(fld1),count(*) from t2; --enable_ps_protocol +--enable_view_protocol select min(t2nr),max(t2nr) from t3 where t2nr=2115 and price2=823742; select count(*),min(t2nr),max(t2nr) from t3 where name='spates' and companynr=78; select t2nr,count(*) from t3 where name='gems' group by t2nr limit 20; diff --git a/mysql-test/include/crash_mysqld.inc b/mysql-test/include/crash_mysqld.inc index 89bc8ced4161f..6d2e1c522ceee 100644 --- a/mysql-test/include/crash_mysqld.inc +++ b/mysql-test/include/crash_mysqld.inc @@ -1,6 +1,6 @@ # Crash mysqld hard and wait until it's restarted ---source include/have_debug_sync.inc +--source include/have_debug.inc --source include/not_embedded.inc # Write file to make mysql-test-run.pl expect crash and restart diff --git a/mysql-test/include/ctype_numconv.inc b/mysql-test/include/ctype_numconv.inc index 2546980ddc31d..a7e31d1f56b31 100644 --- a/mysql-test/include/ctype_numconv.inc +++ b/mysql-test/include/ctype_numconv.inc @@ -1149,13 +1149,6 @@ insert into t1 values (1.1), (10.1), (100.1), (1000.1), (10000.1); select hex(concat(a)), a from t1; drop table t1; -create table t1 (a year(2)); -insert into t1 values (1); -select hex(concat(a)) from t1; -create table t2 as select concat(a) from t1; -show create table t2; -drop table t1, t2; - create table t1 (a year); insert into t1 values (1); select hex(concat(a)) from t1; @@ -1457,14 +1450,6 @@ select hex(a) from v1; drop table t1; drop view v1; -create table t1 (a year(2)); -insert into t1 values (1); -create view v1(a) as select concat(a) from t1; -show columns from v1; -select hex(a) from v1; -drop table t1; -drop view v1; - create table t1 (a year); insert into t1 values (1); create view v1(a) as select concat(a) from t1; diff --git a/mysql-test/include/deselect_db.inc b/mysql-test/include/deselect_db.inc new file mode 100644 index 0000000000000..eda2875245dcc --- /dev/null +++ b/mysql-test/include/deselect_db.inc @@ -0,0 +1,4 @@ +# Drop the current db. This de-selects any db. +CREATE DATABASE deselect_db; +USE deselect_db; +DROP DATABASE deselect_db; diff --git a/mysql-test/include/galera_variables_ok.inc b/mysql-test/include/galera_variables_ok.inc index 9bd31bb32b2c9..d10bf1fd36e2f 100644 --- a/mysql-test/include/galera_variables_ok.inc +++ b/mysql-test/include/galera_variables_ok.inc @@ -5,7 +5,7 @@ if (!$_galera_variables_delta) { --let $galera_variables_delta=0 } ---let $galera_variables_expected=`SELECT 51 + $galera_variables_delta` +--let $galera_variables_expected=`SELECT 50 + $galera_variables_delta` --let $galera_variables_count=`SELECT COUNT(*) FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep%'` diff --git a/mysql-test/include/grant_cache.inc b/mysql-test/include/grant_cache.inc index 0fccee64372fe..cf85da89826c1 100644 --- a/mysql-test/include/grant_cache.inc +++ b/mysql-test/include/grant_cache.inc @@ -181,27 +181,13 @@ show status like "Qcache_not_cached"; # Cleanup -connection root; disconnect root; ---source include/wait_until_disconnected.inc -connection root2; disconnect root2; ---source include/wait_until_disconnected.inc -connection user1; disconnect user1; ---source include/wait_until_disconnected.inc -connection user2; disconnect user2; ---source include/wait_until_disconnected.inc -connection user3; disconnect user3; ---source include/wait_until_disconnected.inc -connection user4; disconnect user4; ---source include/wait_until_disconnected.inc -connection unkuser; disconnect unkuser; ---source include/wait_until_disconnected.inc connection default; # diff --git a/mysql-test/include/have_des.inc b/mysql-test/include/have_des.inc deleted file mode 100644 index 5abdaf6e2aafe..0000000000000 --- a/mysql-test/include/have_des.inc +++ /dev/null @@ -1,6 +0,0 @@ -# in the FIPS mode, OpenSSL disables DES and other weak algorithms -source include/have_ssl_crypto_functs.inc; - -if (`select des_encrypt("a", "b") IS NULL`) { - skip DES is disabled (fips mode?); -} diff --git a/mysql-test/include/have_innodb_binlog.inc b/mysql-test/include/have_innodb_binlog.inc new file mode 100644 index 0000000000000..c841fece70297 --- /dev/null +++ b/mysql-test/include/have_innodb_binlog.inc @@ -0,0 +1 @@ +--source include/have_innodb.inc diff --git a/mysql-test/include/have_innodb_binlog.opt b/mysql-test/include/have_innodb_binlog.opt new file mode 100644 index 0000000000000..67fff2dd613e7 --- /dev/null +++ b/mysql-test/include/have_innodb_binlog.opt @@ -0,0 +1 @@ +--log-bin --binlog-storage-engine=innodb --max-binlog-size=256K diff --git a/mysql-test/include/icp_debug_kill.inc b/mysql-test/include/icp_debug_kill.inc index d0ecc8428694c..41c9bf6b4bdd3 100644 --- a/mysql-test/include/icp_debug_kill.inc +++ b/mysql-test/include/icp_debug_kill.inc @@ -1,10 +1,5 @@ --source include/have_debug.inc --source include/have_debug_sync.inc ---source include/count_sessions.inc - ---disable_warnings -drop table if exists t0,t1,t2; ---enable_warnings create table t0(a int primary key); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); @@ -46,5 +41,3 @@ set debug_sync='RESET'; disconnect con1; drop table t0,t1,t2; ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/include/invalidate_sp_cache.inc b/mysql-test/include/invalidate_sp_cache.inc new file mode 100644 index 0000000000000..d4503a0f28ec1 --- /dev/null +++ b/mysql-test/include/invalidate_sp_cache.inc @@ -0,0 +1,11 @@ +--echo # source invalidate_sp_cache.inc +--disable_query_log +DELIMITER $$; +CREATE FUNCTION dummy() RETURNS TEXT +BEGIN + RETURN 'dummy'; +END; +$$ +DELIMITER ;$$ +DROP FUNCTION dummy; +--enable_query_log diff --git a/mysql-test/include/kill_binlog_dump_threads.inc b/mysql-test/include/kill_binlog_dump_threads.inc index 38e3e2a7c989c..7c8e63fd52912 100644 --- a/mysql-test/include/kill_binlog_dump_threads.inc +++ b/mysql-test/include/kill_binlog_dump_threads.inc @@ -35,10 +35,17 @@ let $success= 0; while ($wait_counter) { dec $wait_counter; - let $_tid= `SELECT id FROM information_schema.processlist WHERE command = 'Binlog Dump' LIMIT 1`; + # Tricky here. The binlog dump thread will normally be identified by the + # command name "Binlog Dump". But if it was killed, but didn't have time + # to react on the killed yet, it will be 'Killed'. It can also be 'Busy' + # if the code fails to obtain the LOCK_thd_data mutex. + let $_tid= `SELECT IF(command='Binlog Dump', id, -1) FROM information_schema.processlist WHERE command IN ('Binlog Dump', 'Killed', 'Busy') LIMIT 1`; if ($_tid) { - eval KILL QUERY $_tid; + if ($_tid > 0) { + --error 0,ER_NO_SUCH_THREAD + eval KILL CONNECTION $_tid; + } } if (!$_tid) { @@ -55,6 +62,14 @@ if (!$success) SHOW FULL PROCESSLIST; --die Timeout while waiting for binlog dump threads to disappear. } +# This an attempt to get more info about a rare sporadic test failure where +# RESET MASTER still fails with ER_BINLOG_IN_USE after this has run. +--let $sanity_check= `SELECT COUNT(*) FROM information_schema.processlist WHERE command = 'Binlog Dump'` +if ($sanity_check > 0) { + SHOW FULL PROCESSLIST; + --echo ERROR: still $sanity_check dump thread(s) found! + --die ERROR: still $sanity_check dump thread(s) found +} --enable_query_log diff --git a/mysql-test/include/percona_nonflushing_analyze_debug.inc b/mysql-test/include/percona_nonflushing_analyze_debug.inc index 8cdf6218609fa..8ecb9e45a2ed4 100644 --- a/mysql-test/include/percona_nonflushing_analyze_debug.inc +++ b/mysql-test/include/percona_nonflushing_analyze_debug.inc @@ -4,8 +4,6 @@ # $percona_nonflushing_analyze_table - table to test # ---source include/count_sessions.inc - --connect con1,localhost,root SET DEBUG_SYNC="handler_rnd_next_end SIGNAL idx_scan_in_progress WAIT_FOR finish_scan"; @@ -31,5 +29,3 @@ reap; --disconnect con1 --connection default SET DEBUG_SYNC='reset'; - ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/include/query_cache.inc b/mysql-test/include/query_cache.inc index 840118206f502..f6aae89b81f9a 100644 --- a/mysql-test/include/query_cache.inc +++ b/mysql-test/include/query_cache.inc @@ -189,7 +189,6 @@ show status like "Qcache_hits"; # Final cleanup disconnect connection1; ---source include/wait_until_disconnected.inc connection default; set @@global.query_cache_size = @save_query_cache_size; drop table t2; diff --git a/mysql-test/include/require_openssl_client.inc b/mysql-test/include/require_openssl_client.inc index 9b19960041b40..463c44fc8b275 100644 --- a/mysql-test/include/require_openssl_client.inc +++ b/mysql-test/include/require_openssl_client.inc @@ -1,5 +1,5 @@ if ($CLIENT_TLS_LIBRARY != "OpenSSL") { if ($CLIENT_TLS_LIBRARY != "LibreSSL") { - skip "Test requires Connector/C with OpenSSL library"; + skip Test requires Connector/C with OpenSSL library; } } diff --git a/mysql-test/include/reset_master.inc b/mysql-test/include/reset_master.inc new file mode 100644 index 0000000000000..b4036ec31be0f --- /dev/null +++ b/mysql-test/include/reset_master.inc @@ -0,0 +1,58 @@ +# ==== Purpose ==== +# +# Execute a RESET MASTER on the current connection, first terminating any +# lingering binlog dump threads that might still be sitting idle and would +# block the RESTE MASTER. +# +# Note that any configured IO threads on other servers must be stopped before +# calling this, as RESET MASTER cannot be run while there is a slave connected. +# +# +# ==== Usage ==== +# +# [--let $kill_timeout= NUMBER] +# [--let $reset_master_retries= NUMBER] +# --source include/reset_master.inc +# +# Parameters: +# $kill_timeout +# Maximum number of seconds to wait for dump threads to disappear. +# $reset_master_retries +# Maximum number of times RESET MASTER can get ER_BINLOG_IN_USE before +# giving up. + +--let $include_filename= reset_master.inc +--source include/begin_include_file.inc + +--disable_query_log + +let $_retries= 10; +if ($reset_master_retries) +{ + let $_retries= $reset_master_retries; +} + +let $_success= 0; +let $_i= 0; +while ($_i < $_retries) +{ + inc $_i; + --source include/kill_binlog_dump_threads.inc + --let $errno= 0 + --error 0,ER_BINLOG_IN_USE + RESET MASTER; + if (!$errno) { + let $_success= 1; + let $_i = $_retries; + } +} +if (!$_success) +{ + SHOW FULL PROCESSLIST; + --die Timeout while trying to remove dump threads and run RESET MASTER. +} + +--enable_query_log + +--let $include_filename= reset_master.inc +--source include/end_include_file.inc diff --git a/mysql-test/include/reset_master_slave.inc b/mysql-test/include/reset_master_slave.inc index af66da2bb8bfb..a468ee873be39 100644 --- a/mysql-test/include/reset_master_slave.inc +++ b/mysql-test/include/reset_master_slave.inc @@ -21,6 +21,7 @@ while ($con_name != 'No such row') --let $con_name = query_get_value(show all slaves status, Connection_name, 1) } +--source include/kill_binlog_dump_threads.inc --error 0,ER_FLUSH_MASTER_BINLOG_CLOSED reset master; set global gtid_slave_pos=''; diff --git a/mysql-test/include/rowid_filter_debug_kill.inc b/mysql-test/include/rowid_filter_debug_kill.inc index 5c3ae214f02c6..8e90e8f728616 100644 --- a/mysql-test/include/rowid_filter_debug_kill.inc +++ b/mysql-test/include/rowid_filter_debug_kill.inc @@ -1,7 +1,6 @@ --source include/have_debug.inc --source include/have_debug_sync.inc --source include/have_sequence.inc ---source include/count_sessions.inc --source include/have_sequence.inc --source include/no_valgrind_without_big.inc @@ -80,4 +79,3 @@ set debug_sync='RESET'; drop table t2,t3; ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc b/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc index b46da97cafa28..284561d7f564b 100644 --- a/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc +++ b/mysql-test/include/rpl_clone_slave_using_mariadb-backup.inc @@ -293,6 +293,7 @@ if ($cnf == "galera2_to_mariadb") --connection master set global wsrep_on=OFF; + --source include/kill_binlog_dump_threads.inc RESET MASTER; set global wsrep_on=ON; } diff --git a/mysql-test/include/rpl_heartbeat.inc b/mysql-test/include/rpl_heartbeat.inc new file mode 100644 index 0000000000000..248d5652e7874 --- /dev/null +++ b/mysql-test/include/rpl_heartbeat.inc @@ -0,0 +1,124 @@ +# Testing master to slave heartbeat protocol +# Shared between rpl.rpl_heartbeat and binlog_in_engine.rpl_heartbeat. +# +# Including: +# - no rotation of relay log if heartbeat is less that slave_net_timeout +# - SHOW STATUS like 'Slave_received_heartbeats' action +# - SHOW STATUS like 'Slave_heartbeat_period' report +# +# `rpl.rpl_heartbeat_basic` tests the user interface, grammar, range, +# and warnings about unreasonable values for the heartbeat period. + +connection slave; +-- source include/stop_slave.inc + +connection master; +--source include/kill_binlog_dump_threads.inc +reset master; + +connection slave; +set @restore_slave_net_timeout= @@global.slave_net_timeout; +--disable_warnings +set @@global.slave_net_timeout= 10; +--enable_warnings + +--enable_prepare_warnings +# +# A warning if slave_net_timeout is set to less than the current HB period +# +set @@global.slave_net_timeout= 5; +--replace_result $MASTER_MYPORT MASTER_PORT +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_heartbeat_period= 4; +--query_vertical show status like 'Slave_heartbeat_period'; +set @@global.slave_net_timeout= 3 /* must be a warning */; + +reset slave; + + +### +### checking no rotation +### + +connection master; +--disable_warnings +drop table if exists t1; +--enable_warnings +# +# Even though master_heartbeat_period= 0.5 is 20 times less than +# @@global.slave_net_timeout= 10 in some circumstances master will +# not be able to send any heartbeat during the slave's net timeout +# and slave's relay log will rotate. +# The probability for such a scenario is pretty small so the following +# part is almost deterministic. +# + +connection slave; +set @@global.slave_net_timeout= 10; +--replace_result $MASTER_MYPORT MASTER_PORT +# no error this time but rather a warning +eval change master to master_host='127.0.0.1',master_port=$MASTER_MYPORT, master_user='root', master_ssl_verify_server_cert=0, master_heartbeat_period= 0.5; +--query_vertical show status like 'Slave_heartbeat_period'; + +start slave; + +connection master; +create table t1 (f1 int); + +connection master; +--source include/save_master_gtid.inc +connection slave; +--source include/sync_with_master_gtid.inc +let $slave_param= Relay_Log_File; +let $slave_param_value= query_get_value(SHOW SLAVE STATUS, Relay_Log_File, 1); + +# there is an explicit sleep lasting longer than slave_net_timeout +# to ensure that nothing will come to slave from master for that period. +# That would cause reconnecting and relaylog rotation w/o the fix i.e +# without a heartbeat received. + +real_sleep 15; + +# check (compare with the previous show's results) that no rotation happened +source include/check_slave_param.inc; + +### +### SHOW STATUS like 'Slave_heartbeat_period' and 'Slave_received_heartbeats' +### + +--query_vertical show status like 'Slave_heartbeat_period'; + +# +# proof that there has been received at least one heartbeat; +# The exact number of received heartbeat is an indeterministic value +# and therefore it's not recorded into results. +# + +let $slave_wait_param_counter= 300; +let $slave_value= query_get_value("SHOW STATUS like 'Slave_received_heartbeats'", Value, 1); +# Checking the fact that at least one heartbeat is received +while (!$slave_value) +{ + dec $slave_wait_param_counter; + if (!$slave_wait_param_counter) + { + --echo ERROR: failed while waiting for slave parameter $slave_param: $slave_param_value + query_vertical show slave status; + SHOW STATUS like 'Slave_received_heartbeats'; + exit; + } + sleep 0.1; + let $slave_value= query_get_value("SHOW STATUS like 'Slave_received_heartbeats'", Value, 1); +} +--echo A heartbeat has been received by the slave +# cleanup + +connection master; +drop table t1; + +connection master; +--source include/save_master_gtid.inc +connection slave; +--source include/sync_with_master_gtid.inc +set @@global.slave_net_timeout= @restore_slave_net_timeout; + +--disable_prepare_warnings diff --git a/mysql-test/include/rpl_init.inc b/mysql-test/include/rpl_init.inc index 26ce4e1b57fd8..671943340b35a 100644 --- a/mysql-test/include/rpl_init.inc +++ b/mysql-test/include/rpl_init.inc @@ -162,6 +162,7 @@ while ($_rpl_server) USE test; if (!$rpl_skip_reset_master_and_slave) { + --source include/kill_binlog_dump_threads.inc if (!$rpl_server_skip_log_bin) { --error 0 diff --git a/mysql-test/include/rpl_ip_mix.inc b/mysql-test/include/rpl_ip_mix.inc index d547d77a3ccb1..01db8b4d77d8b 100644 --- a/mysql-test/include/rpl_ip_mix.inc +++ b/mysql-test/include/rpl_ip_mix.inc @@ -1,6 +1,7 @@ connect (master,$IPv6,root,,test,$MASTER_MYPORT); connect (slave,127.0.0.1,root,,test,$SLAVE_MYPORT); connection master; +--source include/kill_binlog_dump_threads.inc reset master; source include/show_master_status.inc; save_master_pos; diff --git a/mysql-test/include/rpl_ipv6.inc b/mysql-test/include/rpl_ipv6.inc index 69f282e22d98f..762e51a82e987 100644 --- a/mysql-test/include/rpl_ipv6.inc +++ b/mysql-test/include/rpl_ipv6.inc @@ -1,5 +1,6 @@ connect (master,$IPv6,root,,test,$MASTER_MYPORT); connect (slave,$IPv6,root,,test,$SLAVE_MYPORT); +--source include/kill_binlog_dump_threads.inc connection master; reset master; source include/show_master_status.inc; diff --git a/mysql-test/include/rpl_multi_engine2.inc b/mysql-test/include/rpl_multi_engine2.inc index 24154220cb098..e7cd7ef38d318 100644 --- a/mysql-test/include/rpl_multi_engine2.inc +++ b/mysql-test/include/rpl_multi_engine2.inc @@ -9,6 +9,7 @@ STOP SLAVE; RESET SLAVE; connection master; +--source include/kill_binlog_dump_threads.inc RESET MASTER; connection slave; diff --git a/mysql-test/include/rpl_parallel_temptable.inc b/mysql-test/include/rpl_parallel_temptable.inc new file mode 100644 index 0000000000000..28ff0a408eb07 --- /dev/null +++ b/mysql-test/include/rpl_parallel_temptable.inc @@ -0,0 +1,302 @@ +--echo *** MDEV-6321: close_temporary_tables() in format description event not serialised correctly *** + +--connection server_2 +SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads; +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=5; +--source include/start_slave.inc + +--connection server_1 +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(100) CHARACTER SET utf8); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + + +--connection server_1 +SET gtid_domain_id= 1; +INSERT INTO t1 VALUES (1, 0); + +CREATE TEMPORARY TABLE t2 (a int); + +--connection default +SET gtid_domain_id= 2; +CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY); +CREATE TEMPORARY TABLE t4 (a int); +INSERT INTO t3 VALUES (100); +INSERT INTO t4 SELECT a+1 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (2), (4), (6), (8), (10), (12), (14), (16), (18), (20); +INSERT INTO t2 VALUES (3), (6), (9), (12), (15), (18); +INSERT INTO t2 VALUES (4), (8), (12), (16), (20); + +--connection default +INSERT INTO t3 SELECT a+2 FROM t4; +INSERT INTO t4 SELECT a+4 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (5), (10), (15), (20); +INSERT INTO t2 VALUES (6), (12), (18); +INSERT INTO t2 VALUES (7), (14); +INSERT INTO t2 VALUES (8), (16); +INSERT INTO t2 VALUES (9), (18); +INSERT INTO t2 VALUES (10), (20); + +--connection default +INSERT INTO t3 SELECT a+8 FROM t4; +INSERT INTO t4 SELECT a+16 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (11); +INSERT INTO t2 VALUES (12); +INSERT INTO t2 VALUES (13); + +--connection default +INSERT INTO t3 SELECT a+32 FROM t4; + +--connection server_1 +INSERT INTO t2 VALUES (14); +INSERT INTO t2 VALUES (15); +INSERT INTO t2 VALUES (16); + +--connection default +INSERT INTO t4 SELECT a+64 FROM t3; + +--connection server_1 +INSERT INTO t2 VALUES (17); +INSERT INTO t2 VALUES (18); +INSERT INTO t2 VALUES (19); + +--connection default +INSERT INTO t3 SELECT a+128 FROM t4; + +--connection server_1 +INSERT INTO t2 VALUES (20); + +--connection default +INSERT INTO t1 SELECT a, a MOD 7 FROM t3; +INSERT INTO t1 SELECT a, a MOD 7 FROM t4; + +--connection server_1 +INSERT INTO t1 SELECT a, COUNT(*) FROM t2 GROUP BY a; + +# Crash the master server, so that temporary tables are implicitly dropped. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +FLUSH TABLES; +SET SESSION debug_dbug="+d,crash_dispatch_command_before"; +--error 2006,2013 +SELECT 1; + +--source include/wait_until_disconnected.inc +--connection default +--source include/wait_until_disconnected.inc + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +--connection default +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc + +INSERT INTO t1 VALUES (0, 1); +--source include/save_master_gtid.inc + +--connection server_2 +# Start the slave replicating the events. +# The bug was that the format description event written after the crash could +# be fetched ahead of the execution of the temporary table events and executed +# out-of-band. This would cause drop of all temporary tables and thus failure +# for execution of remaining events. + +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 WHERE a <= 20 ORDER BY a; +SELECT COUNT(*) FROM t1 WHERE a BETWEEN 100+0 AND 100+256; +SHOW STATUS LIKE 'Slave_open_temp_tables'; + + +--echo *** Test that if master logged partial event group before crash, we finish that group correctly before executing format description event *** + +--source include/stop_slave.inc + +--connection server_1 +CALL mtr.add_suppression("Statement accesses nontransactional table as well as transactional or temporary table, and writes to any of them"); +SET gtid_domain_id= 1; +DELETE FROM t1; +ALTER TABLE t1 ENGINE=InnoDB; +CREATE TEMPORARY TABLE t2 (a INT PRIMARY KEY); +INSERT INTO t2 VALUES (1); +INSERT INTO t2 VALUES (2); + +--connection default +SET gtid_domain_id= 2; +CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY); +INSERT INTO t3 VALUES (10); +INSERT INTO t3 VALUES (20); + +--connection server_1 +INSERT INTO t1 SELECT a, 'server_1' FROM t2; + +--connection default +INSERT INTO t1 SELECT a, 'default' FROM t3; + +--connection server_1 +INSERT INTO t1 SELECT a+2, '+server_1' FROM t2; + +# Crash the master server in the middle of writing an event group. +--write_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +wait +EOF + +# Don't run this part of the test when testing binlog-in-engine. +# Because with binlog-in-engine, partial event groups cannot result +# from server crash, binlog writes are atomic and crash-recovered. +if (!$binlog_in_engine) { + FLUSH TABLES; + SET SESSION debug_dbug="+d,crash_before_writing_xid"; + --error 2006,2013 + INSERT INTO t1 SELECT a+4, '++server_1' FROM t2; + +--source include/wait_until_disconnected.inc +--connection default +--source include/wait_until_disconnected.inc +} + +--append_file $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +restart +EOF + +if (!$binlog_in_engine) { +--connection default +--enable_reconnect +--source include/wait_until_connected_again.inc + +--connection server_1 +--enable_reconnect +--source include/wait_until_connected_again.inc +} +if ($binlog_in_engine) { + # Drop the temporary tables manually, as we did not crash the server. + --connection default + DROP TEMPORARY TABLE t3; + --connection server_1 + DROP TEMPORARY TABLE t2; +} + +INSERT INTO t1 VALUES (0, 1); +--source include/save_master_gtid.inc + +--connection server_2 +# Start the slave replicating the events. +# The main thing to test here is that the slave will know that it +# needs to abort the partially received event group, so that the +# execution of format_description event will not wait infinitely +# for a commit of the incomplete group that never happens. + +# Apart from the suppression, MDEV-27697 refinement to the original test needs +# an allowance to one time accept malformed event group. +set @@sql_log_bin=0; +call mtr.add_suppression("Unexpected break of being relay-logged GTID 1-1-32 event group by the current GTID event 0-1-4"); +set @@sql_log_bin=1; +set @@global.debug_dbug="+d,slave_discard_xid_for_gtid_0_x_1000"; +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +set @@global.debug_dbug=""; + +SELECT * FROM t1 ORDER BY a; +SHOW STATUS LIKE 'Slave_open_temp_tables'; + +--connection server_1 +# This FLUSH can be removed once MDEV-6608 is fixed. +FLUSH LOGS; + +--echo *** MDEV-7936: Assertion `!table || table->in_use == _current_thd()' failed on parallel replication in optimistic mode *** + +--connection server_1 +CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +SET @old_dbug= @@SESSION.debug_dbug; +SET SESSION debug_dbug="+d,binlog_force_commit_id"; +SET @commit_id= 10000; +INSERT INTO t4 VALUES (30); +INSERT INTO t4 VALUES (31); +SET SESSION debug_dbug= @old_dbug; +INSERT INTO t1 SELECT a, "conservative" FROM t4; +DROP TEMPORARY TABLE t4; +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + +--source include/stop_slave.inc +SET @old_mode= @@GLOBAL.slave_parallel_mode; +SET GLOBAL slave_parallel_mode=optimistic; + +--connection server_1 +CREATE TEMPORARY TABLE t4 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t4 VALUES (32); +INSERT INTO t4 VALUES (33); +INSERT INTO t1 SELECT a, "optimistic" FROM t4; +DROP TEMPORARY TABLE t4; + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc + +SELECT * FROM t1 WHERE a >= 30 ORDER BY a; + +--source include/stop_slave.inc +SET GLOBAL slave_parallel_mode=@old_mode; +--source include/start_slave.inc + + +--echo *** MDEV33426: Memory allocation accounting incorrect for replicated temptable +--connection server_1 +CREATE TEMPORARY TABLE t5 (a int) ENGINE=Aria; +CREATE TEMPORARY TABLE t6 (a int) ENGINE=Heap; +INSERT INTO t5 VALUES (1); +INSERT INTO t6 VALUES (2); +--source include/save_master_gtid.inc + +--connection server_2 +--source include/sync_with_master_gtid.inc +--source include/stop_slave.inc + +--connection server_1 +INSERT INTO t1 SELECT a+40, 5 FROM t5; +INSERT INTO t1 SELECT a+40, 6 FROM t6; +DROP TABLE t5, t6; + +--source include/save_master_gtid.inc + +--connection server_2 +--source include/start_slave.inc +--source include/sync_with_master_gtid.inc +SELECT * FROM t1 WHERE a>=40 ORDER BY a; + +# Clean up. + +--connection server_2 +--source include/stop_slave.inc +SET GLOBAL slave_parallel_threads=@old_parallel_threads; +--source include/start_slave.inc + +--connection server_1 +DROP TABLE t1; diff --git a/mysql-test/include/rpl_reset.inc b/mysql-test/include/rpl_reset.inc index 53ed1de98749d..82961c2e0e0e9 100644 --- a/mysql-test/include/rpl_reset.inc +++ b/mysql-test/include/rpl_reset.inc @@ -31,6 +31,9 @@ # Set the timeout when waiting for slave threads to stop and # start, respectively. See include/wait_for_slave_param.inc # +# $rpl_skip_sync +# Don't sync the slaves before resetting them. +# # Note: # This script will fail if Last_SQL_Error or Last_IO_Error is # nonempty. If you expect an error in the SQL thread, you should @@ -50,7 +53,10 @@ if (!$rpl_debug) } ---source include/rpl_sync.inc +if (!$rpl_skip_sync) +{ + --source include/rpl_sync.inc +} if ($rpl_debug) @@ -63,11 +69,26 @@ while ($_rpl_server) --let $rpl_connection_name= server_$_rpl_server --source include/rpl_connection.inc - RESET MASTER; # Check if this server is configured to have a master if (`SELECT SUBSTRING('$rpl_master_list', 1 + ($_rpl_server - 1) * $rpl_server_count_length, $rpl_server_count_length) != ''`) { --source include/stop_slave.inc + } + --dec $_rpl_server +} + +--let $_rpl_server= $rpl_server_count +while ($_rpl_server) +{ + --let $rpl_connection_name= server_$_rpl_server + --source include/rpl_connection.inc + + --source include/kill_binlog_dump_threads.inc + RESET MASTER; + + # Check if this server is configured to have a master + if (`SELECT SUBSTRING('$rpl_master_list', 1 + ($_rpl_server - 1) * $rpl_server_count_length, $rpl_server_count_length) != ''`) + { --source include/reset_slave.inc } --dec $_rpl_server diff --git a/mysql-test/include/rpl_restart_server.inc b/mysql-test/include/rpl_restart_server.inc index 5df2c67d3da23..c2b6427390374 100644 --- a/mysql-test/include/rpl_restart_server.inc +++ b/mysql-test/include/rpl_restart_server.inc @@ -6,6 +6,7 @@ # ==== Usage ==== # # --let $rpl_server_number= N +# [--let $shutdown_timeout= 60] # [--let $rpl_server_parameters= --flag1 --flag2 ...] # [--let $rpl_debug= 1] # --source include/rpl_restart_server.inc diff --git a/mysql-test/include/rpl_stmt_seq.inc b/mysql-test/include/rpl_stmt_seq.inc index b23178ee5343a..372473cfb7f52 100644 --- a/mysql-test/include/rpl_stmt_seq.inc +++ b/mysql-test/include/rpl_stmt_seq.inc @@ -81,7 +81,10 @@ if ($show_binlog) --let $binlog_file= master-bin.$_log_num_s --source include/show_binlog_events.inc } -sync_slave_with_master; +--connection master +--source include/save_master_gtid.inc +--connection slave +--source include/sync_with_master_gtid.inc connection slave; # results before DDL(to be tested) @@ -106,7 +109,10 @@ if ($show_binlog) --let $binlog_file= master-bin.$_log_num_s --source include/show_binlog_events.inc } -sync_slave_with_master; +--connection master +--source include/save_master_gtid.inc +--connection slave +--source include/sync_with_master_gtid.inc connection slave; # results after DDL(to be tested) @@ -139,7 +145,10 @@ if ($show_binlog) --let $binlog_file= master-bin.$_log_num_s --source include/show_binlog_events.inc } -sync_slave_with_master; +--connection master +--source include/save_master_gtid.inc +--connection slave +--source include/sync_with_master_gtid.inc connection slave; # results after final ROLLBACK @@ -173,7 +182,10 @@ connection master; flush logs; # sleep 1; # eval SHOW BINLOG EVENTS IN 'master-bin.$_log_num_s'; -sync_slave_with_master; +--connection master +--source include/save_master_gtid.inc +--connection slave +--source include/sync_with_master_gtid.inc connection slave; # the final content of the binary log diff --git a/mysql-test/include/rpl_stop_server.inc b/mysql-test/include/rpl_stop_server.inc index 1e4a64cca250d..ee331d49cad7a 100644 --- a/mysql-test/include/rpl_stop_server.inc +++ b/mysql-test/include/rpl_stop_server.inc @@ -5,6 +5,7 @@ # ==== Usage ==== # # --let $rpl_server_number= N +# [--let $shutdown_timeout= 60] # [--let $rpl_debug= 1] # --source include/rpl_stop_server.inc # @@ -50,6 +51,10 @@ if ($rpl_debug) # it 60 seconds (of mysqltest's default) to die before zapping it let $rpl_shutdown_timeout= `select 60*(1+9*count(*)) from information_schema.system_variables where variable_name='have_sanitizer' and global_value like "MSAN%"`; +if ($shutdown_timeout != '') { + --let $rpl_shutdown_timeout= $shutdown_timeout +} + shutdown_server $rpl_shutdown_timeout; --source include/wait_until_disconnected.inc diff --git a/mysql-test/include/rpl_sync.inc b/mysql-test/include/rpl_sync.inc index 83d4a2e4628bc..64275fade63f1 100644 --- a/mysql-test/include/rpl_sync.inc +++ b/mysql-test/include/rpl_sync.inc @@ -10,6 +10,7 @@ # [--let $rpl_only_running_threads= 1] # [--let $rpl_debug= 1] # [--let $slave_timeout= NUMBER] +# [--let $disable_gtid= 1] # --source include/rpl_sync.inc # # Parameters: @@ -23,6 +24,11 @@ # - If only SQL thread is running, sync SQL thread with IO thread. # - If no thread is running, don't sync. # +# $disable_gtid +# Use old-style file/offset for syncing, even if slave is configured +# to connect using GTID. (Useful for tests that run without properly +# configuring domain_id, like rpl.rpl_circular_for_4_hosts). +# # $slave_timeout # Set the timeout when waiting for threads to sync. See # include/wait_for_slave_param.inc @@ -75,6 +81,17 @@ while ($_rpl_i) { if ($_rpl_server) { + disable_query_log; + --connection server_$_rpl_server + enable_query_log; + # By default, sync using GTID (when GTID is enabled), as GTID is now + # on by default. But allow to fallback explicitly to old-style file/pos + # for tests that need this. + --let $_rpl_gtid_mode= query_get_value(SHOW SLAVE STATUS, Using_Gtid, 1) + if ($disable_gtid) + { + --let $_rpl_gtid_mode= No + } if ($rpl_debug) { --echo [sync server_$_rpl_prev_server -> server_$_rpl_server] @@ -99,15 +116,30 @@ while ($_rpl_i) { enable_query_log; if ($_rpl_slave_sql_running) { - if ($rpl_debug) + if ($_rpl_gtid_mode == 'No') + { + if ($rpl_debug) + { + --let $_rpl_master_file= query_get_value("SHOW MASTER STATUS", File, 1) + --let $_rpl_master_pos= query_get_value("SHOW MASTER STATUS", Position, 1) + --echo syncing master_file='$_rpl_master_file' master_pos='$_rpl_master_pos' + } + disable_connect_log; + --sync_slave_with_master server_$_rpl_server + enable_connect_log; + } + if ($_rpl_gtid_mode != 'No') { - --let $_rpl_master_file= query_get_value("SHOW MASTER STATUS", File, 1) - --let $_rpl_master_pos= query_get_value("SHOW MASTER STATUS", Position, 1) - --echo syncing master_file='$_rpl_master_file' master_pos='$_rpl_master_pos' + --source include/save_master_gtid.inc + disable_connect_log; + --connection server_$_rpl_server + if ($rpl_debug) + { + --echo syncing with GTID position '$master_pos' + } + --source include/sync_with_master_gtid.inc + enable_connect_log; } - disable_connect_log; - --sync_slave_with_master server_$_rpl_server - enable_connect_log; } if (!$_rpl_slave_sql_running) { @@ -127,13 +159,25 @@ while ($_rpl_i) { { disable_connect_log; --connection server_$_rpl_prev_server - if ($rpl_debug) - { - --let $_rpl_master_file= query_get_value("SHOW MASTER STATUS", File, 1) - --let $_rpl_master_pos= query_get_value("SHOW MASTER STATUS", Position, 1) - --echo syncing master_file='$_rpl_master_file' master_pos='$_rpl_master_pos' + if ($_rpl_gtid_mode == 'No') { + if ($rpl_debug) + { + --let $_rpl_master_file= query_get_value("SHOW MASTER STATUS", File, 1) + --let $_rpl_master_pos= query_get_value("SHOW MASTER STATUS", Position, 1) + --echo syncing master_file='$_rpl_master_file' master_pos='$_rpl_master_pos' + } + --sync_slave_with_master server_$_rpl_server + } + if ($_rpl_gtid_mode != 'No') { + --source include/save_master_gtid.inc + disable_connect_log; + --connection server_$_rpl_server + if ($rpl_debug) + { + --echo syncing with GTID position'$master_pos' + } + --source include/sync_with_master_gtid.inc } - --sync_slave_with_master server_$_rpl_server enable_connect_log; } } diff --git a/mysql-test/include/show_binlog_events2.inc b/mysql-test/include/show_binlog_events2.inc index 69391ff8fa2f0..ef1c45f700ebf 100644 --- a/mysql-test/include/show_binlog_events2.inc +++ b/mysql-test/include/show_binlog_events2.inc @@ -26,7 +26,7 @@ if ($binlog_start) } if (!$binlog_start) { - --let $_binlog_start=256 + --let $_binlog_start=257 } if ($binlog_file) { diff --git a/mysql-test/include/show_master_status.inc b/mysql-test/include/show_master_status.inc index b7b32a65df411..642b06f64d731 100644 --- a/mysql-test/include/show_master_status.inc +++ b/mysql-test/include/show_master_status.inc @@ -1,5 +1,5 @@ # show master status # mask out the binlog position --- replace_column 2 # 3 4 +--replace_column 2 # 3 4 5 show master status; diff --git a/mysql-test/include/test_fieldsize.inc b/mysql-test/include/test_fieldsize.inc index 1ce846eed0b49..cbf69c2df80c4 100644 --- a/mysql-test/include/test_fieldsize.inc +++ b/mysql-test/include/test_fieldsize.inc @@ -17,6 +17,7 @@ eval $test_table_slave; connection master; eval $test_table_master; +--source include/kill_binlog_dump_threads.inc RESET MASTER; eval $test_insert; @@ -33,6 +34,7 @@ STOP SLAVE; --source include/reset_slave.inc connection master; +--source include/kill_binlog_dump_threads.inc RESET MASTER; connection slave; diff --git a/mysql-test/include/wait_for_engine_binlog.inc b/mysql-test/include/wait_for_engine_binlog.inc new file mode 100644 index 0000000000000..040d1de6279ce --- /dev/null +++ b/mysql-test/include/wait_for_engine_binlog.inc @@ -0,0 +1,77 @@ +# include/wait_for_engine_binlog.inc +# +# SUMMARY +# +# Waits until a specific (engine-implemented) binlog file is seen with +# the specified size in SHOW BINARY LOGS. +# Used to avoid sporadic failures due to races with the binlog +# pre-allocation thread. +# +# USAGE +# +# --let $binlog_name= binlog-000002.ibb +# --let $binlog_size= 262144 +# --source include/wait_for_engine_binlog.inc +# +# OPTIONALLY: +# +# let $wait_timeout= 60; # Override default 30 seconds with 60. +# let $wait_notfound= 1; # Wait until specified binlog _not_ found. +# +# EXAMPLE +# binlog_in_engine.binlog_flush_purge.test +# + +--disable_query_log + +let $_wait_counter= 300; +if ($wait_timeout) +{ + let $_wait_counter= `SELECT $wait_timeout * 10`; +} +# Reset $wait_timeout so that its value won't be used on subsequent +# calls, and default will be used instead. +let $wait_timeout= 0; + +--let $_expect= 1 +--let $_message= exist +if ($wait_notfound) { + --let $_expect= 0 + --let $_message= no longer exist +} +let $wait_notfound= 0; + +--let $_done= 0 +--let $_i= 0 +while (!$_done) { + --let $_j= 1 + --let $_end= 0 + --let $_found= 0 + while (!$_end) { + --let $_x= query_get_value(SHOW BINARY LOGS, Log_name, $_j) + if ($_x == No such row) { + --let $_end= 1 + } + if ($_x == $binlog_name) { + --let $_y= query_get_value(SHOW BINARY LOGS, File_size, $_j) + if ($_y == $binlog_size) { + --let $_found= 1 + --let $_end= 1 + } + } + inc $_j; + } + if ($_found == $_expect) { + --let $_done= 1 + } + if (!$_done) { + sleep 0.1; + inc $_i; + if ($_i >= $_wait_counter) { + SHOW BINARY LOGS; + --die Timeout waiting for binlog '$binlog_name' to $_message + } + } +} + +--enable_query_log diff --git a/mysql-test/include/wait_for_line_count_in_file.inc b/mysql-test/include/wait_for_line_count_in_file.inc index 838a3ff342bfa..93531821f1314 100644 --- a/mysql-test/include/wait_for_line_count_in_file.inc +++ b/mysql-test/include/wait_for_line_count_in_file.inc @@ -15,4 +15,5 @@ perl; die "Timeout waiting for $search_count lines in $search_file\n"; sleep(0.1); } + print "Line count in file: $search_count\n"; EOF diff --git a/mysql-test/lib/My/Debugger.pm b/mysql-test/lib/My/Debugger.pm index 2ab8a3520c897..a3985e65bab96 100644 --- a/mysql-test/lib/My/Debugger.pm +++ b/mysql-test/lib/My/Debugger.pm @@ -81,6 +81,7 @@ my %debuggers = ( options => '_RR_TRACE_DIR={log} rr record {exe} {args}', run => 'env', pre => sub { + push @::global_suppressions, qr/InnoDB: native AIO failed/; ::mtr_error('rr requires kernel.perf_event_paranoid <= 1') if ::mtr_grab_file('/proc/sys/kernel/perf_event_paranoid') > 1; } diff --git a/mysql-test/lib/My/SafeProcess/safe_process.cc b/mysql-test/lib/My/SafeProcess/safe_process.cc index dcaea161097db..204351bbc4014 100644 --- a/mysql-test/lib/My/SafeProcess/safe_process.cc +++ b/mysql-test/lib/My/SafeProcess/safe_process.cc @@ -237,7 +237,8 @@ int main(int argc, char* const argv[] ) sigaction(SIGCHLD, &sa,NULL); sigaction(SIGABRT, &sa_abort,NULL); - sprintf(safe_process_name, "safe_process[%ld]", (long) own_pid); + snprintf(safe_process_name, sizeof(safe_process_name), + "safe_process[%ld]", (long) own_pid); message("Started"); diff --git a/mysql-test/lib/generate-ssl-certs.sh b/mysql-test/lib/generate-ssl-certs.sh index f698464b93294..1c6cda56fe2d0 100755 --- a/mysql-test/lib/generate-ssl-certs.sh +++ b/mysql-test/lib/generate-ssl-certs.sh @@ -67,3 +67,156 @@ rm -fv crldir/* cp -v client-cert.crl crldir/`openssl x509 -in client-cert.pem -noout -issuer_hash`.r0 rm -rf demoCA + +# --- Certificate Chain --- +# These tests are inspired from the following commit from MySQL Server +# https://github.com/mysql/mysql-server/commit/969afef933f1872c5f38ea93047ef05c4509c335 +# +# Credits to salman.s.khan@oracle.com +# +# ------------------------------------------------------------------------------------- +# +# STEPS TO GENERATE THE FOLLOWING CHAINED CERTIFICATES WHICH IS USED IN THE TEST CASE : +# +# +---------+ +# | Root CA | +# +---------+ +# | +# /------------+-----------\ +# | | +# +------------------+ +------------------+ +# | Intermediate CA1 | | Intermediate CA2 | +# +------------------+ +------------------+ +# | | +# +-------------+ +-------------+ +# | Server | | Client | +# | certificate | | certificate | +# +-------------+ +-------------+ + +cd cachain + +mkdir ca +mkdir server +mkdir clients + +mkdir ca/root.certs +touch ca/root.index.txt +touch ca/root.index.txt.attr +echo '01' > ca/root.serial + +cat > ca/root.cfg << EOF +[ ca ] +default_ca = CA_default +[ CA_default ] +dir = $PWD/ca +certs = \$dir/certs +database = \$dir/root.index.txt +serial = \$dir/root.serial +policy= policy_match +[ policy_match ] +organizationName = match +organizationalUnitName = optional +commonName = supplied +emailAddress = optional +[ v3_ca ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = critical,CA:TRUE +keyUsage = critical,keyCertSign,cRLSign +[ v3_ca_intermediate ] +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid:always,issuer +basicConstraints = critical,CA:TRUE,pathlen:0 +keyUsage = critical,keyCertSign,cRLSign +EOF + +# Generate Root CA key and cert +openssl genrsa -out ca/root.key 4096 +openssl req -new -x509 '-sha256' -key ca/root.key -out ca/root.crt -days 7200 -subj "/O=MariaDB/OU=MariaDB/CN=Root CA" -config ca/root.cfg -extensions v3_ca + +# Generate Intermediate CA1 key and cert +openssl genrsa -out ca/intermediate_ca1.key 4096 +openssl req -new '-sha256' -key ca/intermediate_ca1.key -out ca/intermediate_ca1.csr -subj "/O=MariaDB/OU=MariaDB/CN=Intermediate CA1" + +openssl ca -batch -days 7200 -notext -md sha256 -in ca/intermediate_ca1.csr -out ca/intermediate_ca1.crt -keyfile ca/root.key -cert ca/root.crt -outdir ca/root.certs/ -config ca/root.cfg -extensions v3_ca_intermediate + +mkdir ca/intermediate_ca1.certs +touch ca/intermediate_ca1.index.txt +touch ca/intermediate_ca1.index.txt.attr +echo '01' > ca/intermediate_ca1.serial + +cat > ca/intermediate_ca1.cfg << EOF +[ ca ] +default_ca = CA_default +[ CA_default ] +dir = $PWD/ca +certs = \$dir/intermediate_ca1.certs +database = \$dir/intermediate_ca1.index.txt +serial = \$dir/intermediate_ca1.serial +policy= policy_match +[ policy_match ] +commonName = supplied +[ alt_names ] +DNS.1 = localhost +IP.1 = 127.0.0.1 +[ server_cert ] +basicConstraints = CA:FALSE +keyUsage = critical,digitalSignature,keyEncipherment +extendedKeyUsage = serverAuth +subjectAltName = @alt_names +EOF + +# Generate Server key and cert +openssl genrsa -out server/server.key 4096 +openssl req -new '-sha256' -key server/server.key -out server/server.csr -subj "/CN=localhost" + +openssl ca -batch -days 7200 -notext -md sha256 -in server/server.csr -out server/server.crt -keyfile ca/intermediate_ca1.key -cert ca/intermediate_ca1.crt -outdir ca/intermediate_ca1.certs/ -config ca/intermediate_ca1.cfg -extensions server_cert + +# Generate Intermediate CA2 key and cert +openssl genrsa -out ca/intermediate_ca2.key 4096 + +openssl req -new '-sha256' -key ca/intermediate_ca2.key -out ca/intermediate_ca2.csr -subj "/O=MariaDB/OU=MariaDB/CN=Intermediate CA2" +openssl ca -batch -days 7200 -notext -md sha256 -in ca/intermediate_ca2.csr -out ca/intermediate_ca2.crt -keyfile ca/root.key -cert ca/root.crt -outdir ca/root.certs/ -config ca/root.cfg -extensions v3_ca_intermediate + +mkdir ca/intermediate_ca2.certs +touch ca/intermediate_ca2.index.txt +touch ca/intermediate_ca2.index.txt.attr +echo '01' > ca/intermediate_ca2.serial + +cat > ca/intermediate_ca2.cfg << EOF +[ ca ] +default_ca = CA_default +[ CA_default ] +dir = $PWD/ca +certs = \$dir/intermediate_ca2.certs +database = \$dir/intermediate_ca2.index.txt +serial = \$dir/intermediate_ca2.serial +policy= policy_match +[ policy_match ] +commonName = supplied +[ client_cert ] +basicConstraints = CA:FALSE +keyUsage = critical,digitalSignature,keyEncipherment +extendedKeyUsage = clientAuth +EOF + +# Generate Client key and cert +openssl genrsa -out clients/client.key 4096 +openssl req -new '-sha256' -key clients/client.key -out clients/client.csr -subj "/CN=client" + +openssl ca -batch -days 7200 -notext -md sha256 -in clients/client.csr -out clients/client.crt -keyfile ca/intermediate_ca2.key -cert ca/intermediate_ca2.crt -outdir ca/intermediate_ca2.certs/ -config ca/intermediate_ca2.cfg -extensions client_cert + +cat server/server.crt ca/intermediate_ca1.crt > server/server.cachain + +cat clients/client.crt ca/intermediate_ca2.crt > clients/client.cachain + +cat ca/root.crt ca/intermediate_ca1.crt > ca/root_intermediate_ca1.crt + +# Generate Unrelated Root CA key and cert +openssl genrsa -out ca/unrelated_root.key 4096 +openssl req -new -x509 '-sha256' -key ca/unrelated_root.key -out ca/unrelated_root.crt -days 7200 -subj "/O=MariaDB/OU=MariaDB/CN=Root CA" -config ca/root.cfg -extensions v3_ca + +cp -v ca/root.crt ca/root_intermediate_ca1.crt ca/unrelated_root.crt server/server.key server/server.cachain clients/client.key clients/client.cachain ./ +rm -rf ca server clients + +cd .. diff --git a/mysql-test/lib/v1/mtr_cases.pl b/mysql-test/lib/v1/mtr_cases.pl index 968f13bcc6102..4cf8c2b48239a 100644 --- a/mysql-test/lib/v1/mtr_cases.pl +++ b/mysql-test/lib/v1/mtr_cases.pl @@ -863,6 +863,7 @@ ($$$$$$$$$) "binlog_formats", ["row", "statement"]], ["include/have_innodb.inc", "innodb_test", 1], + ["include/have_innodb_binlog.inc", "innodb_test", 1], ["include/have_log_bin.inc", "need_binlog", 1], ["include/big_test.inc", "big_test", 1], ["include/have_debug.inc", "need_debug", 1], diff --git a/mysql-test/main/aborted_clients.test b/mysql-test/main/aborted_clients.test index 200bac031336e..74651dbd7b9d1 100644 --- a/mysql-test/main/aborted_clients.test +++ b/mysql-test/main/aborted_clients.test @@ -2,15 +2,13 @@ # Check that ordinary connect/disconnect does not increase aborted_clients # status variable, but KILL connection does --- source include/not_embedded.inc --- source include/count_sessions.inc +--source include/not_embedded.inc FLUSH GLOBAL STATUS; # Connect/Disconnect look that aborted_clients stays 0 connect (con1,localhost,root,,); disconnect con1; connection default; --- source include/wait_until_count_sessions.inc # Check that there is 0 aborted clients so far SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='aborted_clients'; @@ -21,7 +19,6 @@ connect(con2,localhost,root,,); KILL CONNECTION_ID(); disconnect con2; connection default; --- source include/wait_until_count_sessions.inc # aborted clients must be 1 now SELECT VARIABLE_VALUE FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME='aborted_clients'; diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 7c97739eeadce..056cee0534b15 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -1539,13 +1539,13 @@ t2 CREATE TABLE `t2` ( KEY `fk` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ALTER TABLE t2 ADD FOREIGN KEY (id) REFERENCES t1(id); -ALTER TABLE t2 ADD FOREIGN KEY IF NOT EXISTS t2_ibfk_1(id) REFERENCES t1(id); +ALTER TABLE t2 ADD FOREIGN KEY IF NOT EXISTS `1`(id) REFERENCES t1(id); Warnings: -Note 1061 Duplicate key name 't2_ibfk_1' -ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1; -ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1; +Note 1061 Duplicate key name '1' +ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS `1`; +ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS `1`; Warnings: -Note 1091 Can't DROP FOREIGN KEY `t2_ibfk_1`; check that it exists +Note 1091 Can't DROP FOREIGN KEY `1`; check that it exists SHOW CREATE TABLE t2; Table Create Table t2 CREATE TABLE `t2` ( @@ -1780,7 +1780,6 @@ DROP TABLE t1; # --enable_info allows us to see how many rows were updated # by ALTER TABLE. in-place will show 0 rows, while copy > 0. # -DROP TABLE IF EXISTS ti1, ti2, ti3, tm1, tm2, tm3; # Single operation tests CREATE TABLE ti1(a INT NOT NULL, b INT, c INT) engine=InnoDB; CREATE TABLE tm1(a INT NOT NULL, b INT, c INT) engine=MyISAM; @@ -3153,12 +3152,36 @@ DROP TABLE t; # End of 10.7 tests # # +# MDEV-37275 Cannot remove default value of NOT NULL column +# +create table t1 (d time default '00:00:00'); +alter table t1 alter column d drop default; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `d` time DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +create table t2 (d datetime not null default current_timestamp()); +alter table t2 alter column d drop default; +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `d` datetime NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +create table t3 (d datetime not null); +alter table t3 alter column d set default current_timestamp(); +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `d` datetime NOT NULL DEFAULT current_timestamp() +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +drop tables t1, t2, t3; +# End of 10.11 tests +# # MDEV-33655 Remove alter_algorithm # CREATE TABLE t1 (a INT) ENGINE=MyISAM; CREATE TABLE t2 (a INT) ENGINE=MERGE, UNION(t1); ALTER TABLE t2 COMMENT 'x', LOCK=SHARED; DROP TABLE t2,t1; -# # End of 11.5 tests -# diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index e9bc5f63cc98f..7b2b2c7f98379 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -1318,8 +1318,6 @@ SELECT LENGTH(my_t3_fld1) FROM t3; # Cleanup --disconnect con1 ---source include/wait_until_disconnected.inc - --connection default DROP TABLE t1, t2, t3; @@ -1384,9 +1382,9 @@ ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS fk; ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS fk; SHOW CREATE TABLE t2; ALTER TABLE t2 ADD FOREIGN KEY (id) REFERENCES t1(id); -ALTER TABLE t2 ADD FOREIGN KEY IF NOT EXISTS t2_ibfk_1(id) REFERENCES t1(id); -ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1; -ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS t2_ibfk_1; +ALTER TABLE t2 ADD FOREIGN KEY IF NOT EXISTS `1`(id) REFERENCES t1(id); +ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS `1`; +ALTER TABLE t2 DROP FOREIGN KEY IF EXISTS `1`; SHOW CREATE TABLE t2; DROP TABLE t2; @@ -1569,8 +1567,6 @@ connection con1; --echo # Reaping: ALTER TABLE t1 DISABLE KEYS --reap disconnect con1; ---source include/wait_until_disconnected.inc - connection default; DROP TABLE t1; @@ -1584,10 +1580,6 @@ DROP TABLE t1; --echo # by ALTER TABLE. in-place will show 0 rows, while copy > 0. --echo # ---disable_warnings -DROP TABLE IF EXISTS ti1, ti2, ti3, tm1, tm2, tm3; ---enable_warnings - --echo # Single operation tests CREATE TABLE ti1(a INT NOT NULL, b INT, c INT) engine=InnoDB; @@ -2449,6 +2441,25 @@ DROP TABLE t; --echo # End of 10.7 tests --echo # +--echo # +--echo # MDEV-37275 Cannot remove default value of NOT NULL column +--echo # +create table t1 (d time default '00:00:00'); +alter table t1 alter column d drop default; +show create table t1; + +create table t2 (d datetime not null default current_timestamp()); +alter table t2 alter column d drop default; +show create table t2; + +create table t3 (d datetime not null); +alter table t3 alter column d set default current_timestamp(); +show create table t3; + +drop tables t1, t2, t3; + +--echo # End of 10.11 tests + --echo # --echo # MDEV-33655 Remove alter_algorithm --echo # @@ -2458,6 +2469,4 @@ CREATE TABLE t2 (a INT) ENGINE=MERGE, UNION(t1); ALTER TABLE t2 COMMENT 'x', LOCK=SHARED; DROP TABLE t2,t1; ---echo # --echo # End of 11.5 tests ---echo # diff --git a/mysql-test/main/alter_table_combinations,aria.rdiff b/mysql-test/main/alter_table_combinations,aria.rdiff index 6564dbb44a629..f5f05cf954332 100644 --- a/mysql-test/main/alter_table_combinations,aria.rdiff +++ b/mysql-test/main/alter_table_combinations,aria.rdiff @@ -5,7 +5,7 @@ `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, - KEY `b` (`b`), -- CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`bb`) +- CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `t1` (`bb`) + KEY `b` (`b`) ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ALTER TABLE t1 RENAME COLUMN bb TO b; @@ -15,7 +15,7 @@ `a` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, - KEY `b` (`c`), -- CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`c`) REFERENCES `t1` (`b`) +- CONSTRAINT `1` FOREIGN KEY (`c`) REFERENCES `t1` (`b`) + KEY `b` (`c`) ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci CREATE TABLE t4(a int); diff --git a/mysql-test/main/alter_table_combinations,heap.rdiff b/mysql-test/main/alter_table_combinations,heap.rdiff index 81633a8255ff6..c9c7907f7d6d7 100644 --- a/mysql-test/main/alter_table_combinations,heap.rdiff +++ b/mysql-test/main/alter_table_combinations,heap.rdiff @@ -14,7 +14,7 @@ `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, - KEY `b` (`b`), -- CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`bb`) +- CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `t1` (`bb`) + KEY `b` (`b`) ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ALTER TABLE t1 RENAME COLUMN bb TO b; @@ -24,7 +24,7 @@ `a` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, - KEY `b` (`c`), -- CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`c`) REFERENCES `t1` (`b`) +- CONSTRAINT `1` FOREIGN KEY (`c`) REFERENCES `t1` (`b`) + KEY `b` (`c`) ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci CREATE TABLE t4(a int); diff --git a/mysql-test/main/alter_table_combinations.result b/mysql-test/main/alter_table_combinations.result index 1e8d1ee599b67..d14aaaac8f73d 100644 --- a/mysql-test/main/alter_table_combinations.result +++ b/mysql-test/main/alter_table_combinations.result @@ -174,7 +174,7 @@ t3 CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL, `b` int(11) DEFAULT NULL, KEY `b` (`b`), - CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`b`) REFERENCES `t1` (`bb`) + CONSTRAINT `1` FOREIGN KEY (`b`) REFERENCES `t1` (`bb`) ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci ALTER TABLE t1 RENAME COLUMN bb TO b; SHOW CREATE TABLE t1; @@ -191,7 +191,7 @@ t3 CREATE TABLE `t3` ( `a` int(11) DEFAULT NULL, `c` int(11) DEFAULT NULL, KEY `b` (`c`), - CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`c`) REFERENCES `t1` (`b`) + CONSTRAINT `1` FOREIGN KEY (`c`) REFERENCES `t1` (`b`) ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci CREATE TABLE t4(a int); ALTER TABLE t4 RENAME COLUMN a TO aa, ALGORITHM = INPLACE; diff --git a/mysql-test/main/alter_table_lock.result b/mysql-test/main/alter_table_lock.result index 170a7c47e6b67..c42a621faf1b0 100644 --- a/mysql-test/main/alter_table_lock.result +++ b/mysql-test/main/alter_table_lock.result @@ -1,23 +1,4 @@ # -# MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in -# Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) -# -SET @max_session_mem_used_save= @@max_session_mem_used; -CREATE TABLE t1 (a INT); -SELECT * FROM t1; -a -ALTER TABLE x MODIFY xx INT; -ERROR 42S02: Table 'test.x' doesn't exist -SET SESSION max_session_mem_used= 8192; -LOCK TABLE t1 WRITE; -ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT; -SET SESSION max_session_mem_used = @max_session_mem_used_save; -UNLOCK TABLES; -DROP TABLE t1; -# -# End of 10.5 tests -# -# # MDEV-28943 Online alter fails under LOCK TABLE with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON # create table t1 (f int) engine=innodb; @@ -58,9 +39,6 @@ alter online table t1 add column s blob not null, algorithm=inplace; ERROR 0A000: LOCK=NONE is not supported. Reason: Fulltext index creation requires a lock. Try LOCK=SHARED drop table t1; # -# End of 10.11 tests -# -# # MDEV-35611 Assertion failure in Diagnostics_area::sql_errno upon interrupted ALTER # CREATE TABLE t (a INT) ENGINE=MyISAM; @@ -69,13 +47,11 @@ LOCK TABLE t READ; connection con1; SET max_statement_time=0.001; ALTER TABLE t FORCE; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.001 sec exceeded ALTER TABLE IF EXISTS t FORCE; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.001 sec exceeded disconnect con1; connection default; UNLOCK TABLES; DROP TABLE t; -# # End of 11.4 tests -# diff --git a/mysql-test/main/alter_table_lock.test b/mysql-test/main/alter_table_lock.test index a01bd721e04d3..aaf40243a1bbb 100644 --- a/mysql-test/main/alter_table_lock.test +++ b/mysql-test/main/alter_table_lock.test @@ -1,36 +1,6 @@ --source include/not_embedded.inc --source include/have_innodb.inc ---echo # ---echo # MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in ---echo # Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) ---echo # - -SET @max_session_mem_used_save= @@max_session_mem_used; - -CREATE TABLE t1 (a INT); -SELECT * FROM t1; - ---error ER_NO_SUCH_TABLE -ALTER TABLE x MODIFY xx INT; - -SET SESSION max_session_mem_used= 8192; ---error 0,ER_OPTION_PREVENTS_STATEMENT -LOCK TABLE t1 WRITE; - ---disable_warnings ---error 0,ER_OPTION_PREVENTS_STATEMENT -ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT; ---enable_warnings - -SET SESSION max_session_mem_used = @max_session_mem_used_save; -UNLOCK TABLES; -DROP TABLE t1; - ---echo # ---echo # End of 10.5 tests ---echo # - --echo # --echo # MDEV-28943 Online alter fails under LOCK TABLE with ER_ALTER_OPERATION_NOT_SUPPORTED_REASON --echo # @@ -75,10 +45,6 @@ lock table t1 write; alter online table t1 add column s blob not null, algorithm=inplace; drop table t1; ---echo # ---echo # End of 10.11 tests ---echo # - --echo # --echo # MDEV-35611 Assertion failure in Diagnostics_area::sql_errno upon interrupted ALTER --echo # @@ -97,6 +63,4 @@ ALTER TABLE IF EXISTS t FORCE; UNLOCK TABLES; DROP TABLE t; ---echo # --echo # End of 11.4 tests ---echo # diff --git a/mysql-test/main/alter_table_online_debug.result b/mysql-test/main/alter_table_online_debug.result index 1148e178428df..537556e2e2db9 100644 --- a/mysql-test/main/alter_table_online_debug.result +++ b/mysql-test/main/alter_table_online_debug.result @@ -414,23 +414,23 @@ set debug_sync= 'now SIGNAL start_replication'; set debug_sync= 'now WAIT_FOR applied'; select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; stage progress examined_rows -3 53.390 0 +3 53.488 0 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; stage progress examined_rows -3 63.559 1 +3 63.636 1 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; stage progress examined_rows -3 71.610 2 +3 71.670 2 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; stage progress examined_rows -3 81.780 3 +3 81.818 3 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; stage progress examined_rows -3 89.831 4 +3 89.852 4 set debug_sync= 'now SIGNAL proceed WAIT_FOR applied'; select stage, progress, examined_rows from INFORMATION_SCHEMA.PROCESSLIST where id = @con; stage progress examined_rows diff --git a/mysql-test/main/alter_user.result b/mysql-test/main/alter_user.result index 19e427e8f10fa..16147a6c7d237 100644 --- a/mysql-test/main/alter_user.result +++ b/mysql-test/main/alter_user.result @@ -34,12 +34,14 @@ select @@global.read_only; ON alter user foo; ERROR HY000: The MariaDB server is running with the --read-only=ON option so it cannot execute this statement +disconnect a; # Grant READ_ONLY ADMIN privilege to the user. connection default; grant READ_ONLY ADMIN on *.* to foo; # We now have READ_ONLY ADMIN privilege. We should be able to run alter user. connect b, localhost, foo; alter user foo; +disconnect b; connection default; SET GLOBAL read_only = @start_read_only; # diff --git a/mysql-test/main/alter_user.test b/mysql-test/main/alter_user.test index 6f4f9fb1e1eff..f00016e98c4c5 100644 --- a/mysql-test/main/alter_user.test +++ b/mysql-test/main/alter_user.test @@ -32,6 +32,7 @@ select @@global.read_only; --error ER_OPTION_PREVENTS_STATEMENT alter user foo; +disconnect a; --echo # Grant READ_ONLY ADMIN privilege to the user. connection default; @@ -40,6 +41,7 @@ grant READ_ONLY ADMIN on *.* to foo; --echo # We now have READ_ONLY ADMIN privilege. We should be able to run alter user. connect (b, localhost, foo); alter user foo; +disconnect b; connection default; SET GLOBAL read_only = @start_read_only; diff --git a/mysql-test/main/analyze.result b/mysql-test/main/analyze.result index 4af950ddc0048..43da87403a172 100644 --- a/mysql-test/main/analyze.result +++ b/mysql-test/main/analyze.result @@ -364,7 +364,7 @@ t1 CREATE TABLE `t1` ( `b` int(11) DEFAULT NULL, KEY `b` (`b`), KEY `idx` (`aaaa`), - CONSTRAINT `t1_ibfk_1` FOREIGN KEY (`aaaa`) REFERENCES `t1` (`b`) + CONSTRAINT `1` FOREIGN KEY (`aaaa`) REFERENCES `t1` (`b`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci SELECT index_name FROM mysql.index_stats WHERE table_name = 't1' order by index_name; index_name diff --git a/mysql-test/main/analyze_engine_stats.result b/mysql-test/main/analyze_engine_stats.result index d68324a4bb527..8c0a0952509e3 100644 --- a/mysql-test/main/analyze_engine_stats.result +++ b/mysql-test/main/analyze_engine_stats.result @@ -72,7 +72,8 @@ X "rows": 10000, "r_rows": 10000, "r_total_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": { "pages_accessed": "REPLACED", "pages_updated": "REPLACED" @@ -106,7 +107,8 @@ X "rows": 10000, "r_rows": 10000, "r_total_filtered": 50, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": { "pages_accessed": "REPLACED", "pages_updated": "REPLACED" diff --git a/mysql-test/main/analyze_format_json.result b/mysql-test/main/analyze_format_json.result index 5797ef435ad30..0889f2ac82903 100644 --- a/mysql-test/main/analyze_format_json.result +++ b/mysql-test/main/analyze_format_json.result @@ -431,7 +431,8 @@ ANALYZE "rows": 1000, "r_rows": 1000, "r_total_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "r_filtered": 100 } @@ -499,7 +500,8 @@ ANALYZE "rows": 10, "r_rows": 10, "r_total_filtered": 50, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t1.pk < 10 and t1.b > 4", "r_filtered": 50 @@ -1765,3 +1767,125 @@ ANALYZE } } drop table t12,t13; +# +# MDEV-33309: ANALYZE FORMAT=JSON: UPDATE|DELETE don't show r_other_time_ms +# +create table t1 (pk int primary key, a int); +insert into t1 select seq, seq from seq_1_to_1000; +create table t2 like t1; +insert into t2 select * from t1; +# Top-level query block must have r_table_time_ms and r_other_time_ms +analyze format=json +update t1 set a=a+1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; +ANALYZE +{ + "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": 1000, + "r_rows": 1000, + "r_total_filtered": 100, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "attached_condition": "t1.pk > (subquery#2) - 10", + "r_filtered": 100 + }, + "subqueries": [ + { + "query_block": { + "select_id": 2, + "cost": "REPLACED", + "r_loops": 1000, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "r_loops": 1000, + "rows": 1000, + "r_rows": 1000, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_total_filtered": 0.1, + "attached_condition": "t2.pk + 1 = t1.pk + 1", + "r_filtered": 0.1 + } + } + ] + } + } + ] + } +} +# Top-level query block must have r_table_time_ms and r_other_time_ms +analyze format=json +delete from t1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; +ANALYZE +{ + "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": 1000, + "r_rows": 1000, + "r_total_filtered": 100, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "attached_condition": "t1.pk > (subquery#2) - 10", + "r_filtered": 100 + }, + "subqueries": [ + { + "query_block": { + "select_id": 2, + "cost": "REPLACED", + "r_loops": 1000, + "r_total_time_ms": "REPLACED", + "nested_loop": [ + { + "table": { + "table_name": "t2", + "access_type": "ALL", + "loops": 1, + "r_loops": 1000, + "rows": 1000, + "r_rows": 1000, + "cost": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_total_filtered": 0.1, + "attached_condition": "t2.pk + 1 = t1.pk + 1", + "r_filtered": 0.1 + } + } + ] + } + } + ] + } +} +drop table t1, t2; diff --git a/mysql-test/main/analyze_format_json.test b/mysql-test/main/analyze_format_json.test index b4cb24b0335b5..4cc196e84c5a5 100644 --- a/mysql-test/main/analyze_format_json.test +++ b/mysql-test/main/analyze_format_json.test @@ -346,3 +346,26 @@ analyze format=json select * from t13,t12 where t13.b between 1 and 2 and t12.a= between 400 and 450 and t12.b like '%f%'; drop table t12,t13; + +--echo # +--echo # MDEV-33309: ANALYZE FORMAT=JSON: UPDATE|DELETE don't show r_other_time_ms +--echo # +--source include/have_sequence.inc +create table t1 (pk int primary key, a int); +insert into t1 select seq, seq from seq_1_to_1000; +create table t2 like t1; +insert into t2 select * from t1; + +--echo # Top-level query block must have r_table_time_ms and r_other_time_ms +--source include/analyze-format.inc +analyze format=json +update t1 set a=a+1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; + +--echo # Top-level query block must have r_table_time_ms and r_other_time_ms +--source include/analyze-format.inc +analyze format=json +delete from t1 +where t1.pk > (select max(a) from t2 where t2.pk+1 = t1.pk+1 ) - 10; + +drop table t1, t2; diff --git a/mysql-test/main/analyze_stmt_orderby.result b/mysql-test/main/analyze_stmt_orderby.result index 6db47ec187b17..cf9dc40964845 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_total_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "r_filtered": 100 } @@ -112,7 +113,8 @@ ANALYZE "rows": 9, "r_rows": 10, "r_total_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t2.a < 10", "r_filtered": 100 @@ -167,7 +169,8 @@ ANALYZE "rows": 10000, "r_rows": 10000, "r_total_filtered": 100, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "r_filtered": 100 } diff --git a/mysql-test/main/analyze_stmt_prefetch_count.result b/mysql-test/main/analyze_stmt_prefetch_count.result index f5a5c9bda96d3..d55b416c32a85 100644 --- a/mysql-test/main/analyze_stmt_prefetch_count.result +++ b/mysql-test/main/analyze_stmt_prefetch_count.result @@ -33,9 +33,16 @@ select @pages_accessed > 1000 and @pages_accessed < 1500; @pages_accessed > 1000 and @pages_accessed < 1500 1 set @total_read = (@pages_read_count + @pages_prefetch_read_count); -select @pages_accessed*0.75 < @total_read, @total_read < @pages_accessed*1.25; -@pages_accessed*0.75 < @total_read @total_read < @pages_accessed*1.25 +set @low_ok= @pages_accessed*0.75 < @total_read; +set @high_ok= @total_read < @pages_accessed*1.50; +select @low_ok, @high_ok; +@low_ok @high_ok 1 1 +select +if(@low_ok and @high_ok,0,@pages_accessed) unexpected_accessed, +if(@low_ok and @high_ok,0,@total_read) unexpected_read; +unexpected_accessed unexpected_read +0 0 set @innodb_pages_read1= (select variable_value from information_schema.session_status diff --git a/mysql-test/main/analyze_stmt_prefetch_count.test b/mysql-test/main/analyze_stmt_prefetch_count.test index b5c6aac67b591..3e52830a0d06f 100644 --- a/mysql-test/main/analyze_stmt_prefetch_count.test +++ b/mysql-test/main/analyze_stmt_prefetch_count.test @@ -48,8 +48,13 @@ set @pages_prefetch_read_count= cast(json_value(@js,'$.pages_prefetch_read_count select @pages_accessed > 1000 and @pages_accessed < 1500; set @total_read = (@pages_read_count + @pages_prefetch_read_count); +set @low_ok= @pages_accessed*0.75 < @total_read; +set @high_ok= @total_read < @pages_accessed*1.50; -select @pages_accessed*0.75 < @total_read, @total_read < @pages_accessed*1.25; +select @low_ok, @high_ok; +select +if(@low_ok and @high_ok,0,@pages_accessed) unexpected_accessed, +if(@low_ok and @high_ok,0,@total_read) unexpected_read; set @innodb_pages_read1= (select variable_value diff --git a/mysql-test/main/analyze_stmt_privileges2.test b/mysql-test/main/analyze_stmt_privileges2.test index 8b011c2b5924a..133572479b236 100644 --- a/mysql-test/main/analyze_stmt_privileges2.test +++ b/mysql-test/main/analyze_stmt_privileges2.test @@ -21,9 +21,6 @@ --source include/not_embedded.inc --source include/default_optimizer_switch.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - set GLOBAL sql_mode=""; set LOCAL sql_mode=""; @@ -5392,8 +5389,4 @@ connection default; DROP USER 'privtest'@localhost; USE test; DROP DATABASE privtest_db; - set GLOBAL sql_mode=default; ---source include/wait_until_count_sessions.inc - - diff --git a/mysql-test/main/aria_icp_debug.result b/mysql-test/main/aria_icp_debug.result index fc01ee4fb3bb9..d9427a93798a2 100644 --- a/mysql-test/main/aria_icp_debug.result +++ b/mysql-test/main/aria_icp_debug.result @@ -1,5 +1,4 @@ set default_storage_engine=aria; -drop table if exists t0,t1,t2; create table t0(a int primary key); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1(a int primary key); diff --git a/mysql-test/main/auth_rpl.test b/mysql-test/main/auth_rpl.test index 9b2c4357cf09f..bfabc83aba56c 100644 --- a/mysql-test/main/auth_rpl.test +++ b/mysql-test/main/auth_rpl.test @@ -57,7 +57,9 @@ DROP USER 'plug_user'; --echo # Cleanup (on master). --connection master +--disable_warnings DROP USER 'plug_user'; +--enable_warnings --let $rpl_only_running_threads= 1 --source include/rpl_end.inc diff --git a/mysql-test/main/backup_lock.result b/mysql-test/main/backup_lock.result index 6e2ccad5091ea..0103a0fc92626 100644 --- a/mysql-test/main/backup_lock.result +++ b/mysql-test/main/backup_lock.result @@ -55,7 +55,7 @@ MDL_SHARED_WRITE Table metadata lock test t1 MDL_SHARED_UPGRADABLE Table metadata lock test t1 MDL_INTENTION_EXCLUSIVE Schema metadata lock test SET STATEMENT max_statement_time=1 FOR backup stage block_ddl; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 1.0 sec exceeded backup stage block_ddl; connection default; commit; diff --git a/mysql-test/main/backup_locks.result b/mysql-test/main/backup_locks.result index 4d5de53c1fbf3..0d4f24cfb611c 100644 --- a/mysql-test/main/backup_locks.result +++ b/mysql-test/main/backup_locks.result @@ -51,13 +51,13 @@ connection con1; CREATE OR REPLACE SEQUENCE seq1 START -28; ERROR HY000: Sequence 'test.seq1' has out of range value for options SET STATEMENT max_statement_time=10 FOR CREATE OR REPLACE SEQUENCE seq1 START 50; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 NOMAXVALUE; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded SET STATEMENT max_statement_time=10 FOR ALTER SEQUENCE IF EXISTS seq1 MAXVALUE 1000; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded SET STATEMENT max_statement_time=10 for rename table seq2 to seq3, seq3 to seq1; -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 10.0 sec exceeded connection default; backup unlock; drop table seq1,seq2; diff --git a/mysql-test/main/backup_locks.test b/mysql-test/main/backup_locks.test index 6a1fe9f609406..c2618cbbadbde 100644 --- a/mysql-test/main/backup_locks.test +++ b/mysql-test/main/backup_locks.test @@ -5,6 +5,7 @@ --source include/long_test.inc --source include/have_innodb.inc --source include/have_metadata_lock_info.inc +--source include/have_profiling.inc --source include/not_embedded.inc --source include/no_view_protocol.inc diff --git a/mysql-test/main/backup_priv.result b/mysql-test/main/backup_priv.result index 4169f58f40fa0..cd7f2c1dd3239 100644 --- a/mysql-test/main/backup_priv.result +++ b/mysql-test/main/backup_priv.result @@ -13,6 +13,7 @@ BACKUP STAGE FLUSH; SELECT lock_mode FROM information_schema.metadata_lock_info WHERE lock_type='Backup lock'; lock_mode MDL_BACKUP_FLUSH +change_user user2,,; SELECT lock_mode FROM information_schema.metadata_lock_info WHERE lock_type='Backup lock'; lock_mode disconnect con1; diff --git a/mysql-test/main/backup_priv.test b/mysql-test/main/backup_priv.test index c77075c239356..a446e85b31f84 100644 --- a/mysql-test/main/backup_priv.test +++ b/mysql-test/main/backup_priv.test @@ -22,7 +22,6 @@ SELECT lock_mode FROM information_schema.metadata_lock_info WHERE lock_type='Bac change_user user2; SELECT lock_mode FROM information_schema.metadata_lock_info WHERE lock_type='Backup lock'; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default --echo # A very low privileged user (-> con4) cannot acquire the backup lock @@ -39,7 +38,6 @@ BACKUP STAGE BLOCK_COMMIT; --error ER_SPECIFIC_ACCESS_DENIED_ERROR BACKUP STAGE END; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default DROP USER user1@localhost, user2@localhost; diff --git a/mysql-test/main/backup_stages.test b/mysql-test/main/backup_stages.test index 1f5fb2d682823..d1d30e2b04c84 100644 --- a/mysql-test/main/backup_stages.test +++ b/mysql-test/main/backup_stages.test @@ -6,11 +6,9 @@ # A transactional engine --source include/have_innodb.inc --source include/have_metadata_lock_info.inc +--source include/no_view_protocol.inc # As non transactional engine we have MyISAM anyway. -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc - let $old_lock_wait_timeout = `SELECT @@global.lock_wait_timeout`; --echo #----------------------------------------------------------------------- @@ -384,4 +382,3 @@ SET GLOBAL lock_wait_timeout = $old_lock_wait_timeout; --disconnect backup --connection default ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/binary_to_hex.result b/mysql-test/main/binary_to_hex.result index 3918021f3e65a..c24f91eef63a1 100644 --- a/mysql-test/main/binary_to_hex.result +++ b/mysql-test/main/binary_to_hex.result @@ -1,5 +1,3 @@ -USE test; -DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (c1 TINYBLOB, c2 BLOB, c3 MEDIUMBLOB, diff --git a/mysql-test/main/binary_to_hex.test b/mysql-test/main/binary_to_hex.test index be4fb301e4033..bd7397313fbe8 100644 --- a/mysql-test/main/binary_to_hex.test +++ b/mysql-test/main/binary_to_hex.test @@ -8,15 +8,8 @@ # CLIENT (CONTRIBUTION) # -# Save the initial number of concurrent sessions ---source include/count_sessions.inc --source include/not_embedded.inc -USE test; ---disable_warnings -DROP TABLE IF EXISTS t1, t2; ---enable_warnings - CREATE TABLE t1 (c1 TINYBLOB, c2 BLOB, c3 MEDIUMBLOB, @@ -91,6 +84,3 @@ remove_file $MYSQLTEST_VARDIR/tmp/mdev-14593.sql; #Cleanup DROP TABLE t1; - -# Wait till all disconnects are completed - --source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/bool_innodb.result b/mysql-test/main/bool_innodb.result new file mode 100644 index 0000000000000..c08bc52a1b779 --- /dev/null +++ b/mysql-test/main/bool_innodb.result @@ -0,0 +1,10 @@ +# +# MDEV-35288: Assertion `!is_cond()' failed in +# virtual longlong Item_bool_func::val_int() +# +CREATE TABLE t (a INT) ENGINE=INNODB; +SELECT SUM(a), ROWNUM() AS r FROM t HAVING r=1; +SUM(a) r +NULL 1 +DROP TABLE t; +# End of 10.5 tests diff --git a/mysql-test/main/bool_innodb.test b/mysql-test/main/bool_innodb.test new file mode 100644 index 0000000000000..744311990cfdc --- /dev/null +++ b/mysql-test/main/bool_innodb.test @@ -0,0 +1,15 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-35288: Assertion `!is_cond()' failed in +--echo # virtual longlong Item_bool_func::val_int() +--echo # + +CREATE TABLE t (a INT) ENGINE=INNODB; +SELECT SUM(a), ROWNUM() AS r FROM t HAVING r=1; + +# Cleanup +DROP TABLE t; + + +--echo # End of 10.5 tests diff --git a/mysql-test/main/bug39022.test b/mysql-test/main/bug39022.test index 81dd6f14bed1c..bceb7229cba0a 100644 --- a/mysql-test/main/bug39022.test +++ b/mysql-test/main/bug39022.test @@ -52,11 +52,9 @@ connection thread2; REAP; disconnect thread2; ---source include/wait_until_disconnected.inc connection thread1; disconnect thread1; ---source include/wait_until_disconnected.inc connection default; diff --git a/mysql-test/main/chained_ssl_certificates.opt b/mysql-test/main/chained_ssl_certificates.opt new file mode 100644 index 0000000000000..bb2f8e1d88341 --- /dev/null +++ b/mysql-test/main/chained_ssl_certificates.opt @@ -0,0 +1,3 @@ +--ssl-ca=$MYSQL_TEST_DIR/std_data/cachain/root.crt +--ssl-key=$MYSQL_TEST_DIR/std_data/cachain/server.key +--ssl-cert=$MYSQL_TEST_DIR/std_data/cachain/server.cachain diff --git a/mysql-test/main/chained_ssl_certificates.result b/mysql-test/main/chained_ssl_certificates.result new file mode 100644 index 0000000000000..08911b0c936cb --- /dev/null +++ b/mysql-test/main/chained_ssl_certificates.result @@ -0,0 +1,12 @@ +call mtr.add_suppression("Server SSL certificate doesn't verify"); +CREATE USER 'user1'@'%' REQUIRE SSL; +Variable_name Value +Ssl_version TLS + +Restart server and provide ssl-ca comprising intermediate_ca1 in addition to the root ca. +Variable_name Value +Ssl_version TLS + +Restart server and provide unrelated ssl-ca at server startup +ERROR 2026 (HY000): TLS/SSL error: +DROP USER 'user1'; diff --git a/mysql-test/main/chained_ssl_certificates.test b/mysql-test/main/chained_ssl_certificates.test new file mode 100644 index 0000000000000..9d315e9480796 --- /dev/null +++ b/mysql-test/main/chained_ssl_certificates.test @@ -0,0 +1,74 @@ +# These tests are inspired from the following commit from MySQL Server +# https://github.com/mysql/mysql-server/commit/969afef933f1872c5f38ea93047ef05c4509c335 + +# Credits to salman.s.khan@oracle.com + +##################################################################################### +# This test verifies MariaDB can handle chained ssl certificate +# This test uses chained ssl certificates which is depicted as +# below:- +# +# +---------+ +# | Root CA | +# +---------+ +# | +# /------------+-----------\ +# | | +# +------------------+ +------------------+ +# | Intermediate CA1 | | Intermediate CA2 | +# +------------------+ +------------------+ +# | | +# +-------------+ +-------------+ +# | Server | | Client | +# | certificate | | certificate | +# +-------------+ +-------------+ +# +# certificates that may be helpful for chain construction. +# In order to validate server cert correctly, we need to +# provide the trusted root certificate and the untrusted +# intermediate certificates as part of ssl-ca. Hence +# root_intermediate_ca1.crt (trusted root certificate + +# untrusted intermediate ca1 certificate) is passed as with +# --ssl-ca option + +--source include/not_embedded.inc +--source include/have_ssl_communication.inc + +#Suppress warning by the server certificate verification check: unrelated CA +call mtr.add_suppression("Server SSL certificate doesn't verify"); + +CREATE USER 'user1'@'%' REQUIRE SSL; + +--replace_result TLSv1.3 TLS TLSv1.2 TLS +--exec $MYSQL --host=localhost -P $MASTER_MYPORT --user=user1 --ssl-verify-server-cert --ssl-ca=$MYSQL_TEST_DIR/std_data/cachain/root.crt --ssl-cert=$MYSQL_TEST_DIR/std_data/cachain/client.cachain --ssl-key=$MYSQL_TEST_DIR/std_data/cachain/client.key -e "SHOW STATUS LIKE 'ssl_version'" + +--echo +--echo Restart server and provide ssl-ca comprising intermediate_ca1 in addition to the root ca. +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--write_line "restart:--ssl-ca=$MYSQL_TEST_DIR/std_data/cachain/root_intermediate_ca1.crt --ssl-key=$MYSQL_TEST_DIR/std_data/cachain/server.key --ssl-cert=$MYSQL_TEST_DIR/std_data/cachain/server.cachain" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--replace_result TLSv1.3 TLS TLSv1.2 TLS +--exec $MYSQL --host=localhost -P $MASTER_MYPORT --user=user1 --ssl-verify-server-cert --ssl-ca=$MYSQL_TEST_DIR/std_data/cachain/root.crt --ssl-cert=$MYSQL_TEST_DIR/std_data/cachain/client.cachain --ssl-key=$MYSQL_TEST_DIR/std_data/cachain/client.key -e "SHOW STATUS LIKE 'ssl_version'" + +--echo +--echo Restart server and provide unrelated ssl-ca at server startup +--write_line wait $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--write_line "restart:--ssl-ca=$MYSQL_TEST_DIR/std_data/cachain/unrelated_root.crt --ssl-key=$MYSQL_TEST_DIR/std_data/cachain/server.key --ssl-cert=$MYSQL_TEST_DIR/std_data/cachain/server.cachain" $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +--replace_regex /(ERROR 2026 \(HY000\): TLS\/SSL error:).*/\1/ +--error 1 +--exec $MYSQL --host=localhost -P $MASTER_MYPORT --user=user1 --ssl-verify-server-cert --ssl-ca=$MYSQL_TEST_DIR/std_data/cachain/unrelated_root.crt --ssl-cert=$MYSQL_TEST_DIR/std_data/cachain/client.cachain --ssl-key=$MYSQL_TEST_DIR/std_data/cachain/client.key -e "SHOW STATUS LIKE 'ssl_version'" 2>&1 +--echo + +# Cleanup +DROP USER 'user1'; diff --git a/mysql-test/main/change_master_default.result b/mysql-test/main/change_master_default.result new file mode 100644 index 0000000000000..9178c395339fb --- /dev/null +++ b/mysql-test/main/change_master_default.result @@ -0,0 +1,266 @@ +# Start of main.change_master_default +CREATE PROCEDURE show_defaultable_fields() +SELECT connection_name, +connect_retry, +master_ssl_allowed, +master_ssl_ca_file, +master_ssl_ca_path, +master_ssl_cert, +master_ssl_cipher, +master_ssl_key, +master_ssl_verify_server_cert, +master_ssl_crl, +master_ssl_crlpath, +using_gtid, +master_retry_count, +slave_heartbeat_period +FROM information_schema.slave_status ORDER BY connection_name; +CHANGE MASTER 'unset' TO master_host='127.0.1.1'; +CHANGE MASTER 'defaulted' TO +master_connect_retry= DEFAULT, +master_ssl= DEFAULT, +master_ssl_ca= DEFAULT, +master_ssl_capath= DEFAULT, +master_ssl_cert= DEFAULT, +master_ssl_cipher= DEFAULT, +master_ssl_key= DEFAULT, +master_ssl_verify_server_cert= DEFAULT, +master_ssl_crl= DEFAULT, +master_ssl_crlpath= DEFAULT, +master_use_gtid= DEFAULT, +master_retry_count= DEFAULT, +master_heartbeat_period= DEFAULT, +master_host= '127.0.1.2'; +CHANGE MASTER TO # Default master does not replace named masters +master_connect_retry= 90, +master_ssl= FALSE, +master_ssl_ca= 'specified_ca', +master_ssl_capath= 'specified_capath', +master_ssl_cert= 'specified_cert', +master_ssl_cipher= 'specified_cipher', +master_ssl_key= 'specified_key', +master_ssl_verify_server_cert= FALSE, +master_ssl_crl= 'specified_crl', +master_ssl_crlpath= 'specified_crlpath', +master_use_gtid= NO, +master_retry_count= 150000, +master_heartbeat_period= 45, +master_host='127.0.0.1'; +CALL show_defaultable_fields(); +connection_name +connect_retry 90 +master_ssl_allowed No +master_ssl_ca_file specified_ca +master_ssl_ca_path specified_capath +master_ssl_cert specified_cert +master_ssl_cipher specified_cipher +master_ssl_key specified_key +master_ssl_verify_server_cert No +master_ssl_crl specified_crl +master_ssl_crlpath specified_crlpath +using_gtid No +master_retry_count 150000 +slave_heartbeat_period 45.000 +connection_name defaulted +connect_retry 60 +master_ssl_allowed Yes +master_ssl_ca_file +master_ssl_ca_path +master_ssl_cert +master_ssl_cipher +master_ssl_key +master_ssl_verify_server_cert Yes +master_ssl_crl +master_ssl_crlpath +using_gtid Slave_Pos +master_retry_count 100000 +slave_heartbeat_period 60.000 +connection_name unset +connect_retry 60 +master_ssl_allowed Yes +master_ssl_ca_file +master_ssl_ca_path +master_ssl_cert +master_ssl_cipher +master_ssl_key +master_ssl_verify_server_cert Yes +master_ssl_crl +master_ssl_crlpath +using_gtid Slave_Pos +master_retry_count 100000 +slave_heartbeat_period 60.000 +# Those set or left as `DEFAULT` should pick up changes to defaults. +# restart: --skip-slave-start --master-connect-retry=30 --skip-master-ssl --master-ssl-ca=default_ca --master-ssl-capath=default_capath --master-ssl-cert=default_cert --master-ssl-cipher=default_cipher --master-ssl-key=default_key --skip-master-ssl-verify-server-cert --master-ssl-crl=default_crl --master-ssl-crlpath=default_crlpath --master-use-gtid=CURRENT_POS --master-retry-count=50000 --master-heartbeat-period=15 +CALL show_defaultable_fields(); +connection_name +connect_retry 90 +master_ssl_allowed No +master_ssl_ca_file specified_ca +master_ssl_ca_path specified_capath +master_ssl_cert specified_cert +master_ssl_cipher specified_cipher +master_ssl_key specified_key +master_ssl_verify_server_cert No +master_ssl_crl specified_crl +master_ssl_crlpath specified_crlpath +using_gtid No +master_retry_count 150000 +slave_heartbeat_period 45.000 +connection_name defaulted +connect_retry 30 +master_ssl_allowed No +master_ssl_ca_file default_ca +master_ssl_ca_path default_capath +master_ssl_cert default_cert +master_ssl_cipher default_cipher +master_ssl_key default_key +master_ssl_verify_server_cert No +master_ssl_crl default_crl +master_ssl_crlpath default_crlpath +using_gtid Current_Pos +master_retry_count 50000 +slave_heartbeat_period 15.000 +connection_name unset +connect_retry 30 +master_ssl_allowed No +master_ssl_ca_file default_ca +master_ssl_ca_path default_capath +master_ssl_cert default_cert +master_ssl_cipher default_cipher +master_ssl_key default_key +master_ssl_verify_server_cert No +master_ssl_crl default_crl +master_ssl_crlpath default_crlpath +using_gtid Current_Pos +master_retry_count 50000 +slave_heartbeat_period 15.000 +SET @@GLOBAL.slave_net_timeout= 100; +SELECT connection_name, slave_heartbeat_period +FROM information_schema.slave_status ORDER BY connection_name; +connection_name slave_heartbeat_period + 45.000 +defaulted 15.000 +unset 15.000 +CHANGE MASTER TO +master_connect_retry= DEFAULT, +master_ssl= DEFAULT, +master_ssl_ca= DEFAULT, +master_ssl_capath= DEFAULT, +master_ssl_cert= DEFAULT, +master_ssl_cipher= DEFAULT, +master_ssl_key= DEFAULT, +master_ssl_verify_server_cert= DEFAULT, +master_ssl_crl= DEFAULT, +master_ssl_crlpath= DEFAULT, +master_use_gtid= DEFAULT, +master_retry_count= DEFAULT, +master_heartbeat_period= DEFAULT; +CALL show_defaultable_fields(); +connection_name +connect_retry 30 +master_ssl_allowed No +master_ssl_ca_file default_ca +master_ssl_ca_path default_capath +master_ssl_cert default_cert +master_ssl_cipher default_cipher +master_ssl_key default_key +master_ssl_verify_server_cert No +master_ssl_crl default_crl +master_ssl_crlpath default_crlpath +using_gtid Current_Pos +master_retry_count 50000 +slave_heartbeat_period 15.000 +connection_name defaulted +connect_retry 30 +master_ssl_allowed No +master_ssl_ca_file default_ca +master_ssl_ca_path default_capath +master_ssl_cert default_cert +master_ssl_cipher default_cipher +master_ssl_key default_key +master_ssl_verify_server_cert No +master_ssl_crl default_crl +master_ssl_crlpath default_crlpath +using_gtid Current_Pos +master_retry_count 50000 +slave_heartbeat_period 15.000 +connection_name unset +connect_retry 30 +master_ssl_allowed No +master_ssl_ca_file default_ca +master_ssl_ca_path default_capath +master_ssl_cert default_cert +master_ssl_cipher default_cipher +master_ssl_key default_key +master_ssl_verify_server_cert No +master_ssl_crl default_crl +master_ssl_crlpath default_crlpath +using_gtid Current_Pos +master_retry_count 50000 +slave_heartbeat_period 15.000 +RESET REPLICA 'unset' ALL; +CHANGE MASTER 'unset' TO master_host='127.0.1.3'; +# Validate command line options +# restart_abort: --master-heartbeat-period='' +# restart_abort: --master-heartbeat-period=123abc +# restart_abort: --master-heartbeat-period=-1 +# restart_abort: --master-heartbeat-period=4294967.296 +# restart: --skip-slave-start --master-heartbeat-period=0.000499 +SELECT connection_name, slave_heartbeat_period +FROM information_schema.slave_status ORDER BY connection_name; +connection_name slave_heartbeat_period + 0.000 +defaulted 0.000 +unset 0.000 +CALL mtr.add_suppression('.*master-heartbeat-period.+0.*disabl.+'); +FOUND 1 /\[Warning\] .*master-heartbeat-period.+0.*disabl.+/ in mysqld.1.err +# restart: --skip-slave-start --skip-master-ssl --master-ssl --skip-master-ssl-verify-server-cert --master-ssl-verify-server-cert --master-use-gtid=NO --autoset-master-use-gtid --master-heartbeat-period=45 --autoset-master-heartbeat-period +CALL show_defaultable_fields(); +connection_name +connect_retry 60 +master_ssl_allowed Yes +master_ssl_ca_file +master_ssl_ca_path +master_ssl_cert +master_ssl_cipher +master_ssl_key +master_ssl_verify_server_cert Yes +master_ssl_crl +master_ssl_crlpath +using_gtid Slave_Pos +master_retry_count 100000 +slave_heartbeat_period 60.000 +connection_name defaulted +connect_retry 60 +master_ssl_allowed Yes +master_ssl_ca_file +master_ssl_ca_path +master_ssl_cert +master_ssl_cipher +master_ssl_key +master_ssl_verify_server_cert Yes +master_ssl_crl +master_ssl_crlpath +using_gtid Slave_Pos +master_retry_count 100000 +slave_heartbeat_period 60.000 +connection_name unset +connect_retry 60 +master_ssl_allowed Yes +master_ssl_ca_file +master_ssl_ca_path +master_ssl_cert +master_ssl_cipher +master_ssl_key +master_ssl_verify_server_cert Yes +master_ssl_crl +master_ssl_crlpath +using_gtid Slave_Pos +master_retry_count 100000 +slave_heartbeat_period 60.000 +# Clean-up +DROP PROCEDURE show_defaultable_fields; +RESET REPLICA 'unset' ALL; +RESET REPLICA 'defaulted' ALL; +RESET REPLICA ALL; +# End of main.change_master_default diff --git a/mysql-test/main/change_master_default.test b/mysql-test/main/change_master_default.test new file mode 100644 index 0000000000000..a4e25c8d86992 --- /dev/null +++ b/mysql-test/main/change_master_default.test @@ -0,0 +1,149 @@ +--echo # Start of main.change_master_default + +# MDEV-28302: Test how `CHANGE MASTER [named]` reads server +# options for its default values and the lack of those options. +# The test creates multiple CHANGE MASTER connections, +# where the defaultable fields of a connection are: +# * left unset +# * set to `DEFAULT` +# * configured with values + +# only need CHANGE MASTER and IS.slave_status +--source include/have_binlog_format_mixed.inc + +CREATE PROCEDURE show_defaultable_fields() +SELECT connection_name, + connect_retry, + master_ssl_allowed, + master_ssl_ca_file, + master_ssl_ca_path, + master_ssl_cert, + master_ssl_cipher, + master_ssl_key, + master_ssl_verify_server_cert, + master_ssl_crl, + master_ssl_crlpath, + using_gtid, + master_retry_count, + slave_heartbeat_period +FROM information_schema.slave_status ORDER BY connection_name; + +CHANGE MASTER 'unset' TO master_host='127.0.1.1'; + +CHANGE MASTER 'defaulted' TO + master_connect_retry= DEFAULT, + master_ssl= DEFAULT, + master_ssl_ca= DEFAULT, + master_ssl_capath= DEFAULT, + master_ssl_cert= DEFAULT, + master_ssl_cipher= DEFAULT, + master_ssl_key= DEFAULT, + master_ssl_verify_server_cert= DEFAULT, + master_ssl_crl= DEFAULT, + master_ssl_crlpath= DEFAULT, + master_use_gtid= DEFAULT, + master_retry_count= DEFAULT, + master_heartbeat_period= DEFAULT, + master_host= '127.0.1.2'; + +CHANGE MASTER TO # Default master does not replace named masters + master_connect_retry= 90, + master_ssl= FALSE, + master_ssl_ca= 'specified_ca', + master_ssl_capath= 'specified_capath', + master_ssl_cert= 'specified_cert', + master_ssl_cipher= 'specified_cipher', + master_ssl_key= 'specified_key', + master_ssl_verify_server_cert= FALSE, + master_ssl_crl= 'specified_crl', + master_ssl_crlpath= 'specified_crlpath', + master_use_gtid= NO, + master_retry_count= 150000, + master_heartbeat_period= 45, + master_host='127.0.0.1'; + +# Show freshly created configurations +--query_vertical CALL show_defaultable_fields() + + +--echo # Those set or left as `DEFAULT` should pick up changes to defaults. + +--let $restart_parameters= --skip-slave-start --master-connect-retry=30 --skip-master-ssl --master-ssl-ca=default_ca --master-ssl-capath=default_capath --master-ssl-cert=default_cert --master-ssl-cipher=default_cipher --master-ssl-key=default_key --skip-master-ssl-verify-server-cert --master-ssl-crl=default_crl --master-ssl-crlpath=default_crlpath --master-use-gtid=CURRENT_POS --master-retry-count=50000 --master-heartbeat-period=15 +--source include/restart_mysqld.inc # not_embedded +--query_vertical CALL show_defaultable_fields() + +# The `DEFAULT` of `master_heartbeat_period` changes with `@@slave_net_timeout`. +SET @@GLOBAL.slave_net_timeout= 100; +SELECT connection_name, slave_heartbeat_period +FROM information_schema.slave_status ORDER BY connection_name; + +# `DEFAULT` overwrites the existing configs for only the CHANGEd connection. +CHANGE MASTER TO + master_connect_retry= DEFAULT, + master_ssl= DEFAULT, + master_ssl_ca= DEFAULT, + master_ssl_capath= DEFAULT, + master_ssl_cert= DEFAULT, + master_ssl_cipher= DEFAULT, + master_ssl_key= DEFAULT, + master_ssl_verify_server_cert= DEFAULT, + master_ssl_crl= DEFAULT, + master_ssl_crlpath= DEFAULT, + master_use_gtid= DEFAULT, + master_retry_count= DEFAULT, + master_heartbeat_period= DEFAULT; +--query_vertical CALL show_defaultable_fields() + +# Recreate 'unset' to see later that it saves `DEFAULT`, not the options' values +--disable_warnings + RESET REPLICA 'unset' ALL; +--enable_warnings +CHANGE MASTER 'unset' TO master_host='127.0.1.3'; + + +--echo # Validate command line options + +# Invalid `--master-heartbeat-period` values should abort the server +# (`restart_abort` includes a wait for the server to exit on its own, +# e.g., due to a startup error.) +--source include/shutdown_mysqld.inc +--let $restart_parameters= restart_abort: --master-heartbeat-period='' +--echo # $restart_parameters +--write_line "$restart_parameters" $_expect_file_name +--let $restart_parameters= restart_abort: --master-heartbeat-period=123abc +--echo # $restart_parameters +--write_line "$restart_parameters" $_expect_file_name +--let $restart_parameters= restart_abort: --master-heartbeat-period=-1 +--echo # $restart_parameters +--write_line "$restart_parameters" $_expect_file_name +--let $restart_parameters= restart_abort: --master-heartbeat-period=4294967.296 +--echo # $restart_parameters +--write_line "$restart_parameters" $_expect_file_name + +# Numbers between 0 and 0.5 exclusive should warn about rounding to 0 (disabled) +--let $restart_parameters= --skip-slave-start --master-heartbeat-period=0.000499 +--source include/start_mysqld.inc +SELECT connection_name, slave_heartbeat_period +FROM information_schema.slave_status ORDER BY connection_name; +--let $regexp= .*master-heartbeat-period.+0.*disabl.+ +--eval CALL mtr.add_suppression('$regexp') +--let SEARCH_FILE= `SELECT @@log_error` +--let SEARCH_PATTERN= \[Warning\] $regexp +--source include/search_pattern_in_file.inc + +# Test prefixes: adding `auto-` and omitting `skip-` +--let $restart_parameters= --skip-slave-start --skip-master-ssl --master-ssl --skip-master-ssl-verify-server-cert --master-ssl-verify-server-cert --master-use-gtid=NO --autoset-master-use-gtid --master-heartbeat-period=45 --autoset-master-heartbeat-period +--source include/restart_mysqld.inc + +--query_vertical CALL show_defaultable_fields() + + +--echo # Clean-up + +DROP PROCEDURE show_defaultable_fields; + +RESET REPLICA 'unset' ALL; +RESET REPLICA 'defaulted' ALL; +RESET REPLICA ALL; + +--echo # End of main.change_master_default diff --git a/mysql-test/main/change_user.result b/mysql-test/main/change_user.result index d9bbb34b6c295..3b7d668947dbb 100644 --- a/mysql-test/main/change_user.result +++ b/mysql-test/main/change_user.result @@ -1,7 +1,4 @@ connect old,localhost,root,,,,,auth=mysql_old_password:mysql_native_password; -set global secure_auth=0; -Warnings: -Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release create user test_nopw; grant select on test.* to test_nopw; create user test_oldpw identified by password "09301740536db389"; @@ -11,27 +8,27 @@ grant select on test.* to test_newpw; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() test +change_user test_nopw,,; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() NULL -select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); -concat('<', user(), '>') concat('<', current_user(), '>') database() - NULL +change_user test_newpw,newpw,; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() NULL +change_user root,,; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() NULL +change_user test_nopw,,test; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() test -select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); -concat('<', user(), '>') concat('<', current_user(), '>') database() - test +change_user test_newpw,newpw,test; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() test +change_user root,,test; select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); concat('<', user(), '>') concat('<', current_user(), '>') database() test @@ -45,7 +42,7 @@ SELECT @@session.sql_big_selects; SELECT @@global.max_join_size; @@global.max_join_size HA_POS_ERROR -change_user +change_user root,,test; SELECT @@session.sql_big_selects; @@session.sql_big_selects 1 @@ -54,13 +51,13 @@ SELECT @@global.max_join_size; HA_POS_ERROR SET @@global.max_join_size = 10000; SET @@session.max_join_size = default; -change_user +change_user root,,test; SELECT @@session.sql_big_selects; @@session.sql_big_selects 0 SET @@global.max_join_size = 18446744073709551615; SET @@session.max_join_size = default; -change_user +change_user root,,test; SELECT @@session.sql_big_selects; @@session.sql_big_selects 1 @@ -83,7 +80,7 @@ GET_LOCK('bug31418', 1) SELECT IS_USED_LOCK('bug31418') = CONNECTION_ID(); IS_USED_LOCK('bug31418') = CONNECTION_ID() 1 -change_user +change_user root,,test; SELECT IS_FREE_LOCK('bug31418'); IS_FREE_LOCK('bug31418') 1 @@ -91,10 +88,8 @@ SELECT IS_USED_LOCK('bug31418'); IS_USED_LOCK('bug31418') NULL FLUSH STATUS; +change_user root,,test; Value of com_select did not change -set global secure_auth=default; -Warnings: -Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release set timestamp=unix_timestamp('2010-10-10 10:10:10'); select now(); now() @@ -102,7 +97,7 @@ now() select year(now()) > 2011; year(now()) > 2011 0 -change_user +change_user root,,test; select year(now()) > 2011; year(now()) > 2011 1 diff --git a/mysql-test/main/change_user.test b/mysql-test/main/change_user.test index 5f7d5a21915b0..d891ce4ea962c 100644 --- a/mysql-test/main/change_user.test +++ b/mysql-test/main/change_user.test @@ -1,10 +1,8 @@ -# This test is checking that old password authentication works --disable_service_connection # connect with mysql_old_password enabled connect old,localhost,root,,,,,auth=mysql_old_password:mysql_native_password; -set global secure_auth=0; # # functional change user tests # @@ -27,19 +25,6 @@ change_user test_nopw; --replace_result <@> @> @localhost> select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); -# -# embedded with enabled privilege control cannot do plugin negotiation. -# that is, it cannot try to authenticate with a new scramble, receive a request -# to switch to an old scramble, and retry with an old scramble. -# As a result, it cannot change to a user that has old scramble and -# and it stays logged as a previous user - test_nopw in this test file. -# For the embedded with auth we replace nopw with oldpw in the results. -# -let $repl = `select if(version() like '%embedded%' and user() like '%nopw%', 'nopw', 'oldpw')`; - -change_user test_oldpw, oldpw; ---replace_result <@> @> @localhost> $repl oldpw -select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); change_user test_newpw, newpw; --replace_result <@> @> @localhost> select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); @@ -50,9 +35,6 @@ select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); change_user test_nopw,,test; --replace_result <@> @> @localhost> select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); -change_user test_oldpw,oldpw,test; ---replace_result <@> @> @localhost> $repl oldpw -select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); change_user test_newpw,newpw,test; --replace_result <@> @> @localhost> select concat('<', user(), '>'), concat('<', current_user(), '>'), database(); @@ -74,7 +56,6 @@ SELECT @@session.sql_big_selects; # The exact value depends on the server build flags --replace_result 18446744073709551615 HA_POS_ERROR 4294967295 HA_POS_ERROR SELECT @@global.max_join_size; ---echo change_user --change_user SELECT @@session.sql_big_selects; # The exact value depends on the server build flags @@ -82,7 +63,6 @@ SELECT @@session.sql_big_selects; SELECT @@global.max_join_size; SET @@global.max_join_size = 10000; SET @@session.max_join_size = default; ---echo change_user --change_user SELECT @@session.sql_big_selects; # On some machines the following will result into a warning @@ -90,7 +70,6 @@ SELECT @@session.sql_big_selects; SET @@global.max_join_size = 18446744073709551615; --enable_warnings SET @@session.max_join_size = default; ---echo change_user --change_user SELECT @@session.sql_big_selects; --replace_result 4294967295 18446744073709551615 @@ -107,7 +86,6 @@ SELECT IS_FREE_LOCK('bug31418'); SELECT IS_USED_LOCK('bug31418'); SELECT GET_LOCK('bug31418', 1); SELECT IS_USED_LOCK('bug31418') = CONNECTION_ID(); ---echo change_user --change_user SELECT IS_FREE_LOCK('bug31418'); SELECT IS_USED_LOCK('bug31418'); @@ -146,12 +124,9 @@ if ($after != $before){ } echo Value of com_select did not change; -set global secure_auth=default; - set timestamp=unix_timestamp('2010-10-10 10:10:10'); select now(); select year(now()) > 2011; ---echo change_user --change_user select year(now()) > 2011; --enable_service_connection diff --git a/mysql-test/main/change_user_notembedded.result b/mysql-test/main/change_user_notembedded.result index fbdd15377c77e..61fdf2b1f6ca0 100644 --- a/mysql-test/main/change_user_notembedded.result +++ b/mysql-test/main/change_user_notembedded.result @@ -1,9 +1,15 @@ connect test,localhost,root,,; connection test; +change_user foo,bar,; ERROR 28000: Access denied for user 'foo'@'localhost' (using password: YES) +change_user foo,,; ERROR 28000: Access denied for user 'foo'@'localhost' (using password: NO) +change_user root,,test; +change_user foo,bar,; ERROR 28000: Access denied for user 'foo'@'localhost' (using password: YES) +change_user foo,bar,; ERROR 08S01: Unknown command +change_user root,,test; ERROR 08S01: Unknown command disconnect test; connection default; @@ -12,6 +18,7 @@ connection default; # MDEV-36405 Session tracking does not report changes from COM_CHANGE_USER # change_user +change_user root,,test; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES -- autocommit: ON -- character_set_client: latin1 diff --git a/mysql-test/main/check.result b/mysql-test/main/check.result index e7d26778e88ad..13219415a908a 100644 --- a/mysql-test/main/check.result +++ b/mysql-test/main/check.result @@ -1,8 +1,6 @@ connect con1,localhost,root,,; connect con2,localhost,root,,; connection con1; -drop table if exists t1,t2; -drop view if exists v1; create table t1(n int not null, key(n), key(n), key(n), key(n)); Warnings: Note 1831 Duplicate index `n_2`. This is deprecated and will be disallowed in a future release @@ -18,6 +16,7 @@ connection default; disconnect con1; disconnect con2; drop table t1; +# End of 4.1 tests Create table t1(f1 int); Create table t2(f1 int); Create view v1 as Select * from t1; @@ -39,7 +38,6 @@ DROP TABLE t1; # Bug#56422 CHECK TABLE run when the table is locked reports corruption # along with timeout # -DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT); LOCK TABLE t1 WRITE; connect con1, localhost, root; @@ -53,52 +51,24 @@ UNLOCK TABLES; DROP TABLE t1; disconnect con1; # -# MDEV-15338 -# Assertion `!table || (!table->read_set || -# bitmap_is_set(table->read_set, field_index))' -# failed on dropping column with CHECK +# MDEV-37971 CHECK TABLE command can be executed by users with the table-level CREATE but not with global CREATE # -CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,2),(3,4); -ALTER TABLE t1 DROP COLUMN a; -CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b; -ERROR 42S22: Unknown column 'b' in 'CHECK' -ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL, - `b` int(11) DEFAULT NULL, - `c` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` int(11) DEFAULT NULL, - `c` int(11) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -DROP TABLE t1; -create temporary table t1 ( -id int not null auto_increment primary key, -f int not null default 0 -); -insert into t1 () values (); -alter ignore table t1 add constraint check (f > 0); -Warnings: -Warning 4025 CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` -alter table t1; -drop table t1; -create temporary table t1 (a int default 0, check (a > 0)); -alter table t1 drop constraint if exists non_existing_constraint; -Warnings: -Note 1091 Can't DROP CONSTRAINT `non_existing_constraint`; check that it exists -insert into t1 () values (); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +create table t1 (a int); +create user table_level_priv; +create user global_level_priv; +grant create on *.* to global_level_priv; +grant create on test.t1 to table_level_priv; +connect g,localhost,global_level_priv; +check table test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +connect t,localhost,table_level_priv; +check table test.t1; +Table Op Msg_type Msg_text +test.t1 check status OK +disconnect g; +disconnect t; +connection default; drop table t1; +drop user table_level_priv, global_level_priv; +# End of 10.11 tests diff --git a/mysql-test/main/check.test b/mysql-test/main/check.test index 29587a9f62313..2f48fe8543dce 100644 --- a/mysql-test/main/check.test +++ b/mysql-test/main/check.test @@ -1,13 +1,6 @@ -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; ---disable_warnings -drop table if exists t1,t2; -drop view if exists v1; ---enable_warnings # Add a lot of keys to slow down check create table t1(n int not null, key(n), key(n), key(n), key(n)); @@ -32,7 +25,7 @@ disconnect con2; drop table t1; -# End of 4.1 tests +--echo # End of 4.1 tests # # Bug#9897 Views: 'Check Table' crashes MySQL, with a view and a table @@ -60,10 +53,6 @@ DROP TABLE t1; --echo # along with timeout --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1(a INT); LOCK TABLE t1 WRITE; @@ -76,51 +65,24 @@ UNLOCK TABLES; DROP TABLE t1; disconnect con1; - -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc - --echo # ---echo # MDEV-15338 ---echo # Assertion `!table || (!table->read_set || ---echo # bitmap_is_set(table->read_set, field_index))' ---echo # failed on dropping column with CHECK +--echo # MDEV-37971 CHECK TABLE command can be executed by users with the table-level CREATE but not with global CREATE --echo # - -CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -INSERT INTO t1 VALUES (1,2),(3,4); -ALTER TABLE t1 DROP COLUMN a; -CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; ---error ER_BAD_FIELD_ERROR -ALTER TABLE t1 DROP COLUMN b; -ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; -ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; -SHOW CREATE TABLE t1; -DROP TABLE t1; - -# -# MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table -# -create temporary table t1 ( - id int not null auto_increment primary key, - f int not null default 0 -); -insert into t1 () values (); -alter ignore table t1 add constraint check (f > 0); -alter table t1; +create table t1 (a int); +create user table_level_priv; +create user global_level_priv; +grant create on *.* to global_level_priv; +grant create on test.t1 to table_level_priv; + +connect g,localhost,global_level_priv; +check table test.t1; + +connect t,localhost,table_level_priv; +check table test.t1; +disconnect g; +disconnect t; +connection default; drop table t1; +drop user table_level_priv, global_level_priv; -# -# MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint -# -create temporary table t1 (a int default 0, check (a > 0)); -alter table t1 drop constraint if exists non_existing_constraint; ---error ER_CONSTRAINT_FAILED -insert into t1 () values (); -drop table t1; +--echo # End of 10.11 tests diff --git a/mysql-test/main/check_constraint.result b/mysql-test/main/check_constraint.result index 830fff3243f78..fbec0c6839806 100644 --- a/mysql-test/main/check_constraint.result +++ b/mysql-test/main/check_constraint.result @@ -131,17 +131,29 @@ t1 CREATE TABLE `t1` ( CONSTRAINT `CONSTRAINT_2` CHECK (`a` > `b`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t1; +# +# MDEV-10370 Check constraints on virtual columns fails on INSERT when column not specified +# create table t1(c1 int, c2 int as (c1 + 1), check (c2 > 2)); insert into t1(c1) values(1); ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` insert into t1(c1) values(2); drop table t1; +# +# MDEV-11117 CHECK constraint fails on intermediate step of ALTER +# create or replace table t1( c1 int auto_increment primary key, check( c1 > 0 or c1 is null ) ); ERROR HY000: Function or expression 'AUTO_INCREMENT' cannot be used in the CHECK clause of `c1` +# +# MDEV-12421 Check constraint with query crashes server and renders DB unusable +# create table t1 (a int check (@b in (select user from mysql.user))); ERROR 42000: CHECK does not support subqueries or stored functions create table t1 (a int check (a > @b)); ERROR HY000: Function or expression '@b' cannot be used in the CHECK clause of `a` +# +# MDEV-13596 CHECK constraints disallow NULL to pass through, violating SQL +# create table t1 (a int check (a = 1)); insert t1 values (1); insert t1 values (2); @@ -152,10 +164,16 @@ a 1 NULL drop table t1; +# +# MDEV-15141 Check constraint validation on a datetime field crashes the process +# create table t1 (id int auto_increment primary key, datecol datetime, check (datecol>'0001-01-01 00:00:00')); insert into t1 (datecol) values (now()); insert into t1 (datecol) values (now()); drop table t1; +# +# MDEV-15461 Check Constraints with binary logging makes insert inconsistent +# CREATE TABLE t1 ( EmployeeID SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, FirstName VARCHAR(30) NOT NULL CHECK (CHAR_LENGTH(FirstName > 2)) @@ -198,8 +216,7 @@ EmployeeID FirstName 6 Brian drop table t1; # -# MDEV-16630: Ambiguous error message when check constraint -# matches table name +# MDEV-16630: Ambiguous error message when check constraint matches table name # use test; drop table if exists t; @@ -279,8 +296,59 @@ Warning 1265 Data truncated for column 'v1' at row 1 Warning 1292 Truncated incorrect INTEGER value: 'x' drop table t1; # -# End of 10.2 tests +# MDEV-15338 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on dropping column with CHECK +# +CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,2),(3,4); +ALTER TABLE t1 DROP COLUMN a; +CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b; +ERROR 42S22: Unknown column 'b' in 'CHECK' +ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `b` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL, + `c` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +DROP TABLE t1; +# +# MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table +# +create temporary table t1 ( +id int not null auto_increment primary key, +f int not null default 0 +); +insert into t1 () values (); +alter ignore table t1 add constraint check (f > 0); +Warnings: +Warning 4025 CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +alter table t1; +drop table t1; # +# MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint +# +create temporary table t1 (a int default 0, check (a > 0)); +alter table t1 drop constraint if exists non_existing_constraint; +Warnings: +Note 1091 Can't DROP CONSTRAINT `non_existing_constraint`; check that it exists +insert into t1 () values (); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +drop table t1; +# End of 10.2 tests # # MDEV-26061 MariaDB server crash at Field::set_default # @@ -292,10 +360,8 @@ t1 CREATE TABLE `t1` ( `1` int(1) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t1; -# # End of 10.3 tests # -# # MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error # create table t1 (id varchar(2), constraint id check (id regexp '[a-z]')); diff --git a/mysql-test/main/check_constraint.test b/mysql-test/main/check_constraint.test index 81fe6d162dc31..e62f7c2cc1abc 100644 --- a/mysql-test/main/check_constraint.test +++ b/mysql-test/main/check_constraint.test @@ -69,32 +69,32 @@ create or replace table t1 (a int, b int, show create table t1; drop table t1; -# -# MDEV-10370 Check constraints on virtual columns fails on INSERT when column not specified -# +--echo # +--echo # MDEV-10370 Check constraints on virtual columns fails on INSERT when column not specified +--echo # create table t1(c1 int, c2 int as (c1 + 1), check (c2 > 2)); --error ER_CONSTRAINT_FAILED insert into t1(c1) values(1); insert into t1(c1) values(2); drop table t1; -# -# MDEV-11117 CHECK constraint fails on intermediate step of ALTER -# +--echo # +--echo # MDEV-11117 CHECK constraint fails on intermediate step of ALTER +--echo # -- error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED create or replace table t1( c1 int auto_increment primary key, check( c1 > 0 or c1 is null ) ); -# -# MDEV-12421 Check constraint with query crashes server and renders DB unusable -# +--echo # +--echo # MDEV-12421 Check constraint with query crashes server and renders DB unusable +--echo # --error ER_SUBQUERIES_NOT_SUPPORTED create table t1 (a int check (@b in (select user from mysql.user))); --error ER_GENERATED_COLUMN_FUNCTION_IS_NOT_ALLOWED create table t1 (a int check (a > @b)); -# -# MDEV-13596 CHECK constraints disallow NULL to pass through, violating SQL -# +--echo # +--echo # MDEV-13596 CHECK constraints disallow NULL to pass through, violating SQL +--echo # create table t1 (a int check (a = 1)); insert t1 values (1); --error ER_CONSTRAINT_FAILED @@ -103,17 +103,17 @@ insert t1 values (NULL); select * from t1; drop table t1; -# -# MDEV-15141 Check constraint validation on a datetime field crashes the process -# +--echo # +--echo # MDEV-15141 Check constraint validation on a datetime field crashes the process +--echo # create table t1 (id int auto_increment primary key, datecol datetime, check (datecol>'0001-01-01 00:00:00')); insert into t1 (datecol) values (now()); insert into t1 (datecol) values (now()); drop table t1; -# -# MDEV-15461 Check Constraints with binary logging makes insert inconsistent -# +--echo # +--echo # MDEV-15461 Check Constraints with binary logging makes insert inconsistent +--echo # CREATE TABLE t1 ( EmployeeID SMALLINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, @@ -136,8 +136,7 @@ select * from t1; drop table t1; --echo # ---echo # MDEV-16630: Ambiguous error message when check constraint ---echo # matches table name +--echo # MDEV-16630: Ambiguous error message when check constraint matches table name --echo # use test; @@ -208,8 +207,48 @@ insert ignore into t1 values ( 'x' , 'x' ) ; drop table t1; --echo # ---echo # End of 10.2 tests +--echo # MDEV-15338 Assertion `!table || (!table->read_set || bitmap_is_set(table->read_set, field_index))' failed on dropping column with CHECK +--echo # + +CREATE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,2),(3,4); +ALTER TABLE t1 DROP COLUMN a; +CREATE OR REPLACE TABLE t1 (a INT, b INT, CHECK (a>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +--error ER_BAD_FIELD_ERROR +ALTER TABLE t1 DROP COLUMN b; +ALTER TABLE t1 DROP COLUMN a, DROP COLUMN b; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +CREATE OR REPLACE TABLE t1 (a INT, b INT, c INT, CHECK (a+b>0)) ENGINE=MyISAM; +ALTER TABLE t1 DROP COLUMN b, DROP CONSTRAINT `CONSTRAINT_1`; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-16903 Assertion `!auto_increment_field_not_null' failed in TABLE::init after unsuccessful attempt to add CHECK constraint on temporary table +--echo # +create temporary table t1 ( + id int not null auto_increment primary key, + f int not null default 0 +); +insert into t1 () values (); +alter ignore table t1 add constraint check (f > 0); +alter table t1; +drop table t1; + --echo # +--echo # MDEV-16905 ASAN heap-use-after-free in __interceptor_strnlen / ... / TABLE::verify_constraints upon INSERT into temporary table with CHECK constraint +--echo # +create temporary table t1 (a int default 0, check (a > 0)); +alter table t1 drop constraint if exists non_existing_constraint; +--error ER_CONSTRAINT_FAILED +insert into t1 () values (); +drop table t1; + +--echo # End of 10.2 tests --echo # --echo # MDEV-26061 MariaDB server crash at Field::set_default @@ -219,9 +258,7 @@ create table t1 (d timestamp not null default now() check (default (d) is true)) show create table t1; drop table t1; ---echo # --echo # End of 10.3 tests ---echo # --echo # --echo # MDEV-24274 ALTER TABLE with CHECK CONSTRAINTS gives "Out of Memory" error diff --git a/mysql-test/main/client_xml.result b/mysql-test/main/client_xml.result index 6f91c18318cf3..1c090300f19c7 100644 --- a/mysql-test/main/client_xml.result +++ b/mysql-test/main/client_xml.result @@ -1,6 +1,5 @@ set @old_concurrent_insert= @@global.concurrent_insert; set @@global.concurrent_insert= 0; -drop table if exists t1; create table t1 ( `a&b` int, `a= 100000, so reversed comments with version +# <= current should NOT execute (server is not older than that version). +SELECT 1 /*!!50101 +1 */; +1 +1 +SELECT 1 /*!!100000 +1 */; +1 +1 +# Reversed comment with version higher than current SHOULD execute. +SELECT 1 /*!!999999 +1 */; +1 +1 +2 +# MariaDB-specific reversed executable comments +SELECT 1 /*M!!50101 +1 */; +1 +1 +SELECT 1 /*M!!999999 +1 */; +1 +1 +2 +# Without version number (just /*!! with no digits) should still work +# as a regular executable comment expanding the content. +SELECT 1 /*!! +1 */; +1 +1 +2 +SELECT 1 /*M!! +1 */; +1 +1 +2 +# Combined forward and reversed in the same statement (MDEV-7381 use case). +# On this server (>= 10.0.0): /*!100000 OR REPLACE */ executes, +# /*!!100000 IF NOT EXISTS */ is skipped. +# Effective statement: CREATE OR REPLACE TABLE t1 (a INT); +CREATE /*!100000 OR REPLACE */ TABLE /*!!100000 IF NOT EXISTS */ t1 (a INT); +INSERT INTO t1 VALUES (1); +# Run again. OR REPLACE should drop and recreate the table, losing the row. +CREATE /*!100000 OR REPLACE */ TABLE /*!!100000 IF NOT EXISTS */ t1 (a INT); +# Table should be empty, proving OR REPLACE was used (not IF NOT EXISTS). +SELECT COUNT(*) FROM t1; +COUNT(*) +0 +DROP TABLE t1; diff --git a/mysql-test/main/comments.test b/mysql-test/main/comments.test index 671e5d6583555..49d18c332f928 100644 --- a/mysql-test/main/comments.test +++ b/mysql-test/main/comments.test @@ -101,3 +101,36 @@ prepare bar from "DELETE FROM table_28779 WHERE a = 7 OR 1=1/*!998765' AND b = ' drop table table_28779; + +--echo # +--echo # MDEV-7381: Reversed executable comments +--echo # + +--echo # Server version is >= 100000, so reversed comments with version +--echo # <= current should NOT execute (server is not older than that version). +SELECT 1 /*!!50101 +1 */; +SELECT 1 /*!!100000 +1 */; + +--echo # Reversed comment with version higher than current SHOULD execute. +SELECT 1 /*!!999999 +1 */; + +--echo # MariaDB-specific reversed executable comments +SELECT 1 /*M!!50101 +1 */; +SELECT 1 /*M!!999999 +1 */; + +--echo # Without version number (just /*!! with no digits) should still work +--echo # as a regular executable comment expanding the content. +SELECT 1 /*!! +1 */; +SELECT 1 /*M!! +1 */; + +--echo # Combined forward and reversed in the same statement (MDEV-7381 use case). +--echo # On this server (>= 10.0.0): /*!100000 OR REPLACE */ executes, +--echo # /*!!100000 IF NOT EXISTS */ is skipped. +--echo # Effective statement: CREATE OR REPLACE TABLE t1 (a INT); +CREATE /*!100000 OR REPLACE */ TABLE /*!!100000 IF NOT EXISTS */ t1 (a INT); +INSERT INTO t1 VALUES (1); +--echo # Run again. OR REPLACE should drop and recreate the table, losing the row. +CREATE /*!100000 OR REPLACE */ TABLE /*!!100000 IF NOT EXISTS */ t1 (a INT); +--echo # Table should be empty, proving OR REPLACE was used (not IF NOT EXISTS). +SELECT COUNT(*) FROM t1; +DROP TABLE t1; diff --git a/mysql-test/main/compress.test b/mysql-test/main/compress.test index daa133ebdc7cf..f48919d264dcc 100644 --- a/mysql-test/main/compress.test +++ b/mysql-test/main/compress.test @@ -9,10 +9,6 @@ # Slow test, don't run during staging part -- source include/not_staging.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - - connect (comp_con,localhost,root,,,,,COMPRESS); # Check compression turned on @@ -27,7 +23,3 @@ SHOW STATUS LIKE 'Compression'; connection default; disconnect comp_con; - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/connect.result b/mysql-test/main/connect.result index 4ce32842a0051..b6e02d1b88fcb 100644 --- a/mysql-test/main/connect.result +++ b/mysql-test/main/connect.result @@ -1,6 +1,3 @@ -SET global secure_auth=0; -Warnings: -Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release connect con1,localhost,root,,mysql; show tables; Tables_in_mysql @@ -102,63 +99,6 @@ connect(localhost,test,zorro,test,MASTER_PORT,MASTER_SOCKET); connect fail_con,localhost,test,zorro,; ERROR 28000: Access denied for user 'test'@'localhost' (using password: YES) # switching from mysql.global_priv to mysql.user -update mysql.user set plugin="", authentication_string="", password=old_password("gambling2") where user=_binary"test"; -flush privileges; -show grants for test@localhost; -Grants for test@localhost -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, BINLOG MONITOR, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY, SET USER, FEDERATED ADMIN, CONNECTION ADMIN, READ_ONLY ADMIN, REPLICATION SLAVE ADMIN, REPLICATION MASTER ADMIN, BINLOG ADMIN, BINLOG REPLAY, SLAVE MONITOR ON *.* TO `test`@`localhost` IDENTIFIED BY PASSWORD '2f27438961437573' -update mysql.user set plugin='mysql_old_password' where user='test'; -flush privileges; -show grants for test@localhost; -Grants for test@localhost -GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, BINLOG MONITOR, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY, SET USER, FEDERATED ADMIN, CONNECTION ADMIN, READ_ONLY ADMIN, REPLICATION SLAVE ADMIN, REPLICATION MASTER ADMIN, BINLOG ADMIN, BINLOG REPLAY, SLAVE MONITOR ON *.* TO `test`@`localhost` IDENTIFIED BY PASSWORD '2f27438961437573' -connect con10,localhost,test,gambling2,,,,auth=mysql_old_password:mysql_native_password; -connect con5,localhost,test,gambling2,mysql,,,auth=mysql_old_password:mysql_native_password; -set password=""; -set password='gambling3'; -ERROR HY000: Password hash should be a 41-digit hexadecimal number -set password=old_password('gambling3'); -show tables; -Tables_in_mysql -column_stats -columns_priv -db -event -func -general_log -global_priv_bak -gtid_slave_pos -help_category -help_keyword -help_relation -help_topic -index_stats -innodb_index_stats -innodb_table_stats -plugin -proc -procs_priv -proxies_priv -roles_mapping -servers -slow_log -table_stats -tables_priv -time_zone -time_zone_leap_second -time_zone_name -time_zone_transition -time_zone_transition_type -transaction_registry -user -user_bak -connect con6,localhost,test,gambling3,test,,,auth=mysql_old_password:mysql_native_password; -show tables; -Tables_in_test -connection default; -disconnect con10; -disconnect con5; -disconnect con6; connect(localhost,test,,test2,MASTER_PORT,MASTER_SOCKET); connect fail_con,localhost,test,,test2,,,auth=mysql_old_password:mysql_native_password; ERROR 28000: Access denied for user 'test'@'localhost' (using password: NO) @@ -277,8 +217,6 @@ disconnect tmp_con7; # -- Restoring default connection... connect default,localhost,root,,test; -# -- Waiting for connections to close... - DROP USER mysqltest_u1@localhost; # -- End of Bug#33507. @@ -343,7 +281,6 @@ disconnect extracon; disconnect extracon2; connection default; CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB'; -CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389'; connect(localhost,mysqltest_up1,foo,test,MASTER_PORT,MASTER_SOCKET); connect pcon1,localhost,mysqltest_up1,foo,,$MASTER_MYPORT,; ERROR 28000: Access denied for user 'mysqltest_up1'@'localhost' (using password: YES) @@ -352,14 +289,6 @@ select user(), current_user(); user() current_user() mysqltest_up1@localhost mysqltest_up1@% disconnect pcon2; -connect(localhost,mysqltest_up2,newpw,test,MASTER_PORT,MASTER_SOCKET); -connect pcon3,localhost,mysqltest_up2,newpw,,$MASTER_MYPORT,,auth=mysql_old_password:mysql_native_password; -ERROR 28000: Access denied for user 'mysqltest_up2'@'localhost' (using password: YES) -connect pcon4,localhost,mysqltest_up2,oldpw,,$MASTER_MYPORT,,auth=mysql_old_password:mysql_native_password; -select user(), current_user(); -user() current_user() -mysqltest_up2@localhost mysqltest_up2@% -disconnect pcon4; connect(localhost,mysqltest_nouser,newpw,test,MASTER_PORT,MASTER_SOCKET); connect pcon5,localhost,mysqltest_nouser,newpw,,$MASTER_MYPORT,; ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using password: YES) @@ -369,27 +298,19 @@ ERROR 28000: Access denied for user 'mysqltest_nouser'@'localhost' (using passwo connection default; # switching from mysql.global_priv to mysql.user update mysql.user set plugin='mysql_native_password' where user = 'mysqltest_up1'; -update mysql.user set plugin='mysql_old_password' where user = 'mysqltest_up2'; select user, password, plugin, authentication_string from mysql.user where user like 'mysqltest_up_'; user password plugin authentication_string mysqltest_up1 *E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB mysql_native_password *E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB -mysqltest_up2 09301740536db389 mysql_old_password 09301740536db389 flush privileges; connect pcon6,localhost,mysqltest_up1,bar,,$MASTER_MYPORT,; select user(), current_user(); user() current_user() mysqltest_up1@localhost mysqltest_up1@% disconnect pcon6; -connect pcon7,localhost,mysqltest_up2,oldpw,,$MASTER_MYPORT,,auth=mysql_old_password:mysql_native_password; -select user(), current_user(); -user() current_user() -mysqltest_up2@localhost mysqltest_up2@% -disconnect pcon7; connection default; # switching back from mysql.user to mysql.global_priv DROP USER mysqltest_up1@'%'; -DROP USER mysqltest_up2@'%'; # # BUG#1010351: New "via" keyword in 5.2+ can't be used as identifier anymore # @@ -413,9 +334,6 @@ test test test drop procedure p1; -SET global secure_auth=default; -Warnings: -Warning 1287 '@@secure_auth' is deprecated and will be removed in a future release # # MDEV-19282: Log more specific warning with log_warnings=2 if # connection is aborted prior to authentication @@ -477,6 +395,4 @@ Connection_errors_peer_address 0 Connection_errors_select 0 Connection_errors_tcpwrap 0 set global max_connections= @max_con.save; -# # End of 10.5 tests -# diff --git a/mysql-test/main/connect.test b/mysql-test/main/connect.test index 8f95712d61a06..69acb71a119c3 100644 --- a/mysql-test/main/connect.test +++ b/mysql-test/main/connect.test @@ -9,11 +9,6 @@ # of the log tables (which are CSV-based). By connect mysql; show tables; --source include/have_csv.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - -SET global secure_auth=0; - #connect (con1,localhost,root,,""); #show tables; connect (con1,localhost,root,,mysql); @@ -61,29 +56,7 @@ connect (fail_con,localhost,test,zorro,test2); --error ER_ACCESS_DENIED_ERROR connect (fail_con,localhost,test,zorro,); -# check if old password version also works source include/switch_to_mysql_user.inc; -update mysql.user set plugin="", authentication_string="", password=old_password("gambling2") where user=_binary"test"; -flush privileges; -show grants for test@localhost; -update mysql.user set plugin='mysql_old_password' where user='test'; -flush privileges; -show grants for test@localhost; - -connect con10,localhost,test,gambling2,,,,auth=mysql_old_password:mysql_native_password; -connect con5,localhost,test,gambling2,mysql,,,auth=mysql_old_password:mysql_native_password; -set password=""; ---error ER_PASSWD_LENGTH -set password='gambling3'; -set password=old_password('gambling3'); -show tables; -connect (con6,localhost,test,gambling3,test,,,auth=mysql_old_password:mysql_native_password); -show tables; - -connection default; -disconnect con10; -disconnect con5; -disconnect con6; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCESS_DENIED_ERROR @@ -250,11 +223,6 @@ let $wait_condition = --echo # -- Restoring default connection... --connect (default,localhost,root,,test) ---echo ---echo # -- Waiting for connections to close... -let $count_sessions=1; ---source include/wait_until_count_sessions.inc - --echo DROP USER mysqltest_u1@localhost; @@ -267,6 +235,9 @@ DROP USER mysqltest_u1@localhost; --echo # -- Bug#35074: max_used_connections is not correct. --echo +let $count_sessions=1; +--source include/wait_until_count_sessions.inc + FLUSH GLOBAL STATUS; --echo @@ -368,7 +339,6 @@ FLUSH PRIVILEGES; # A couple of plugin tests - for builtin plugins only # CREATE USER mysqltest_up1 IDENTIFIED VIA mysql_native_password using '*E8D46CE25265E545D225A8A6F1BAF642FEBEE5CB'; -CREATE USER mysqltest_up2 IDENTIFIED VIA mysql_old_password using '09301740536db389'; --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --error ER_ACCESS_DENIED_ERROR @@ -377,13 +347,6 @@ connect(pcon2,localhost,mysqltest_up1,bar,,$MASTER_MYPORT,); select user(), current_user(); disconnect pcon2; ---replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT ---error ER_ACCESS_DENIED_ERROR -connect(pcon3,localhost,mysqltest_up2,newpw,,$MASTER_MYPORT,,auth=mysql_old_password:mysql_native_password); -connect(pcon4,localhost,mysqltest_up2,oldpw,,$MASTER_MYPORT,,auth=mysql_old_password:mysql_native_password); -select user(), current_user(); -disconnect pcon4; - # # lp:683112 Maria 5.2 incorrectly reports "(using password: NO)" # even when password is specified @@ -406,7 +369,6 @@ connection default; # source include/switch_to_mysql_user.inc; update mysql.user set plugin='mysql_native_password' where user = 'mysqltest_up1'; -update mysql.user set plugin='mysql_old_password' where user = 'mysqltest_up2'; select user, password, plugin, authentication_string from mysql.user where user like 'mysqltest_up_'; flush privileges; @@ -415,18 +377,11 @@ connect(pcon6,localhost,mysqltest_up1,bar,,$MASTER_MYPORT,); select user(), current_user(); disconnect pcon6; -connect(pcon7,localhost,mysqltest_up2,oldpw,,$MASTER_MYPORT,,auth=mysql_old_password:mysql_native_password); -select user(), current_user(); -disconnect pcon7; connection default; source include/switch_to_mysql_global_priv.inc; DROP USER mysqltest_up1@'%'; -DROP USER mysqltest_up2@'%'; - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc --echo # --echo # BUG#1010351: New "via" keyword in 5.2+ can't be used as identifier anymore @@ -453,8 +408,6 @@ delimiter ;| call p1(2); drop procedure p1; -SET global secure_auth=default; - --echo # --echo # MDEV-19282: Log more specific warning with log_warnings=2 if --echo # connection is aborted prior to authentication @@ -557,6 +510,4 @@ let $status_var_value= 1; show global status like 'Connection_errors%'; set global max_connections= @max_con.save; ---echo # --echo # End of 10.5 tests ---echo # diff --git a/mysql-test/main/consistent_snapshot.result b/mysql-test/main/consistent_snapshot.result index b978f1dd9d27f..ac9bc3188ee17 100644 --- a/mysql-test/main/consistent_snapshot.result +++ b/mysql-test/main/consistent_snapshot.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1; connect con1,localhost,root,,; connect con2,localhost,root,,; ### Test 1: @@ -42,3 +41,4 @@ connection default; disconnect con1; disconnect con2; DROP TABLE t1; +# End of 4.1 tests diff --git a/mysql-test/main/consistent_snapshot.test b/mysql-test/main/consistent_snapshot.test index a481e757bed1a..71ec59d02091e 100644 --- a/mysql-test/main/consistent_snapshot.test +++ b/mysql-test/main/consistent_snapshot.test @@ -1,12 +1,5 @@ --source include/have_innodb.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - connect (con1,localhost,root,,); connect (con2,localhost,root,,); @@ -62,8 +55,4 @@ disconnect con1; disconnect con2; DROP TABLE t1; -# End of 4.1 tests - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - +--echo # End of 4.1 tests diff --git a/mysql-test/main/costs.result b/mysql-test/main/costs.result index b8ee34cb1c1cb..f7b2b4a036f05 100644 --- a/mysql-test/main/costs.result +++ b/mysql-test/main/costs.result @@ -124,3 +124,77 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range l_suppkey l_suppkey 10 NULL 1 Using where; Using index drop table t1; set global InnoDB.optimizer_disk_read_ratio=@save; +# +# MDEV-37723 In MDEV-36861, analyze Q4 +# Alter disk based tmp table lookup cost formula +# +create table t1 (a int primary key, +b date, c char(15), +d blob, +key t1_ix1 (b)) ENGINE= InnoDB; +create table t2 (e int not null, +f int not null, +g date, h date, +primary key (e, f)) ENGINE= InnoDB; +insert into t1 select seq, date('1993-06-01') + interval seq second, +chr(65+mod(seq, 4)), NULL from seq_1_to_7000; +insert into t2 select a.seq, b.seq, date('1993-06-01') + interval b.seq day, +if (mod(a.seq,2), date('1993-06-01') + interval b.seq+1 day, +date('1993-06-01') - interval b.seq-1 day) +from seq_1_to_7000 a, seq_1_to_3 b; +set +@save_mhts= @@max_heap_table_size, +@@max_heap_table_size=16384; +# This should use "t1, FirstMatch(t2)". Not "t1, SJ-Materialization(t2)". +explain format=json +select c, count(*) as dc +from t1 +where +b >= date '1993-06-01' and b < date '1993-06-01' + interval '3' month and +exists (select * from t2 where e = t1.a and g < h) +group by c; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 12.53886553, + "filesort": { + "sort_key": "t1.c", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "possible_keys": ["PRIMARY", "t1_ix1"], + "loops": 1, + "rows": 7000, + "cost": 1.1518548, + "filtered": 100, + "attached_condition": "t1.b >= DATE'1993-06-01' and t1.b < (DATE'1993-06-01' + interval '3' month)" + } + }, + { + "table": { + "table_name": "t2", + "access_type": "ref", + "possible_keys": ["PRIMARY"], + "key": "PRIMARY", + "key_length": "4", + "used_key_parts": ["e"], + "ref": ["test.t1.a"], + "loops": 7000, + "rows": 1, + "cost": 6.7528092, + "filtered": 100, + "attached_condition": "t2.g < t2.h", + "first_match": "t1" + } + } + ] + } + } + } +} +set max_heap_table_size=@save_mhts; +drop table t1, t2; diff --git a/mysql-test/main/costs.test b/mysql-test/main/costs.test index c425390e17dd5..5de334c67d396 100644 --- a/mysql-test/main/costs.test +++ b/mysql-test/main/costs.test @@ -7,6 +7,7 @@ --source include/have_sequence.inc --source include/have_innodb.inc +--source include/innodb_stable_estimates.inc create table t1 (a int primary key, b int, c int, d int, e int, key ba (b,a), key bda (b,d,a), key cba (c,b,a), key cb (c,b), key d (d)) engine=aria; insert into t1 select seq,seq,seq,seq,seq from seq_1_to_10; @@ -114,3 +115,41 @@ explain select count(*) from test.t1 force index (l_suppkey) where l_suppkey >= drop table t1; set global InnoDB.optimizer_disk_read_ratio=@save; + +--echo # +--echo # MDEV-37723 In MDEV-36861, analyze Q4 +--echo # Alter disk based tmp table lookup cost formula +--echo # + +create table t1 (a int primary key, + b date, c char(15), + d blob, + key t1_ix1 (b)) ENGINE= InnoDB; +create table t2 (e int not null, + f int not null, + g date, h date, + primary key (e, f)) ENGINE= InnoDB; +--disable_warnings +insert into t1 select seq, date('1993-06-01') + interval seq second, + chr(65+mod(seq, 4)), NULL from seq_1_to_7000; +insert into t2 select a.seq, b.seq, date('1993-06-01') + interval b.seq day, + if (mod(a.seq,2), date('1993-06-01') + interval b.seq+1 day, + date('1993-06-01') - interval b.seq-1 day) + from seq_1_to_7000 a, seq_1_to_3 b; + +set + @save_mhts= @@max_heap_table_size, + @@max_heap_table_size=16384; + + +--echo # This should use "t1, FirstMatch(t2)". Not "t1, SJ-Materialization(t2)". +explain format=json +select c, count(*) as dc +from t1 +where + b >= date '1993-06-01' and b < date '1993-06-01' + interval '3' month and + exists (select * from t2 where e = t1.a and g < h) +group by c; + +set max_heap_table_size=@save_mhts; +drop table t1, t2; diff --git a/mysql-test/main/create-big.test b/mysql-test/main/create-big.test index a501d4c5e4480..3b14d14c5bef7 100644 --- a/mysql-test/main/create-big.test +++ b/mysql-test/main/create-big.test @@ -12,8 +12,6 @@ # Some of tests below also use binlog to check that statements are # executed and logged in correct order --source include/have_binlog_format_mixed_or_statement.inc -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc # Create auxiliary connections connect (addconroot1, localhost, root,,); @@ -547,6 +545,3 @@ disconnect addconroot3; set debug_sync='RESET'; source include/show_binlog_events.inc; -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/create_drop_binlog.result b/mysql-test/main/create_drop_binlog.result index dc8f217fd6fd9..eaf8b8da3417a 100644 --- a/mysql-test/main/create_drop_binlog.result +++ b/mysql-test/main/create_drop_binlog.result @@ -338,16 +338,16 @@ Log_name Pos Event_type Server_id End_log_pos Info RESET MASTER; RESET MASTER; SHOW MASTER STATUS; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 +File Position Binlog_Do_DB Binlog_Ignore_DB Gtid_Binlog_Pos +master-bin.000001 RESET MASTER TO 100; SHOW MASTER STATUS; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000100 +File Position Binlog_Do_DB Binlog_Ignore_DB Gtid_Binlog_Pos +master-bin.000100 RESET MASTER; SHOW MASTER STATUS; -File Position Binlog_Do_DB Binlog_Ignore_DB -master-bin.000001 +File Position Binlog_Do_DB Binlog_Ignore_DB Gtid_Binlog_Pos +master-bin.000001 CREATE TABLE t1(a INT, b INT); CREATE TABLE IF NOT EXISTS t1(a INT, b INT); Warnings: diff --git a/mysql-test/main/create_drop_function.result b/mysql-test/main/create_drop_function.result index d6bee4da33900..de74de05f71d2 100644 --- a/mysql-test/main/create_drop_function.result +++ b/mysql-test/main/create_drop_function.result @@ -3,8 +3,8 @@ CREATE FUNCTION f1(str char(20)) RETURNS CHAR(100) RETURN CONCAT('Hello, ', str, '!'); SELECT * FROM mysql.proc WHERE name like 'f1'; -db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate -test f1 FUNCTION f1 SQL CONTAINS_SQL NO DEFINER str char(20) char(100) CHARSET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci RETURN CONCAT('Hello, ', str, '!') root@localhost 2014-09-30 08:00:00 2014-09-30 08:00:00 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci RETURN CONCAT('Hello, ', str, '!') NONE +db name type specific_name language sql_data_access is_deterministic security_type param_list returns body definer created modified sql_mode comment character_set_client collation_connection db_collation body_utf8 aggregate path +test f1 FUNCTION f1 SQL CONTAINS_SQL NO DEFINER str char(20) char(100) CHARSET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci RETURN CONCAT('Hello, ', str, '!') root@localhost 2014-09-30 08:00:00 2014-09-30 08:00:00 STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION latin1 latin1_swedish_ci utf8mb4_uca1400_ai_ci RETURN CONCAT('Hello, ', str, '!') NONE CURRENT_SCHEMA SELECT f1('world'); f1('world') Hello, world! diff --git a/mysql-test/main/create_drop_role.result b/mysql-test/main/create_drop_role.result index e3c893aaacfe6..ee8243aa4fddf 100644 --- a/mysql-test/main/create_drop_role.result +++ b/mysql-test/main/create_drop_role.result @@ -76,6 +76,7 @@ Warnings: Note 1976 Can't drop role 'role_1'; it doesn't exist DROP ROLE role_1; ERROR HY000: Operation DROP ROLE failed for 'role_1' +disconnect user_a; DROP USER u1@localhost; CREATE ROLE r; GRANT SHOW DATABASES ON *.* TO r; diff --git a/mysql-test/main/create_drop_role.test b/mysql-test/main/create_drop_role.test index 808461ed3441c..e4890851bebe0 100644 --- a/mysql-test/main/create_drop_role.test +++ b/mysql-test/main/create_drop_role.test @@ -54,6 +54,7 @@ DROP ROLE IF EXISTS role_1; --error ER_CANNOT_USER DROP ROLE role_1; +disconnect user_a; DROP USER u1@localhost; # MDEV-17942 diff --git a/mysql-test/main/create_drop_user.result b/mysql-test/main/create_drop_user.result index 67717f3e4e05d..4a72a4b089152 100644 --- a/mysql-test/main/create_drop_user.result +++ b/mysql-test/main/create_drop_user.result @@ -41,3 +41,80 @@ Warnings: Note 1974 Can't drop user 'u1'@'%'; it doesn't exist DROP USER u2; ERROR HY000: Operation DROP USER failed for 'u2'@'%' +# +# MDEV-35617: DROP USER should leave no active session for that user +# +CREATE USER u1; +CREATE USER u2; +CREATE USER u3; +GRANT ALL on test.* to u1; +GRANT ALL on test.* to u2; +GRANT ALL on test.* to u3; +# Establish two connections on behalf the users u1, u3 +# A connection on behalf the user u2 isn't established intentionally +connect con1, localhost, u1, , test; +connect con3, localhost, u3, , test; +# Drop the users u1, u2, u3. Since the users u1 and u3 have active +# connections to the server, the warning about it will be output +connection default; +DROP USER u1, u2, u3; +Warnings: +Note 4227 Dropped users 'u1'@'%','u3'@'%' have active connections. Use KILL CONNECTION if they should not be used anymore. +# None of the users u1, u2, u3 should be present in the system +SELECT User, Host FROM mysql.user WHERE user IN ('u1', 'u2', 'u3'); +User Host +disconnect con1; +disconnect con3; +# Check behaviour of the DROP USER statement in +# oracle compatibility mode +SET @save_sql_mode = @@sql_mode; +SET sql_mode="oracle"; +CREATE USER u1; +CREATE USER u2; +CREATE USER u3; +GRANT ALL on test.* to u1; +GRANT ALL on test.* to u2; +GRANT ALL on test.* to u3; +# Established two connections on behalf the users u1, u3; +# A connection on behalf the user u2 isn't established intentionally +connect con1, localhost, u1, , test; +connect con3, localhost, u3, , test; +connection default; +# In oracle compatibility mode, DROP USER fails in case +# there are connections on behalf the users being dropped. +DROP USER u1, u2, u3; +ERROR HY000: Operation DROP USER failed for 'u1'@'%','u3'@'%' +# It is expected to see two users in output of the query: u1 and u3, +# u2 should be dropped since it doesn't have active connection at the moment +SELECT User, Host FROM mysql.user WHERE user IN ('u1', 'u2', 'u3'); +User Host +u1 % +u3 % +SET sql_mode= @save_sql_mode; +disconnect con1; +disconnect con3; +# Clean up +# Clean up +DROP USER u1, u3; +CREATE USER u@localhost; +CREATE USER u@'%'; +connect u,localhost,u; +connection default; +DROP USER u@'%'; +disconnect u; +DROP USER u@localhost; +CREATE USER u@localhost; +SET sql_mode=oracle; +connect u,localhost,u; +connection default; +DROP USER u@'%'; +ERROR HY000: Operation DROP USER failed for 'u'@'%' +disconnect u; +connect u,localhost,u; +SELECT user(), current_user(); +user() current_user() +u@localhost u@localhost +disconnect u; +connection default; +# Clean up +DROP USER u@localhost; diff --git a/mysql-test/main/create_drop_user.test b/mysql-test/main/create_drop_user.test index 234383fb4ca06..eeefa63c1b455 100644 --- a/mysql-test/main/create_drop_user.test +++ b/mysql-test/main/create_drop_user.test @@ -44,3 +44,94 @@ DROP USER IF EXISTS u1, u2; --error ER_CANNOT_USER DROP USER u2; + +--echo # +--echo # MDEV-35617: DROP USER should leave no active session for that user +--echo # + +CREATE USER u1; +CREATE USER u2; +CREATE USER u3; + +GRANT ALL on test.* to u1; +GRANT ALL on test.* to u2; +GRANT ALL on test.* to u3; + +--echo # Establish two connections on behalf the users u1, u3 +--echo # A connection on behalf the user u2 isn't established intentionally +--connect (con1, localhost, u1, , test) +--connect (con3, localhost, u3, , test) + +--echo # Drop the users u1, u2, u3. Since the users u1 and u3 have active +--echo # connections to the server, the warning about it will be output +--connection default +DROP USER u1, u2, u3; + +--echo # None of the users u1, u2, u3 should be present in the system +SELECT User, Host FROM mysql.user WHERE user IN ('u1', 'u2', 'u3'); + +--disconnect con1 +--disconnect con3 + +--echo # Check behaviour of the DROP USER statement in +--echo # oracle compatibility mode +SET @save_sql_mode = @@sql_mode; +SET sql_mode="oracle"; +CREATE USER u1; +CREATE USER u2; +CREATE USER u3; + +GRANT ALL on test.* to u1; +GRANT ALL on test.* to u2; +GRANT ALL on test.* to u3; + +--echo # Established two connections on behalf the users u1, u3; +--echo # A connection on behalf the user u2 isn't established intentionally +--connect (con1, localhost, u1, , test) +--connect (con3, localhost, u3, , test) + +--connection default +--echo # In oracle compatibility mode, DROP USER fails in case +--echo # there are connections on behalf the users being dropped. +--error ER_CANNOT_USER +DROP USER u1, u2, u3; + +--echo # It is expected to see two users in output of the query: u1 and u3, +--echo # u2 should be dropped since it doesn't have active connection at the moment +SELECT User, Host FROM mysql.user WHERE user IN ('u1', 'u2', 'u3'); +SET sql_mode= @save_sql_mode; + +--disconnect con1 +--disconnect con3 +--echo # Clean up +--disable_warnings +--echo # Clean up +DROP USER u1, u3; +--enable_warnings + +CREATE USER u@localhost; +CREATE USER u@'%'; +--connect u,localhost,u +--connection default +DROP USER u@'%'; + +--disconnect u +--disable_warnings +DROP USER u@localhost; +--enable_warnings + +CREATE USER u@localhost; +SET sql_mode=oracle; +--connect u,localhost,u +--connection default +--error ER_CANNOT_USER +DROP USER u@'%'; +--disconnect u + +--connect u,localhost,u +SELECT user(), current_user(); + +--disconnect u +--connection default +--echo # Clean up +DROP USER u@localhost; diff --git a/mysql-test/main/create_or_replace.test b/mysql-test/main/create_or_replace.test index 05af75b61b73c..736713183ef1c 100644 --- a/mysql-test/main/create_or_replace.test +++ b/mysql-test/main/create_or_replace.test @@ -239,6 +239,7 @@ select LOCK_MODE,LOCK_TYPE, TABLE_SCHEMA,TABLE_NAME from information_schema.meta --error ER_DUP_FIELDNAME create or replace table test.t1 (a int) select 1 as 'a', 2 as 'a'; show tables; +--sorted_result select LOCK_MODE,LOCK_TYPE, TABLE_SCHEMA,TABLE_NAME from information_schema.metadata_lock_info; --sorted_result select LOCK_MODE,LOCK_TYPE, TABLE_SCHEMA,TABLE_NAME from information_schema.metadata_lock_info; diff --git a/mysql-test/main/create_or_replace_permission.result b/mysql-test/main/create_or_replace_permission.result index 1ea15d9621b16..8888fb04ed4ae 100644 --- a/mysql-test/main/create_or_replace_permission.result +++ b/mysql-test/main/create_or_replace_permission.result @@ -44,13 +44,10 @@ ERROR 42000: Access denied; you need (at least one of) the CREATE USER privilege CREATE OR REPLACE ROLE developer; ERROR 42000: Access denied; you need (at least one of) the CREATE USER privilege(s) for this operation connection default; +disconnect user_a; SELECT CURRENT_USER; CURRENT_USER root@localhost -REVOKE ALL ON db1.* FROM mysqltest_1@localhost; -DROP DATABASE IF EXISTS db2; -Warnings: -Note 1008 Can't drop database 'db2'; database doesn't exist DROP DATABASE db1; DROP USER mysqltest_1@localhost; set global sql_mode=default; diff --git a/mysql-test/main/create_or_replace_permission.test b/mysql-test/main/create_or_replace_permission.test index 0e833a125bd9e..66cd96bc6feed 100644 --- a/mysql-test/main/create_or_replace_permission.test +++ b/mysql-test/main/create_or_replace_permission.test @@ -61,11 +61,9 @@ CREATE OR REPLACE USER u1@localhost; CREATE OR REPLACE ROLE developer; connection default; +disconnect user_a; SELECT CURRENT_USER; -REVOKE ALL ON db1.* FROM mysqltest_1@localhost; -DROP DATABASE IF EXISTS db2; DROP DATABASE db1; DROP USER mysqltest_1@localhost; - set global sql_mode=default; diff --git a/mysql-test/main/create_or_replace_pfs.result b/mysql-test/main/create_or_replace_pfs.result new file mode 100644 index 0000000000000..24e40ea3b317d --- /dev/null +++ b/mysql-test/main/create_or_replace_pfs.result @@ -0,0 +1,27 @@ +# +# MDEV-23298 Assertion `table_list->prelocking_placeholder == +# TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on +# CREATE OR REPLACE TABLE +# +create table t2 (a int); +insert into t2 values(1),(2); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; +drop table t1; +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +SELECT * from t1; +q a +SELECT 1 1 +SELECT 1 2 +drop table t1; +CREATE TABLE t1 (a INT); +lock table t1 write,t2 read, sys.sys_config read; +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +unlock tables; +select * from t1; +q a +SELECT 1 1 +SELECT 1 2 +drop table t1,t2; +# End of 10.6 tests diff --git a/mysql-test/main/create_or_replace_pfs.test b/mysql-test/main/create_or_replace_pfs.test new file mode 100644 index 0000000000000..d7ad6d323365d --- /dev/null +++ b/mysql-test/main/create_or_replace_pfs.test @@ -0,0 +1,28 @@ +# +# Check CREATE OR REPLACE TABLE +# +--source include/have_perfschema.inc + +--echo # +--echo # MDEV-23298 Assertion `table_list->prelocking_placeholder == +--echo # TABLE_LIST::PRELOCK_NONE' failed in check_lock_and_start_stmt on +--echo # CREATE OR REPLACE TABLE +--echo # + +create table t2 (a int); +insert into t2 values(1),(2); +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q; +drop table t1; +CREATE TABLE t1 (a INT); +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +SELECT * from t1; +drop table t1; +CREATE TABLE t1 (a INT); +lock table t1 write,t2 read, sys.sys_config read; +CREATE OR REPLACE TABLE t1 AS SELECT sys.format_statement('SELECT 1') AS q, t2.a from t2; +unlock tables; +select * from t1; +drop table t1,t2; + +--echo # End of 10.6 tests diff --git a/mysql-test/main/create_select.result b/mysql-test/main/create_select.result index 2fe9bba9872e4..bd78e2193aa96 100644 --- a/mysql-test/main/create_select.result +++ b/mysql-test/main/create_select.result @@ -56,6 +56,22 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci WITH SYSTEM VERSIONING drop table t1; set sql_mode=default; -# # End of 10.4 tests # +# MDEV-37998 (Column) CHECK constraints can cause CREATE TABLE (SELECT) queries to fail +# +create table t1( +i int not null check(i > 0), +j int default (i+1), +primary key(i), +check (2*i>1) +); +create table t2 (select i as a,j from t1); +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) NOT NULL, + `j` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci +drop table t1, t2; +# End of 12.1 tests diff --git a/mysql-test/main/create_select.test b/mysql-test/main/create_select.test index d91f71133a0de..c464744390bd4 100644 --- a/mysql-test/main/create_select.test +++ b/mysql-test/main/create_select.test @@ -63,6 +63,19 @@ show create table t1; drop table t1; set sql_mode=default; ---echo # --echo # End of 10.4 tests + +--echo # +--echo # MDEV-37998 (Column) CHECK constraints can cause CREATE TABLE (SELECT) queries to fail --echo # +create table t1( + i int not null check(i > 0), + j int default (i+1), + primary key(i), + check (2*i>1) +); +create table t2 (select i as a,j from t1); +show create table t2; +drop table t1, t2; + +--echo # End of 12.1 tests diff --git a/mysql-test/main/create_w_max_indexes_128.result b/mysql-test/main/create_w_max_indexes_128.result index 112df1b7c4131..e54c27b827048 100644 --- a/mysql-test/main/create_w_max_indexes_128.result +++ b/mysql-test/main/create_w_max_indexes_128.result @@ -470,7 +470,7 @@ t1 CREATE TABLE `t1` ( KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci flush tables; show create table t1; Table Create Table @@ -619,7 +619,7 @@ t1 CREATE TABLE `t1` ( KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop table t1; create table t1 (c1 int, c2 int, c3 int, c4 int, c5 int, c6 int, c7 int, c8 int, c9 int, c10 int, c11 int, c12 int, c13 int, c14 int, c15 int, c16 int); @@ -1092,7 +1092,7 @@ t1 CREATE TABLE `t1` ( KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci flush tables; show create table t1; Table Create Table @@ -1241,7 +1241,7 @@ t1 CREATE TABLE `t1` ( KEY `a126_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a127_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`), KEY `a128_long_123456789_123456789_123456789_123456789_123456789_1234` (`c1`,`c2`,`c3`,`c4`,`c5`,`c6`,`c7`,`c8`,`c9`,`c10`,`c11`,`c12`,`c13`,`c14`,`c15`,`c16`) -) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci alter table t1 add key a129_long_123456789_123456789_123456789_123456789_123456789_1234 ( c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,c16); diff --git a/mysql-test/main/cte_grant.result b/mysql-test/main/cte_grant.result index 7a982fcee9af6..c88fca86454bb 100644 --- a/mysql-test/main/cte_grant.result +++ b/mysql-test/main/cte_grant.result @@ -60,7 +60,7 @@ c d 1 30 1 30 connection root; -revoke all privileges on mysqltest.v1 from mysqltest_1@localhost; +disconnect user1; drop user mysqltest_1@localhost; drop database mysqltest; # diff --git a/mysql-test/main/cte_grant.test b/mysql-test/main/cte_grant.test index 3e6d50095693d..c9330de7a1960 100644 --- a/mysql-test/main/cte_grant.test +++ b/mysql-test/main/cte_grant.test @@ -1,16 +1,10 @@ # Can't test with embedded server -- source include/not_embedded.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (root,localhost,root,,test); connection root; ---disable_warnings create database mysqltest; ---enable_warnings - create user mysqltest_1@localhost; connect (user1,localhost,mysqltest_1,,"*NO-ONE*"); connection user1; @@ -74,7 +68,7 @@ connection user1; select * from mysqltest.v3; connection root; -revoke all privileges on mysqltest.v1 from mysqltest_1@localhost; +disconnect user1; drop user mysqltest_1@localhost; drop database mysqltest; diff --git a/mysql-test/main/cte_nonrecursive.result b/mysql-test/main/cte_nonrecursive.result index 3ac342fb560ca..992c218a10eed 100644 --- a/mysql-test/main/cte_nonrecursive.result +++ b/mysql-test/main/cte_nonrecursive.result @@ -1676,6 +1676,7 @@ use test; # THD::create_tmp_table_def_key # connect con1,localhost,root,,; +change_user root,,; CREATE TEMPORARY TABLE test.t (a INT); WITH cte AS (SELECT 1) SELECT * FROM cte; 1 diff --git a/mysql-test/main/cte_recursive.result b/mysql-test/main/cte_recursive.result index 42c77be5ca296..4bb99195e983d 100644 --- a/mysql-test/main/cte_recursive.result +++ b/mysql-test/main/cte_recursive.result @@ -6052,3 +6052,188 @@ b rank() over (order by c) drop view v1; drop table t1; # End of 10.4 tests +# +# MDEV-32308: Server crash on cleanup of +# non-fully-constructed-due-to-an-error CTE +# +SELECT ( WITH RECURSIVE x AS ( WITH x AS ( SELECT 1 FROM t14 ) SELECT x ) , t14 AS ( SELECT 1 UNION SELECT 'x' FROM x ) SELECT x FROM x WHERE ( SELECT x FROM x ) ) ; +ERROR 42S22: Unknown column 'x' in 'SELECT' +# +# MDEV-32299 Segfault when preparing unreferenced select in recursive CTE +# +SELECT ( WITH RECURSIVE x AS ( SELECT * FROM ( SELECT UTC_TIMESTAMP FROM ( SELECT ( WITH x AS ( WITH x AS ( SELECT * FROM x ) SELECT 1 ) SELECT 1 ) ) x ) x UNION SELECT NULL ) ( SELECT x FROM x ) ) ; +ERROR 42S22: Unknown column 'x' in 'SELECT' +select ( +with recursive x as ( +select * from ( +select utc_timestamp +from ( +select ( +with x as ( +with x as ( +select * from x +) +select 1 +) +select 1 +) s +) y +) z +union +select null +) +(select x from x) +); +ERROR 42S22: Unknown column 'x' in 'SELECT' +select ( +with recursive r as ( +select * from ( +with a as ( +select * from r +) +select 1 +) y +union +select 1 +) +(select * from r) +); +( +with recursive r as ( +select * from ( +with a as ( +select * from r +) +select 1 +) y +union +select 1 +) +(select * from r) +) +1 +create table t1 (x int); +with recursive r as ( +select f1 from ( +with a as ( +select x from t1 +) +select 1 as f1 +) y +union +select null +) +(select * from r); +f1 +1 +NULL +with recursive r as ( +select f1 from ( +with a as ( +select f2 from t1 +) +select 1 as f1 +) y +union +select null +) +(select * from r); +ERROR 42S22: Unknown column 'f2' in 'SELECT' +drop table t1; +with recursive r as ( +select 1 as f1 +union +select f1 from ( +with a as ( +select f1 from r +) +select 1 as f1 +) y +) +(select f1 from r); +f1 +1 +with recursive r as ( +select 1 as f1 +union +select f1 from ( +with a as ( +select f2 from r +) +select 1 as f1 +) y +) +(select f1 from r); +ERROR 42S22: Unknown column 'f2' in 'SELECT' +# End of 10.6 tests +# +# MDEV-32724 Segmentation fault due to Deep Recursion in table.cc and sql_lex.cc +# +with recursive r (y) as ( +with r (z) as (select 1 from r) select 1 from r +union all +select y from r) +select y from r; +ERROR HY000: No anchors for recursive WITH element 'r' +# r2 CTE is the anchor for r (original behavior): +with recursive r (y) as ( +with recursive r2 (z) as ( +select z + 1 from r2 where z < 2 +union all +select 1) +select z from r2 +union all +select y * 2 from r where y < 10) +select y from r; +y +1 +2 +2 +4 +4 +8 +8 +16 +16 +# It is different with the name clash, +# select y * 2 from r is attached to inner r: +with recursive r (y) as ( +with recursive r (z) as ( +select z + 1 from r where z < 2 +union all +select 1) +select z from r +union all +select y * 2 from r where y < 10) +select y from r; +ERROR 42S22: Unknown column 'y' in 'SELECT' +# The whole set of SELECTs is attached to CTE: +with recursive r (z) as ( +select z + 1 from r where z < 2 +union all +select 1) +select z from r +union all +select z * 2 from r where z < 10; +z +1 +2 +2 +4 +# In this case no outer recursion can occur as every r +# is taken by the inner recursive CTE: +with recursive r (y) as ( +with recursive r (z) as ( +select z + 1 from r where z < 2 +union all +select 1) +select z from r +union all +select z * 2 from r where z < 10) +select y from r; +y +1 +2 +2 +4 +# End of 10.11 tests diff --git a/mysql-test/main/cte_recursive.test b/mysql-test/main/cte_recursive.test index f3e6cd78a5449..5f10d92b5cc5c 100644 --- a/mysql-test/main/cte_recursive.test +++ b/mysql-test/main/cte_recursive.test @@ -3,6 +3,8 @@ --source include/no_msan_without_big.inc --source include/not_valgrind.inc --source include/have_innodb.inc +# --view-protocol fails due to MDEV-37119 for MDEV-32299 +--source include/no_view_protocol.inc create table t1 (a int, b varchar(32)); insert into t1 values @@ -4058,3 +4060,186 @@ drop view v1; drop table t1; --echo # End of 10.4 tests + +--echo # +--echo # MDEV-32308: Server crash on cleanup of +--echo # non-fully-constructed-due-to-an-error CTE +--echo # +--error ER_BAD_FIELD_ERROR +SELECT ( WITH RECURSIVE x AS ( WITH x AS ( SELECT 1 FROM t14 ) SELECT x ) , t14 AS ( SELECT 1 UNION SELECT 'x' FROM x ) SELECT x FROM x WHERE ( SELECT x FROM x ) ) ; + +--echo # +--echo # MDEV-32299 Segfault when preparing unreferenced select in recursive CTE +--echo # + +# As in bug report +--error ER_BAD_FIELD_ERROR +SELECT ( WITH RECURSIVE x AS ( SELECT * FROM ( SELECT UTC_TIMESTAMP FROM ( SELECT ( WITH x AS ( WITH x AS ( SELECT * FROM x ) SELECT 1 ) SELECT 1 ) ) x ) x UNION SELECT NULL ) ( SELECT x FROM x ) ) ; + +#0 0x00005555569dff7b in TABLE_LIST::reset_const_table (this=0x7fffe0019938) at ../src/sql/table.cc:9615 +#1 0x00005555569dffd4 in TABLE_LIST::reset_const_table (this=0x7fffe001a8c0) at ../src/sql/table.cc:9622 +--error ER_BAD_FIELD_ERROR +select ( + with recursive x as ( + select * from ( + select utc_timestamp + from ( + select ( + with x as ( + with x as ( + select * from x + ) + select 1 + ) + select 1 + ) s + ) y + ) z + + union + + select null + ) + (select x from x) +); + +#6 0x00007ffff7639206 in __assert_fail (assertion=0x555555e121b6 "table_ref->table || table_ref->view", file=0x555555cdf138 "../src/sql/table.cc", line=7305, function=0x555555e30e24 "void Field_iterator_table_ref::set_field_iterator()") at ./assert/assert.c:101 +#7 0x00005555569da013 in Field_iterator_table_ref::set_field_iterator (this=0x7ffff0a9afc0) at ../src/sql/table.cc:7305 +select ( + with recursive r as ( + select * from ( + with a as ( + select * from r + ) + select 1 + ) y + + union + + select 1 + ) + (select * from r) +); + +# Field resolution in unreferenced: +create table t1 (x int); + +with recursive r as ( + select f1 from ( + with a as ( + select x from t1 + ) + select 1 as f1 + ) y + + union + + select null +) +(select * from r); + +--error ER_BAD_FIELD_ERROR +with recursive r as ( + select f1 from ( + with a as ( + select f2 from t1 + ) + select 1 as f1 + ) y + + union + + select null +) +(select * from r); + +drop table t1; + +with recursive r as ( + select 1 as f1 + + union + + select f1 from ( + with a as ( + select f1 from r + ) + select 1 as f1 + ) y +) +(select f1 from r); + +--error ER_BAD_FIELD_ERROR +with recursive r as ( + select 1 as f1 + + union + + select f1 from ( + with a as ( + select f2 from r + ) + select 1 as f1 + ) y +) +(select f1 from r); + + +--echo # End of 10.6 tests + +--echo # +--echo # MDEV-32724 Segmentation fault due to Deep Recursion in table.cc and sql_lex.cc +--echo # +--error ER_RECURSIVE_WITHOUT_ANCHORS +with recursive r (y) as ( + with r (z) as (select 1 from r) select 1 from r + union all + select y from r) +select y from r; + +--echo # r2 CTE is the anchor for r (original behavior): +with recursive r (y) as ( + with recursive r2 (z) as ( + select z + 1 from r2 where z < 2 + union all + select 1) + select z from r2 + union all + select y * 2 from r where y < 10) +select y from r; + +--echo # It is different with the name clash, +--echo # select y * 2 from r is attached to inner r: +--error ER_BAD_FIELD_ERROR +with recursive r (y) as ( + with recursive r (z) as ( + select z + 1 from r where z < 2 + union all + select 1) + select z from r + union all + select y * 2 from r where y < 10) +select y from r; + +--echo # The whole set of SELECTs is attached to CTE: +with recursive r (z) as ( + select z + 1 from r where z < 2 + union all + select 1) +select z from r +union all +select z * 2 from r where z < 10; + +--echo # In this case no outer recursion can occur as every r +--echo # is taken by the inner recursive CTE: +with recursive r (y) as ( + with recursive r (z) as ( + select z + 1 from r where z < 2 + union all + select 1) + select z from r + union all + select z * 2 from r where z < 10) +select y from r; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/cte_update_delete.result b/mysql-test/main/cte_update_delete.result new file mode 100644 index 0000000000000..6cda90fb9e2cd --- /dev/null +++ b/mysql-test/main/cte_update_delete.result @@ -0,0 +1,1378 @@ +# +# MDEV-37220 Allow UPDATE/DELETE to read from a CTE +# +create table t1 +( +a int not null, +b int, +c int, +d int, +amount decimal, +key t1_ix1 (a,b) +); +insert into t1 values (0, NULL, 0, NULL, 10.0000), (1, 1, 1, 1, 10.0000), +(2, 2, 2, 2, 20.0000), (3, 3, 3, 3, 30.0000), (4, 4, 4, 4, 40.0000), +(5, 5, 5, 5, NULL), (6, 6, 6, 6, NULL), (7, 7, 7, 7, 70.0000), +(8, 8, 8, 8, 80.0000); +create table t2 +( +a int NOT NULL, +b int, +name varchar(50), +key t2_ix1 (a,b) +); +insert into t2 values (0, NULL, 'a'), (1, NULL, 'A'), (2, 2, 'B'), (3,3, 'C'), +(4,4, 'D'), (5,5, NULL), (6,6, NULL), (7,7, 'E'), (8,8, 'F'), (9,9, 'G'), +(10,10,'H'), (11,11, NULL), (12,12, NULL); +create table t3 +( +a int, +b int, +description varchar(50) +); +create table t4 as select * from t1; +create table t5 as select * from t2; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +select * from t3; +a b description +1 1 iron +2 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +# update, single table syntax, subq in set +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte where b in (select b from cte2) and d = t3.a); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 +4 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using where +4 DEPENDENT SUBQUERY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte where b in (select b from cte2) and d = t3.a); +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte where b in (select b from cte2) and d = t3.a); +call p(); +drop procedure p; +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte where b in (select b from cte2) and d = t3.a)'; +execute s; +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +# update, single table syntax, subq in set, cte used twice +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte +where +(b in (select b from cte2 where cte2.a = cte.a) or +b in (select b from cte2 where cte2.b = cte.a)) and +d = t3.a +); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 +4 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using where +6 DEPENDENT SUBQUERY t2 index t2_ix1 t2_ix1 9 NULL 13 Using where; Using index +5 DEPENDENT SUBQUERY t2 ref t2_ix1 t2_ix1 9 test.t1.a,func 1 Using where; Using index +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte +where +(b in (select b from cte2 where cte2.a = cte.a) or +b in (select b from cte2 where cte2.b = cte.a)) and +d = t3.a +); +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte +where +(b in (select b from cte2 where cte2.a = cte.a) or +b in (select b from cte2 where cte2.b = cte.a)) and +d = t3.a +); +call p(); +drop procedure p; +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 +set t3.a = (select a from cte +where +(b in (select b from cte2 where cte2.a = cte.a) or +b in (select b from cte2 where cte2.b = cte.a)) and +d = t3.a +)'; +execute s; +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +NULL 1 iron +2 2 wood +NULL NULL gold +NULL 3 silver +NULL 4 lead +NULL 5 tin +NULL 6 platinum +NULL 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +# multi table syntax, subq in set and where +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3,cte +set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 5 test.t3.a 1 Using where +1 PRIMARY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch() +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3,cte +set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3,cte +set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +# multi table syntax, subq in set and where, more complex CTEs +explain with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +update t3,cte, t4 +set t3.a = cte.a+1, t4.a = cte.a+2 +where cte.b in (select b from cte2) and cte.d = t3.a and cte.b = t4.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 5 test.t3.a 8 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 FirstMatch() +1 PRIMARY t4 ALL NULL NULL NULL NULL 9 Using where +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where +3 DERIVED t5 ALL NULL NULL NULL NULL 13 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +2 DERIVED t4 ALL NULL NULL NULL NULL 9 Using where; Using join buffer (flat, BNL join) +with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +update t3,cte, t4 +set t3.a = cte.a+1, t4.a = cte.a+2 +where cte.b in (select b from cte2) and cte.d = t3.a and cte.b = t4.a; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +select * from t4; +a b c d amount +0 NULL 0 NULL 10 +1 1 1 1 10 +4 2 2 2 20 +3 3 3 3 30 +4 4 4 4 40 +5 5 5 5 NULL +6 6 6 6 NULL +7 7 7 7 70 +8 8 8 8 80 +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop table t4; +create table t4 as select * from t1; +create procedure p() with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +update t3,cte, t4 +set t3.a = cte.a+1, t4.a = cte.a+2 +where cte.b in (select b from cte2) and cte.d = t3.a and cte.b = t4.a; +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +select * from t4; +a b c d amount +0 NULL 0 NULL 10 +1 1 1 1 10 +4 2 2 2 20 +3 3 3 3 30 +4 4 4 4 40 +5 5 5 5 NULL +6 6 6 6 NULL +7 7 7 7 70 +8 8 8 8 80 +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop table t4; +create table t4 as select * from t1; +prepare s from 'with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +update t3,cte, t4 +set t3.a = cte.a+1, t4.a = cte.a+2 +where cte.b in (select b from cte2) and cte.d = t3.a and cte.b = t4.a'; +execute s; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +select * from t4; +a b c d amount +0 NULL 0 NULL 10 +1 1 1 1 10 +4 2 2 2 20 +3 3 3 3 30 +4 4 4 4 40 +5 5 5 5 NULL +6 6 6 6 NULL +7 7 7 7 70 +8 8 8 8 80 +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop table t4; +create table t4 as select * from t1; +execute s; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +select * from t4; +a b c d amount +0 NULL 0 NULL 10 +1 1 1 1 10 +4 2 2 2 20 +3 3 3 3 30 +4 4 4 4 40 +5 5 5 5 NULL +6 6 6 6 NULL +7 7 7 7 70 +8 8 8 8 80 +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +drop table t4; +create table t4 as select * from t1; +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 left join cte on t3.b = cte.b +set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 10 test.t3.b,test.t3.a 1 +1 PRIMARY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch() +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3 left join cte on t3.b = cte.b +set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +select * from t3; +a b description +1 1 iron +3 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3, cte, cte2 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 5 test.t3.a 1 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update t3, cte, cte2 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +select * from t3; +a b description +1 1 iron +4 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key1 key1 5 test.t3.a 1 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +select * from t3; +a b description +1 1 iron +4 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +explain with cte as (select * from t1 where c < 5 group by a), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key1 key1 5 test.t3.a 1 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where; Using temporary; Using filesort +with cte as (select * from t1 where c < 5 group by a), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +select * from t3; +a b description +1 1 iron +4 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create view v1 as select * from t1; +explain with cte as (select * from v1 where c < 5 group by a), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key1 key1 5 test.t3.a 1 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where; Using temporary; Using filesort +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where; Using temporary; Using filesort +with cte as (select * from v1 where c < 5 group by a), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +select * from t3; +a b description +1 1 iron +4 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +with T as (select * from t1) update T set T.a=3; +ERROR HY000: The target table T of the UPDATE is not updatable +with T as (select * from v1) update T set T.a=3; +ERROR HY000: The target table T of the UPDATE is not updatable +with T as (select * from t1) delete from T where a=3; +ERROR HY000: The target table T of the DELETE is not updatable +with T as (select * from v1) delete from T where a=3; +ERROR HY000: The target table T of the DELETE is not updatable +drop view v1; +create view v1 as select * from t1 where b IS NOT NULL limit 1; +explain with cte as (select * from v1 where c < 5 group by a), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 5 test.t3.a 1 +1 PRIMARY ALL NULL NULL NULL NULL 13 +2 DERIVED ALL NULL NULL NULL NULL 2 Using where; Using temporary; Using filesort +4 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where; Using temporary; Using filesort +with cte as (select * from v1 where c < 5 group by a), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where d = t3.a; +select * from t3; +a b description +3 1 iron +2 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop view v1; +CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; +CREATE TABLE tf (f1 DATE); +INSERT INTO tf VALUES('2001-01-01'); +explain with cte as (select f1 as a, f1() as b, 2 as d from tf), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY system NULL NULL NULL NULL 1 +1 PRIMARY ref key0 key0 5 const 1 Using where +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +2 DERIVED tf system NULL NULL NULL NULL 1 +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where; Using temporary; Using filesort +with cte as (select f1 as a, f1() as b, 2 as d from tf), +cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +select * from t3; +a b description +1 1 iron +2 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop function f1; +drop table tf; +# delete single table syntax +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +where t3.a = (select a from cte where b in (select b from cte2)); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +4 SUBQUERY t1 ALL NULL NULL NULL NULL 9 Using where +4 SUBQUERY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch(t1); Using join buffer (flat, BNL join) +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +where t3.a = (select a from cte where b in (select b from cte2)); +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +where t3.a = (select a from cte where b in (select b from cte2)); +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +# delete multi table syntax +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 4 test.t3.a 1 Using where +1 PRIMARY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch() +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2); +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2); +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +# delete multi table syntax, multi table delete +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3, t4 +using t3, t4, cte +where t3.a = cte.a and cte.b in (select b from cte2) +and t4.a = t3.a; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 4 test.t3.a 1 Using where +1 PRIMARY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch() +1 PRIMARY t4 ALL NULL NULL NULL NULL 9 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3, t4 +using t3, t4, cte +where t3.a = cte.a and cte.b in (select b from cte2) +and t4.a = t3.a; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +select * from t4; +a b c d amount +0 NULL 0 NULL 10 +1 1 1 1 10 +3 3 3 3 30 +4 4 4 4 40 +5 5 5 5 NULL +6 6 6 6 NULL +7 7 7 7 70 +8 8 8 8 80 +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3, t4 +using t3, t4, cte +where t3.a = cte.a and cte.b in (select b from cte2) +and t4.a = t3.a; +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +2 2 wood +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +# delete multi table syntax, multi table CTEs +explain with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 4 test.t3.a 8 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 FirstMatch() +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where +3 DERIVED t5 ALL NULL NULL NULL NULL 13 Using where; Using join buffer (flat, BNL join) +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +2 DERIVED t4 ALL NULL NULL NULL NULL 8 Using where; Using join buffer (flat, BNL join) +with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2); +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2); +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), +cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2)'; +execute s; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +# delete multi table syntax, limit clause in delete +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2) limit 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 4 test.t3.a 1 Using where +1 PRIMARY t2 index NULL t2_ix1 9 NULL 13 Using where; Using index; FirstMatch() +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2) limit 1; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2) limit 1; +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte +where t3.a = cte.a and cte.b in (select b from cte2) limit 1'; +execute s; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +explain with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte, cte2 +where t3.a = cte.a and cte.b = cte2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key0 key0 4 test.t3.a 1 Using where +1 PRIMARY ref key0 key0 5 cte.b 1 +2 DERIVED t1 ALL NULL NULL NULL NULL 9 Using where +3 DERIVED t2 ALL NULL NULL NULL NULL 13 Using where +with cte as (select * from t1 where c < 5), +cte2 as (select * from t2 where b < 3) +delete from t3 +using t3, cte, cte2 +where t3.a = cte.a and cte.b = cte2.b; +select * from t3; +a b description +1 1 iron +0 NULL gold +3 3 silver +4 4 lead +5 5 tin +6 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +# recursive CTE, test update on values 1 (NC), 2, 5, 6 from CTE +explain with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +update t3, cte_r +set t3.a = 1 +where t3.b = c; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key1,distinct_key key1 5 test.t3.b 1 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +4 RECURSIVE UNION t1 index t1_ix1 t1_ix1 9 NULL 9 Using index +4 RECURSIVE UNION ref key0 key0 5 test.t1.a 1 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +update t3, cte_r +set t3.a = 1 +where t3.b = c; +select * from t3; +a b description +1 1 iron +1 2 wood +0 NULL gold +3 3 silver +4 4 lead +1 5 tin +1 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +update t3, cte_r +set t3.a = 1 +where t3.b = c; +call p(); +drop procedure p; +select * from t3; +a b description +1 1 iron +1 2 wood +0 NULL gold +3 3 silver +4 4 lead +1 5 tin +1 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +update t3, cte_r +set t3.a = 1 +where t3.b = c'; +execute s; +select * from t3; +a b description +1 1 iron +1 2 wood +0 NULL gold +3 3 silver +4 4 lead +1 5 tin +1 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +1 1 iron +1 2 wood +0 NULL gold +3 3 silver +4 4 lead +1 5 tin +1 6 platinum +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +# recursive CTE, test delete, multi table syntax +explain with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +delete from t3 +using t3, cte_r +where t3.b = c; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key1,distinct_key key1 5 test.t3.b 1 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +4 RECURSIVE UNION t1 index t1_ix1 t1_ix1 9 NULL 9 Using index +4 RECURSIVE UNION ref key0 key0 5 test.t1.a 1 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +delete from t3 +using t3, cte_r +where t3.b = c; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +delete from t3 +using t3, cte_r +where t3.b = c; +call p(); +drop procedure p; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +) +delete from t3 +using t3, cte_r +where t3.b = c'; +execute s; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +# recursive CTE, test delete, single table syntax +explain with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +), +cte (a) as +( +select a from t2 +) +delete from t3 +where t3.b in (select c from cte_r, cte where cte.a = cte_r.a ); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t3 ALL NULL NULL NULL NULL 8 Using where +1 PRIMARY ref key1,distinct_key key1 5 test.t3.b 1 Using where +1 PRIMARY t2 ref t2_ix1 t2_ix1 4 cte_r.a 2 Using index; FirstMatch(t3) +2 DERIVED NULL NULL NULL NULL NULL NULL NULL No tables used +3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +4 RECURSIVE UNION t1 index t1_ix1 t1_ix1 9 NULL 9 Using index +4 RECURSIVE UNION ref key0 key0 5 test.t1.a 1 +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +), +cte (a) as +( +select a from t2 +) +delete from t3 +where t3.b in (select c from cte_r, cte where cte.a = cte_r.a ); +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +create procedure p() with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +), +cte (a) as +( +select a from t2 +) +delete from t3 +where t3.b in (select c from cte_r, cte where cte.a = cte_r.a ); +call p(); +drop procedure p; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +prepare s from 'with recursive cte_r(a, c) as +( +values (1,5) +union +values (2,6) +union +select t1.a, t1.b +from t1, cte_r +where t1.a = cte_r.a +), +cte (a) as +( +select a from t2 +) +delete from t3 +where t3.b in (select c from cte_r, cte where cte.a = cte_r.a )'; +execute s; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +execute s; +select * from t3; +a b description +0 NULL gold +3 3 silver +4 4 lead +7 7 aluminium +truncate t3; +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); +drop prepare s; +# +# MDEV-38258 No error thrown when CTE columns updated in updates set clause +# +with cte as (select * from t1 where c < 1) +update cte set cte.a =(select a from cte); +ERROR HY000: The target table cte of the UPDATE is not updatable +with cte as (select a from t1) +update cte set cte.a=(select a from cte limit 1); +ERROR HY000: The target table cte of the UPDATE is not updatable +with cte as (select a from t1), +cte2 as (select a from t3) +update t2, cte set cte.a=(select a from cte limit 1); +ERROR HY000: The target table cte of the UPDATE is not updatable +with cte as (select a from t1), +cte2 as (select a from t3) +update cte +set cte.a=(select a from cte where cte.a in (select a from cte2) limit 1); +ERROR HY000: The target table cte of the UPDATE is not updatable +drop table t1, t2, t3, t4, t5; +# +# MDEV-38272 Sig11 in LEX::resolve_references_to_cte at sql/sql_cte.cc +# +create table t1(a int); +insert into t1 values (1), (5), (10), (15), (20), (25); +create view v1 as select * from t1 where a < 10; +with cte as (select * from t1) delete from t1,cte where t1.a=cte.a; +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 'where t1.a=cte.a' at line 1 +with cte as (select * from t1) delete from t1 using t1,cte where t1.a=cte.a; +# +# MDEV-38272 Recursive CTE usage leaks memory when not used in a top level select +# +with recursive cte as (select a from t1 union select a from cte) +update t1, cte set t1.o = 1; +ERROR 42S22: Unknown column 't1.o' in 'SET' +with recursive cte as (select a from t1 union select a from cte where a < 2) +delete from cte where a = (select a from cte); +ERROR HY000: The target table cte of the DELETE is not updatable +with recursive cte as (select a from t1 union select a from cte where a < 2) +delete from cte where a = 10; +ERROR HY000: The target table cte of the DELETE is not updatable +insert into t1 values (1), (5), (10), (15), (20), (25); +with recursive cte as (select a from t1 union select a from cte where a < 2) +delete from v1 using v1, cte where v1.a = cte.a; +select * from t1 order by 1; +a +10 +15 +20 +25 +drop table t1; +# End of 12.2 tests diff --git a/mysql-test/main/cte_update_delete.test b/mysql-test/main/cte_update_delete.test new file mode 100644 index 0000000000000..8ec964153c489 --- /dev/null +++ b/mysql-test/main/cte_update_delete.test @@ -0,0 +1,598 @@ +--source include/not_embedded.inc +--echo # +--echo # MDEV-37220 Allow UPDATE/DELETE to read from a CTE +--echo # + +create table t1 +( + a int not null, + b int, + c int, + d int, + amount decimal, + key t1_ix1 (a,b) +); + +insert into t1 values (0, NULL, 0, NULL, 10.0000), (1, 1, 1, 1, 10.0000), +(2, 2, 2, 2, 20.0000), (3, 3, 3, 3, 30.0000), (4, 4, 4, 4, 40.0000), +(5, 5, 5, 5, NULL), (6, 6, 6, 6, NULL), (7, 7, 7, 7, 70.0000), +(8, 8, 8, 8, 80.0000); + +create table t2 +( + a int NOT NULL, + b int, + name varchar(50), + key t2_ix1 (a,b) +); + +insert into t2 values (0, NULL, 'a'), (1, NULL, 'A'), (2, 2, 'B'), (3,3, 'C'), +(4,4, 'D'), (5,5, NULL), (6,6, NULL), (7,7, 'E'), (8,8, 'F'), (9,9, 'G'), +(10,10,'H'), (11,11, NULL), (12,12, NULL); + +create table t3 +( + a int, + b int, + description varchar(50) +); + +let $empty_t3= +truncate t3; +let $fill_t3= +insert into t3 values (1, 1, 'iron'),(2,2,'wood'),(0,NULL, 'gold'), +(3, 3, 'silver'), (4, 4, 'lead'), (5, 5, 'tin'), (6, 6, 'platinum'), +(7, 7, 'aluminium'); + +create table t4 as select * from t1; +create table t5 as select * from t2; + +eval $fill_t3; + +select * from t3; + +--echo # update, single table syntax, subq in set +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +update t3 + set t3.a = (select a from cte where b in (select b from cte2) and d = t3.a); +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +--echo # update, single table syntax, subq in set, cte used twice +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +update t3 + set t3.a = (select a from cte + where + (b in (select b from cte2 where cte2.a = cte.a) or + b in (select b from cte2 where cte2.b = cte.a)) and + d = t3.a + ); +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +--echo # multi table syntax, subq in set and where +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +update t3,cte + set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +--echo # multi table syntax, subq in set and where, more complex CTEs +let $q= +with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), + cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +update t3,cte, t4 + set t3.a = cte.a+1, t4.a = cte.a+2 + where cte.b in (select b from cte2) and cte.d = t3.a and cte.b = t4.a; +eval explain $q; +eval $q; +select * from t3; +select * from t4; +eval $empty_t3; +eval $fill_t3; +drop table t4; +create table t4 as select * from t1; + +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +select * from t4; +eval $empty_t3; +eval $fill_t3; +drop table t4; +create table t4 as select * from t1; +eval prepare s from '$q'; +execute s; +select * from t3; +select * from t4; +eval $empty_t3; +eval $fill_t3; +drop table t4; +create table t4 as select * from t1; +execute s; +select * from t3; +select * from t4; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +drop table t4; +create table t4 as select * from t1; + +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +update t3 left join cte on t3.b = cte.b + set t3.a = cte.a+1 where cte.b in (select b from cte2) and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +update t3, cte, cte2 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +let $q= +with cte as (select * from t1 where c < 5 group by a), + cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +create view v1 as select * from t1; +let $q= +with cte as (select * from v1 where c < 5 group by a), + cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +--error 1288 +with T as (select * from t1) update T set T.a=3; + +--error 1288 +with T as (select * from v1) update T set T.a=3; + +--error 1288 +with T as (select * from t1) delete from T where a=3; + +--error 1288 +with T as (select * from v1) delete from T where a=3; + +drop view v1; + +create view v1 as select * from t1 where b IS NOT NULL limit 1; +let $q= +with cte as (select * from v1 where c < 5 group by a), + cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop view v1; + +CREATE FUNCTION f1 () RETURNS BLOB RETURN 1; +CREATE TABLE tf (f1 DATE); +INSERT INTO tf VALUES('2001-01-01'); +let $q= +with cte as (select f1 as a, f1() as b, 2 as d from tf), + cte2 as (select * from t2 where b < 3 group by a) +update cte, cte2, t3 set t3.a = cte.a+2 where cte.b = cte2.b and d = t3.a; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop function f1; +drop table tf; + +--echo # delete single table syntax +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +delete from t3 + where t3.a = (select a from cte where b in (select b from cte2)); + +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; + + +--echo # delete multi table syntax +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +delete from t3 + using t3, cte + where t3.a = cte.a and cte.b in (select b from cte2); +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +--echo # delete multi table syntax, multi table delete +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +delete from t3, t4 + using t3, t4, cte + where t3.a = cte.a and cte.b in (select b from cte2) + and t4.a = t3.a; +eval explain $q; +eval $q; +select * from t3; +select * from t4; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +--echo # delete multi table syntax, multi table CTEs +let $q= +with cte as (select t1.* from t1 left join t4 on t1.d = t4.d where t1.c < 5), + cte2 as (select t2.* from t2, t5 where t2.b < 3 and t2.name = t5.name limit 1) +delete from t3 + using t3, cte + where t3.a = cte.a and cte.b in (select b from cte2); +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + + + +--echo # delete multi table syntax, limit clause in delete +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +delete from t3 + using t3, cte + where t3.a = cte.a and cte.b in (select b from cte2) limit 1; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +let $q= +with cte as (select * from t1 where c < 5), + cte2 as (select * from t2 where b < 3) +delete from t3 + using t3, cte, cte2 + where t3.a = cte.a and cte.b = cte2.b; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; + +--echo # recursive CTE, test update on values 1 (NC), 2, 5, 6 from CTE +let $q= +with recursive cte_r(a, c) as + ( + values (1,5) + union + values (2,6) + union + select t1.a, t1.b + from t1, cte_r + where t1.a = cte_r.a + ) +update t3, cte_r + set t3.a = 1 + where t3.b = c; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +--echo # recursive CTE, test delete, multi table syntax +let $q= +with recursive cte_r(a, c) as + ( + values (1,5) + union + values (2,6) + union + select t1.a, t1.b + from t1, cte_r + where t1.a = cte_r.a + ) +delete from t3 + using t3, cte_r + where t3.b = c; +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +--echo # recursive CTE, test delete, single table syntax +let $q= +with recursive cte_r(a, c) as + ( + values (1,5) + union + values (2,6) + union + select t1.a, t1.b + from t1, cte_r + where t1.a = cte_r.a + ), + cte (a) as + ( + select a from t2 + ) +delete from t3 + where t3.b in (select c from cte_r, cte where cte.a = cte_r.a ); +eval explain $q; +eval $q; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval create procedure p() $q; +call p(); +drop procedure p; +select * from t3; +eval $empty_t3; +eval $fill_t3; +eval prepare s from '$q'; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +execute s; +select * from t3; +eval $empty_t3; +eval $fill_t3; +drop prepare s; + +--echo # +--echo # MDEV-38258 No error thrown when CTE columns updated in updates set clause +--echo # + +--error ER_NON_UPDATABLE_TABLE +with cte as (select * from t1 where c < 1) + update cte set cte.a =(select a from cte); + +--error ER_NON_UPDATABLE_TABLE +with cte as (select a from t1) + update cte set cte.a=(select a from cte limit 1); + +--error ER_NON_UPDATABLE_TABLE +with cte as (select a from t1), + cte2 as (select a from t3) + update t2, cte set cte.a=(select a from cte limit 1); + +--error ER_NON_UPDATABLE_TABLE +with cte as (select a from t1), + cte2 as (select a from t3) + update cte + set cte.a=(select a from cte where cte.a in (select a from cte2) limit 1); + +drop table t1, t2, t3, t4, t5; + +--echo # +--echo # MDEV-38272 Sig11 in LEX::resolve_references_to_cte at sql/sql_cte.cc +--echo # + +create table t1(a int); +insert into t1 values (1), (5), (10), (15), (20), (25); +create view v1 as select * from t1 where a < 10; +--error ER_PARSE_ERROR +with cte as (select * from t1) delete from t1,cte where t1.a=cte.a; +with cte as (select * from t1) delete from t1 using t1,cte where t1.a=cte.a; + +--echo # +--echo # MDEV-38272 Recursive CTE usage leaks memory when not used in a top level select +--echo # + +--error ER_BAD_FIELD_ERROR +with recursive cte as (select a from t1 union select a from cte) + update t1, cte set t1.o = 1; + +let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; +--write_line wait $restart_file +--shutdown_server +--source include/wait_until_disconnected.inc +--write_line "restart: " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc + +--error ER_NON_UPDATABLE_TABLE +with recursive cte as (select a from t1 union select a from cte where a < 2) + delete from cte where a = (select a from cte); + +let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; +--write_line wait $restart_file +--shutdown_server +--source include/wait_until_disconnected.inc +--write_line "restart: " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc + +--error ER_NON_UPDATABLE_TABLE +with recursive cte as (select a from t1 union select a from cte where a < 2) + delete from cte where a = 10; + +let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; +--write_line wait $restart_file +--shutdown_server +--source include/wait_until_disconnected.inc +--write_line "restart: " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +-- enable_reconnect +-- source include/wait_until_connected_again.inc + +insert into t1 values (1), (5), (10), (15), (20), (25); +with recursive cte as (select a from t1 union select a from cte where a < 2) + delete from v1 using v1, cte where v1.a = cte.a; +select * from t1 order by 1; + +drop table t1; + +--echo # End of 12.2 tests diff --git a/mysql-test/main/ctype_binary.result b/mysql-test/main/ctype_binary.result index ddb6828838625..794f25311db53 100644 --- a/mysql-test/main/ctype_binary.result +++ b/mysql-test/main/ctype_binary.result @@ -2038,20 +2038,6 @@ hex(concat(a)) a 30303030303030303030303030303030313030302E31 00000000000000001000.1 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -select hex(concat(a)) from t1; -hex(concat(a)) -3031 -create table t2 as select concat(a) from t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `concat(a)` varbinary(2) DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -drop table t1, t2; create table t1 (a year); insert into t1 values (1); select hex(concat(a)) from t1; @@ -2353,19 +2339,6 @@ hex(a) 30303030303030303030303030303031303030302E31 drop table t1; drop view v1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -create view v1(a) as select concat(a) from t1; -show columns from v1; -Field Type Null Key Default Extra -a varbinary(2) YES NULL -select hex(a) from v1; -hex(a) -3031 -drop table t1; -drop view v1; create table t1 (a year); insert into t1 values (1); create view v1(a) as select concat(a) from t1; diff --git a/mysql-test/main/ctype_collate_implicit.result b/mysql-test/main/ctype_collate_implicit.result index 2f9fe5723c35f..64082dbf63c4c 100644 --- a/mysql-test/main/ctype_collate_implicit.result +++ b/mysql-test/main/ctype_collate_implicit.result @@ -182,17 +182,17 @@ WHERE CHARACTER_SET_NAME='latin1'; CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN latin1 latin1_bin cp1252 West European 1 SHOW COLLATION LIKE 'latin1%'; -Collation Charset Id Default Compiled Sortlen -latin1_german1_ci latin1 5 Yes 1 -latin1_swedish_ci latin1 8 Yes 1 -latin1_danish_ci latin1 15 Yes 1 -latin1_german2_ci latin1 31 Yes 2 -latin1_bin latin1 47 Yes Yes 1 -latin1_general_ci latin1 48 Yes 1 -latin1_general_cs latin1 49 Yes 1 -latin1_spanish_ci latin1 94 Yes 1 -latin1_swedish_nopad_ci latin1 1032 Yes 1 -latin1_nopad_bin latin1 1071 Yes 1 +Collation Charset Id Default Compiled Sortlen Pad_attribute +latin1_german1_ci latin1 5 Yes 1 PAD SPACE +latin1_swedish_ci latin1 8 Yes 1 PAD SPACE +latin1_danish_ci latin1 15 Yes 1 PAD SPACE +latin1_german2_ci latin1 31 Yes 2 PAD SPACE +latin1_bin latin1 47 Yes Yes 1 PAD SPACE +latin1_general_ci latin1 48 Yes 1 PAD SPACE +latin1_general_cs latin1 49 Yes 1 PAD SPACE +latin1_spanish_ci latin1 94 Yes 1 PAD SPACE +latin1_swedish_nopad_ci latin1 1032 Yes 1 NO PAD +latin1_nopad_bin latin1 1071 Yes 1 NO PAD SELECT COLLATION_NAME, IS_DEFAULT FROM INFORMATION_SCHEMA.COLLATIONS WHERE CHARACTER_SET_NAME LIKE 'latin1%'; @@ -229,8 +229,8 @@ WHERE CHARACTER_SET_NAME='utf8mb4'; CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN utf8mb4 utf8mb4_uca1400_ai_ci UTF-8 Unicode 4 SHOW COLLATION LIKE '%uca1400_ai_ci%'; -Collation Charset Id Default Compiled Sortlen -uca1400_ai_ci NULL NULL NULL Yes 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +uca1400_ai_ci NULL NULL NULL Yes 8 PAD SPACE SELECT COLLATION_NAME, IS_DEFAULT FROM INFORMATION_SCHEMA.COLLATIONS WHERE COLLATION_NAME LIKE '%uca1400_ai_ci%'; diff --git a/mysql-test/main/ctype_cp1250_ch.result b/mysql-test/main/ctype_cp1250_ch.result index fb0373349fdfe..c65b3d260af10 100644 --- a/mysql-test/main/ctype_cp1250_ch.result +++ b/mysql-test/main/ctype_cp1250_ch.result @@ -1,8 +1,8 @@ drop table if exists t1; DROP TABLE IF EXISTS t1; SHOW COLLATION LIKE 'cp1250_czech_cs'; -Collation Charset Id Default Compiled Sortlen -cp1250_czech_cs cp1250 34 Yes 2 +Collation Charset Id Default Compiled Sortlen Pad_attribute +cp1250_czech_cs cp1250 34 Yes 2 PAD SPACE SET @test_character_set= 'cp1250'; SET @test_collation= 'cp1250_general_ci'; SET @safe_character_set_server= @@character_set_server; diff --git a/mysql-test/main/ctype_cp1251.result b/mysql-test/main/ctype_cp1251.result index 9de7d0dd92232..8d67de36b6041 100644 --- a/mysql-test/main/ctype_cp1251.result +++ b/mysql-test/main/ctype_cp1251.result @@ -2450,20 +2450,6 @@ hex(concat(a)) a 30303030303030303030303030303030313030302E31 00000000000000001000.1 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -select hex(concat(a)) from t1; -hex(concat(a)) -3031 -create table t2 as select concat(a) from t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET cp1251 COLLATE cp1251_general_ci DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -drop table t1, t2; create table t1 (a year); insert into t1 values (1); select hex(concat(a)) from t1; @@ -2765,19 +2751,6 @@ hex(a) 30303030303030303030303030303031303030302E31 drop table t1; drop view v1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -create view v1(a) as select concat(a) from t1; -show columns from v1; -Field Type Null Key Default Extra -a varchar(2) YES NULL -select hex(a) from v1; -hex(a) -3031 -drop table t1; -drop view v1; create table t1 (a year); insert into t1 values (1); create view v1(a) as select concat(a) from t1; diff --git a/mysql-test/main/ctype_latin1.result b/mysql-test/main/ctype_latin1.result index 5c584ebec3c48..fb5337ee8ad0a 100644 --- a/mysql-test/main/ctype_latin1.result +++ b/mysql-test/main/ctype_latin1.result @@ -2759,20 +2759,6 @@ hex(concat(a)) a 30303030303030303030303030303030313030302E31 00000000000000001000.1 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -select hex(concat(a)) from t1; -hex(concat(a)) -3031 -create table t2 as select concat(a) from t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET latin1 COLLATE latin1_swedish_ci DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -drop table t1, t2; create table t1 (a year); insert into t1 values (1); select hex(concat(a)) from t1; @@ -3074,19 +3060,6 @@ hex(a) 30303030303030303030303030303031303030302E31 drop table t1; drop view v1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -create view v1(a) as select concat(a) from t1; -show columns from v1; -Field Type Null Key Default Extra -a varchar(2) YES NULL -select hex(a) from v1; -hex(a) -3031 -drop table t1; -drop view v1; create table t1 (a year); insert into t1 values (1); create view v1(a) as select concat(a) from t1; @@ -8161,12 +8134,12 @@ SELECT * FROM t1 WHERE (a,a)=('2001-01-01x',DATE'2001-01-01'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=(DATE'2001-01-01','2001-01-01x'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=('2001-01-01',DATE'2001-01-01'); a 2001-01-01 @@ -8186,12 +8159,12 @@ SELECT * FROM t1 WHERE (a,a)=('2001-01-01x',DATE'2001-01-01'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=(DATE'2001-01-01','2001-01-01x'); a 2001-01-01x Warnings: -Warning 1292 Truncated incorrect date value: '2001-01-01x' +Warning 1292 Incorrect date value: '2001-01-01x' for column `test`.`t1`.`a` at row 2 SELECT * FROM t1 WHERE (a,a)=('2001-01-01',DATE'2001-01-01'); a 2001-01-01 diff --git a/mysql-test/main/ctype_ldml.result b/mysql-test/main/ctype_ldml.result index 54d9dde354be4..c6bc0a3ab74f5 100644 --- a/mysql-test/main/ctype_ldml.result +++ b/mysql-test/main/ctype_ldml.result @@ -7,8 +7,8 @@ show variables like 'character_sets_dir%'; Variable_name Value character_sets_dir MYSQL_TEST_DIR/std_data/ldml/ show collation like 'utf8mb3_phone_ci'; -Collation Charset Id Default Compiled Sortlen -utf8mb3_phone_ci utf8mb3 352 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +utf8mb3_phone_ci utf8mb3 352 8 PAD SPACE CREATE TABLE t1 ( name VARCHAR(64), phone VARCHAR(64) CHARACTER SET utf8 COLLATE utf8_phone_ci @@ -39,8 +39,8 @@ name phone Bar +7-912-800-80-01 DROP TABLE t1; show collation like 'utf8mb3_test_ci'; -Collation Charset Id Default Compiled Sortlen -utf8mb3_test_ci utf8mb3 353 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +utf8mb3_test_ci utf8mb3 353 8 PAD SPACE create table t1 (c1 char(1) character set utf8 collate utf8_test_ci); insert into t1 values ('a'); select * from t1 where c1='b'; @@ -48,8 +48,8 @@ c1 a drop table t1; show collation like 'ucs2_test_ci'; -Collation Charset Id Default Compiled Sortlen -ucs2_test_ci ucs2 358 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +ucs2_test_ci ucs2 358 8 PAD SPACE create table t1 (c1 char(1) character set ucs2 collate ucs2_test_ci); insert into t1 values ('a'); select * from t1 where c1='b'; @@ -57,8 +57,8 @@ c1 a drop table t1; show collation like 'utf8mb4_test_ci'; -Collation Charset Id Default Compiled Sortlen -utf8mb4_test_ci utf8mb4 326 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +utf8mb4_test_ci utf8mb4 326 8 PAD SPACE create table t1 (c1 char(1) character set utf8mb4 collate utf8mb4_test_ci); insert into t1 values ('a'); select * from t1 where c1='b'; @@ -66,8 +66,8 @@ c1 a drop table t1; show collation like 'utf16_test_ci'; -Collation Charset Id Default Compiled Sortlen -utf16_test_ci utf16 327 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +utf16_test_ci utf16 327 8 PAD SPACE create table t1 (c1 char(1) character set utf16 collate utf16_test_ci); insert into t1 values ('a'); select * from t1 where c1='b'; @@ -75,8 +75,8 @@ c1 a drop table t1; show collation like 'utf32_test_ci'; -Collation Charset Id Default Compiled Sortlen -utf32_test_ci utf32 391 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +utf32_test_ci utf32 391 8 PAD SPACE create table t1 (c1 char(1) character set utf32 collate utf32_test_ci); insert into t1 values ('a'); select * from t1 where c1='b'; @@ -174,8 +174,8 @@ Warning 1265 Data truncated for column 'c1' at row 1 DROP TABLE t1; Vietnamese experimental collation show collation like 'ucs2_vn_ci'; -Collation Charset Id Default Compiled Sortlen -ucs2_vn_ci ucs2 359 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +ucs2_vn_ci ucs2 359 8 PAD SPACE create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci); insert into t1 values (0x0061),(0x0041),(0x00E0),(0x00C0),(0x1EA3),(0x1EA2), (0x00E3),(0x00C3),(0x00E1),(0x00C1),(0x1EA1),(0x1EA0); @@ -449,69 +449,69 @@ drop table t1; Bug#46448 trailing spaces are not ignored when user collation maps space != 0x20 set names latin1; show collation like 'latin1_test'; -Collation Charset Id Default Compiled Sortlen -latin1_test latin1 331 1 +Collation Charset Id Default Compiled Sortlen Pad_attribute +latin1_test latin1 331 1 PAD SPACE select "foo" = "foo " collate latin1_test; "foo" = "foo " collate latin1_test 1 The following tests check that two-byte collation IDs work select * from information_schema.collations where id>256 and is_compiled<>'Yes' order by id; -COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN COMMENT -ascii2_general_nopad_ci ascii2 318 1 -ascii2_bin2 ascii2 319 1 -ascii2_general_ci ascii2 320 Yes 1 -ascii2_bin ascii2 321 1 -ascii2_general_inherited_ci ascii2 322 1 -ascii2_general_inherited2_ci ascii2 323 1 -ascii2_badly_inherited_ci ascii2 324 1 -ascii2_nopad_bin ascii2 325 1 -utf8mb4_test_ci utf8mb4 326 8 -utf16_test_ci utf16 327 8 -utf8mb4_test_400_ci utf8mb4 328 8 -utf8mb4_test_520_nopad_ci utf8mb4 329 8 -utf8mb4_uca1400_test01_as_ci utf8mb4 330 4 -latin1_test latin1 331 1 cp1252 West European -latin1_test2 latin1 332 1 cp1252 West European -latin1_test2_cs latin1 333 1 cp1252 West European -latin1_swedish_nopad2_ci latin1 334 1 cp1252 West European -utf8mb3_bengali_standard_ci utf8mb3 336 8 -utf8mb3_bengali_traditional_ci utf8mb3 337 8 -utf8mb3_implicit_weights_ci utf8mb3 338 8 -utf8mb3_phone_ci utf8mb3 352 8 -utf8mb3_test_ci utf8mb3 353 8 -utf8mb3_5624_1 utf8mb3 354 8 -utf8mb3_5624_2 utf8mb3 355 8 -utf8mb3_5624_3 utf8mb3 356 8 -utf8mb3_5624_4 utf8mb3 357 8 -ucs2_test_ci ucs2 358 8 -ucs2_vn_ci ucs2 359 8 -ucs2_5624_1 ucs2 360 8 -utf8mb3_5624_5 utf8mb3 368 8 -utf8mb3_5624_5_bad utf8mb3 369 8 -utf8mb3_czech_test_w2 utf8mb3 370 4 -utf8mb3_czech_test_nopad_w2 utf8mb3 371 4 -utf8mb3_czech_test_bad_w2 utf8mb3 372 4 -utf32_test_ci utf32 391 8 -utf8mb3_maxuserid_ci utf8mb3 2047 8 +COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN PAD_ATTRIBUTE COMMENT +ascii2_general_nopad_ci ascii2 318 1 NO PAD +ascii2_bin2 ascii2 319 1 PAD SPACE +ascii2_general_ci ascii2 320 Yes 1 PAD SPACE +ascii2_bin ascii2 321 1 PAD SPACE +ascii2_general_inherited_ci ascii2 322 1 PAD SPACE +ascii2_general_inherited2_ci ascii2 323 1 PAD SPACE +ascii2_badly_inherited_ci ascii2 324 1 PAD SPACE +ascii2_nopad_bin ascii2 325 1 NO PAD +utf8mb4_test_ci utf8mb4 326 8 PAD SPACE +utf16_test_ci utf16 327 8 PAD SPACE +utf8mb4_test_400_ci utf8mb4 328 8 PAD SPACE +utf8mb4_test_520_nopad_ci utf8mb4 329 8 NO PAD +utf8mb4_uca1400_test01_as_ci utf8mb4 330 4 PAD SPACE +latin1_test latin1 331 1 PAD SPACE cp1252 West European +latin1_test2 latin1 332 1 PAD SPACE cp1252 West European +latin1_test2_cs latin1 333 1 PAD SPACE cp1252 West European +latin1_swedish_nopad2_ci latin1 334 1 NO PAD cp1252 West European +utf8mb3_bengali_standard_ci utf8mb3 336 8 PAD SPACE +utf8mb3_bengali_traditional_ci utf8mb3 337 8 PAD SPACE +utf8mb3_implicit_weights_ci utf8mb3 338 8 PAD SPACE +utf8mb3_phone_ci utf8mb3 352 8 PAD SPACE +utf8mb3_test_ci utf8mb3 353 8 PAD SPACE +utf8mb3_5624_1 utf8mb3 354 8 PAD SPACE +utf8mb3_5624_2 utf8mb3 355 8 PAD SPACE +utf8mb3_5624_3 utf8mb3 356 8 PAD SPACE +utf8mb3_5624_4 utf8mb3 357 8 PAD SPACE +ucs2_test_ci ucs2 358 8 PAD SPACE +ucs2_vn_ci ucs2 359 8 PAD SPACE +ucs2_5624_1 ucs2 360 8 PAD SPACE +utf8mb3_5624_5 utf8mb3 368 8 PAD SPACE +utf8mb3_5624_5_bad utf8mb3 369 8 PAD SPACE +utf8mb3_czech_test_w2 utf8mb3 370 4 PAD SPACE +utf8mb3_czech_test_nopad_w2 utf8mb3 371 4 NO PAD +utf8mb3_czech_test_bad_w2 utf8mb3 372 4 PAD SPACE +utf32_test_ci utf32 391 8 PAD SPACE +utf8mb3_maxuserid_ci utf8mb3 2047 8 PAD SPACE show collation like '%test%'; -Collation Charset Id Default Compiled Sortlen -latin1_test latin1 331 1 -latin1_test2 latin1 332 1 -latin1_test2_cs latin1 333 1 -utf8mb3_test_ci utf8mb3 353 8 -utf8mb3_czech_test_w2 utf8mb3 370 4 -utf8mb3_czech_test_nopad_w2 utf8mb3 371 4 -utf8mb3_czech_test_bad_w2 utf8mb3 372 4 -ucs2_test_ci ucs2 358 8 -utf8mb4_test_ci utf8mb4 326 8 -utf8mb4_test_400_ci utf8mb4 328 8 -utf8mb4_test_520_nopad_ci utf8mb4 329 8 -utf8mb4_uca1400_test01_as_ci utf8mb4 330 4 -utf16_test_ci utf16 327 8 -utf32_test_ci utf32 391 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +latin1_test latin1 331 1 PAD SPACE +latin1_test2 latin1 332 1 PAD SPACE +latin1_test2_cs latin1 333 1 PAD SPACE +utf8mb3_test_ci utf8mb3 353 8 PAD SPACE +utf8mb3_czech_test_w2 utf8mb3 370 4 PAD SPACE +utf8mb3_czech_test_nopad_w2 utf8mb3 371 4 NO PAD +utf8mb3_czech_test_bad_w2 utf8mb3 372 4 PAD SPACE +ucs2_test_ci ucs2 358 8 PAD SPACE +utf8mb4_test_ci utf8mb4 326 8 PAD SPACE +utf8mb4_test_400_ci utf8mb4 328 8 PAD SPACE +utf8mb4_test_520_nopad_ci utf8mb4 329 8 NO PAD +utf8mb4_uca1400_test01_as_ci utf8mb4 330 4 PAD SPACE +utf16_test_ci utf16 327 8 PAD SPACE +utf32_test_ci utf32 391 8 PAD SPACE show collation like 'ucs2_vn_ci'; -Collation Charset Id Default Compiled Sortlen -ucs2_vn_ci ucs2 359 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +ucs2_vn_ci ucs2 359 8 PAD SPACE create table t1 (c1 char(1) character set ucs2 collate ucs2_vn_ci); insert into t1 values (0x0061); set @@character_set_results=NULL; @@ -530,8 +530,8 @@ b DROP TABLE t1; SET NAMES utf8 COLLATE utf8_phone_ci; show collation like 'utf8mb3_phone_ci'; -Collation Charset Id Default Compiled Sortlen -utf8mb3_phone_ci utf8mb3 352 8 +Collation Charset Id Default Compiled Sortlen Pad_attribute +utf8mb3_phone_ci utf8mb3 352 8 PAD SPACE SET NAMES utf8; SELECT hex(weight_string(_utf8mb4'a' collate utf8mb4_test_400_ci)) as exp; exp @@ -3108,7 +3108,7 @@ DROP TABLE case_folding; # MDEV-7947 my_charset_same: strcmp() takes 0.37% in OLTP RO # SHOW COLLATION LIKE 'latin1_test_replace'; -Collation Charset Id Default Compiled Sortlen +Collation Charset Id Default Compiled Sortlen Pad_attribute SELECT 'foo' = 'foo ' COLLATE latin1_test_replace; ERROR HY000: Unknown collation: 'latin1_test_replace' # diff --git a/mysql-test/main/ctype_ucs.result b/mysql-test/main/ctype_ucs.result index 84ee60e19bf78..595fba0b8158c 100644 --- a/mysql-test/main/ctype_ucs.result +++ b/mysql-test/main/ctype_ucs.result @@ -174,8 +174,8 @@ LPAD(_ucs2 X'0420',10,_ucs2 X'04210422') SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); LPAD(_ucs2 X'0420',10,_ucs2 X'042104220423') -SELECT LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); -LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') +SELECT LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') AS res; +res SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'0421'); RPAD(_ucs2 X'0420',10,_ucs2 X'0421') @@ -186,8 +186,8 @@ RPAD(_ucs2 X'0420',10,_ucs2 X'04210422') SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); RPAD(_ucs2 X'0420',10,_ucs2 X'042104220423') -SELECT RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); -RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') +SELECT RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') AS res; +res CREATE TABLE t1 SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'0421') l, @@ -3641,20 +3641,6 @@ hex(concat(a)) a 00300030003000300030003000300030003000300030003000300030003000300031003000300030002E0031 00000000000000001000.1 00300030003000300030003000300030003000300030003000300030003000310030003000300030002E0031 00000000000000010000.1 drop table t1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -select hex(concat(a)) from t1; -hex(concat(a)) -00300031 -create table t2 as select concat(a) from t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET ucs2 COLLATE ucs2_general_ci DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -drop table t1, t2; create table t1 (a year); insert into t1 values (1); select hex(concat(a)) from t1; @@ -3956,19 +3942,6 @@ hex(a) 00300030003000300030003000300030003000300030003000300030003000310030003000300030002E0031 drop table t1; drop view v1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -create view v1(a) as select concat(a) from t1; -show columns from v1; -Field Type Null Key Default Extra -a varchar(2) YES NULL -select hex(a) from v1; -hex(a) -00300031 -drop table t1; -drop view v1; create table t1 (a year); insert into t1 values (1); create view v1(a) as select concat(a) from t1; diff --git a/mysql-test/main/ctype_ucs.test b/mysql-test/main/ctype_ucs.test index 03e6567820431..e9a7513231496 100644 --- a/mysql-test/main/ctype_ucs.test +++ b/mysql-test/main/ctype_ucs.test @@ -51,12 +51,12 @@ DROP TABLE t1; SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'0421'); SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'04210422'); SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); -SELECT LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); +SELECT LPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') AS res; SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'0421'); SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'04210422'); SELECT RPAD(_ucs2 X'0420',10,_ucs2 X'042104220423'); -SELECT RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423'); +SELECT RPAD(_ucs2 X'0420042104220423042404250426042704280429042A042B',10,_ucs2 X'042104220423') AS res; CREATE TABLE t1 SELECT LPAD(_ucs2 X'0420',10,_ucs2 X'0421') l, @@ -118,6 +118,7 @@ SET NAMES koi8r; SET character_set_connection=ucs2; --source include/ctype_like.inc +--disable_service_connection CREATE TABLE t1 (a VARCHAR(10) CHARACTER SET ucs2); INSERT INTO t1 VALUES (''),(''),(''),(''),(''),(''); INSERT INTO t1 VALUES (''),(''),(''),(''); @@ -127,6 +128,7 @@ SELECT * FROM t1 WHERE a LIKE '% SELECT * FROM t1 WHERE a LIKE '%%'; SELECT * FROM t1 WHERE a LIKE '%'; SELECT * FROM t1 WHERE a LIKE '%' COLLATE ucs2_bin; +--enable_service_connection DROP TABLE t1; # diff --git a/mysql-test/main/ctype_utf8.result b/mysql-test/main/ctype_utf8.result index 1182028c925bc..1c184e24ecd4c 100644 --- a/mysql-test/main/ctype_utf8.result +++ b/mysql-test/main/ctype_utf8.result @@ -4387,20 +4387,6 @@ hex(concat(a)) a 30303030303030303030303030303030313030302E31 00000000000000001000.1 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -select hex(concat(a)) from t1; -hex(concat(a)) -3031 -create table t2 as select concat(a) from t1; -show create table t2; -Table Create Table -t2 CREATE TABLE `t2` ( - `concat(a)` varchar(2) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -drop table t1, t2; create table t1 (a year); insert into t1 values (1); select hex(concat(a)) from t1; @@ -4702,19 +4688,6 @@ hex(a) 30303030303030303030303030303031303030302E31 drop table t1; drop view v1; -create table t1 (a year(2)); -Warnings: -Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead -insert into t1 values (1); -create view v1(a) as select concat(a) from t1; -show columns from v1; -Field Type Null Key Default Extra -a varchar(2) YES NULL -select hex(a) from v1; -hex(a) -3031 -drop table t1; -drop view v1; create table t1 (a year); insert into t1 values (1); create view v1(a) as select concat(a) from t1; diff --git a/mysql-test/main/ctype_utf8mb4_0900.result b/mysql-test/main/ctype_utf8mb4_0900.result index 5bb3123aab8dc..4e94f3d3f3339 100644 --- a/mysql-test/main/ctype_utf8mb4_0900.result +++ b/mysql-test/main/ctype_utf8mb4_0900.result @@ -47,51 +47,51 @@ utf8mb4_tr_0900_as_cs utf8mb4 utf8mb4_tr_0900_as_cs 288 utf8mb4_vi_0900_ai_ci utf8mb4 utf8mb4_vi_0900_ai_ci 277 utf8mb4_vi_0900_as_cs utf8mb4 utf8mb4_vi_0900_as_cs 300 select * from information_schema.COLLATIONS where collation_name like "%0900%"; -COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN COMMENT -utf8mb4_0900_ai_ci utf8mb4 255 Yes 8 Alias for utf8mb4_uca1400_nopad_ai_ci -utf8mb4_de_pb_0900_ai_ci utf8mb4 256 Yes 8 Alias for utf8mb4_uca1400_german2_nopad_ai_ci -utf8mb4_is_0900_ai_ci utf8mb4 257 Yes 8 Alias for utf8mb4_uca1400_icelandic_nopad_ai_ci -utf8mb4_lv_0900_ai_ci utf8mb4 258 Yes 8 Alias for utf8mb4_uca1400_latvian_nopad_ai_ci -utf8mb4_ro_0900_ai_ci utf8mb4 259 Yes 8 Alias for utf8mb4_uca1400_romanian_nopad_ai_ci -utf8mb4_sl_0900_ai_ci utf8mb4 260 Yes 8 Alias for utf8mb4_uca1400_slovenian_nopad_ai_ci -utf8mb4_pl_0900_ai_ci utf8mb4 261 Yes 8 Alias for utf8mb4_uca1400_polish_nopad_ai_ci -utf8mb4_et_0900_ai_ci utf8mb4 262 Yes 8 Alias for utf8mb4_uca1400_estonian_nopad_ai_ci -utf8mb4_es_0900_ai_ci utf8mb4 263 Yes 8 Alias for utf8mb4_uca1400_spanish_nopad_ai_ci -utf8mb4_sv_0900_ai_ci utf8mb4 264 Yes 8 Alias for utf8mb4_uca1400_swedish_nopad_ai_ci -utf8mb4_tr_0900_ai_ci utf8mb4 265 Yes 8 Alias for utf8mb4_uca1400_turkish_nopad_ai_ci -utf8mb4_cs_0900_ai_ci utf8mb4 266 Yes 8 Alias for utf8mb4_uca1400_czech_nopad_ai_ci -utf8mb4_da_0900_ai_ci utf8mb4 267 Yes 8 Alias for utf8mb4_uca1400_danish_nopad_ai_ci -utf8mb4_lt_0900_ai_ci utf8mb4 268 Yes 8 Alias for utf8mb4_uca1400_lithuanian_nopad_ai_ci -utf8mb4_sk_0900_ai_ci utf8mb4 269 Yes 8 Alias for utf8mb4_uca1400_slovak_nopad_ai_ci -utf8mb4_es_trad_0900_ai_ci utf8mb4 270 Yes 8 Alias for utf8mb4_uca1400_spanish2_nopad_ai_ci -utf8mb4_la_0900_ai_ci utf8mb4 271 Yes 8 Alias for utf8mb4_uca1400_roman_nopad_ai_ci -utf8mb4_eo_0900_ai_ci utf8mb4 273 Yes 8 Alias for utf8mb4_uca1400_esperanto_nopad_ai_ci -utf8mb4_hu_0900_ai_ci utf8mb4 274 Yes 8 Alias for utf8mb4_uca1400_hungarian_nopad_ai_ci -utf8mb4_hr_0900_ai_ci utf8mb4 275 Yes 8 Alias for utf8mb4_uca1400_croatian_nopad_ai_ci -utf8mb4_vi_0900_ai_ci utf8mb4 277 Yes 8 Alias for utf8mb4_uca1400_vietnamese_nopad_ai_ci -utf8mb4_0900_as_cs utf8mb4 278 Yes 8 Alias for utf8mb4_uca1400_nopad_as_cs -utf8mb4_de_pb_0900_as_cs utf8mb4 279 Yes 8 Alias for utf8mb4_uca1400_german2_nopad_as_cs -utf8mb4_is_0900_as_cs utf8mb4 280 Yes 8 Alias for utf8mb4_uca1400_icelandic_nopad_as_cs -utf8mb4_lv_0900_as_cs utf8mb4 281 Yes 8 Alias for utf8mb4_uca1400_latvian_nopad_as_cs -utf8mb4_ro_0900_as_cs utf8mb4 282 Yes 8 Alias for utf8mb4_uca1400_romanian_nopad_as_cs -utf8mb4_sl_0900_as_cs utf8mb4 283 Yes 8 Alias for utf8mb4_uca1400_slovenian_nopad_as_cs -utf8mb4_pl_0900_as_cs utf8mb4 284 Yes 8 Alias for utf8mb4_uca1400_polish_nopad_as_cs -utf8mb4_et_0900_as_cs utf8mb4 285 Yes 8 Alias for utf8mb4_uca1400_estonian_nopad_as_cs -utf8mb4_es_0900_as_cs utf8mb4 286 Yes 8 Alias for utf8mb4_uca1400_spanish_nopad_as_cs -utf8mb4_sv_0900_as_cs utf8mb4 287 Yes 8 Alias for utf8mb4_uca1400_swedish_nopad_as_cs -utf8mb4_tr_0900_as_cs utf8mb4 288 Yes 8 Alias for utf8mb4_uca1400_turkish_nopad_as_cs -utf8mb4_cs_0900_as_cs utf8mb4 289 Yes 8 Alias for utf8mb4_uca1400_czech_nopad_as_cs -utf8mb4_da_0900_as_cs utf8mb4 290 Yes 8 Alias for utf8mb4_uca1400_danish_nopad_as_cs -utf8mb4_lt_0900_as_cs utf8mb4 291 Yes 8 Alias for utf8mb4_uca1400_lithuanian_nopad_as_cs -utf8mb4_sk_0900_as_cs utf8mb4 292 Yes 8 Alias for utf8mb4_uca1400_slovak_nopad_as_cs -utf8mb4_es_trad_0900_as_cs utf8mb4 293 Yes 8 Alias for utf8mb4_uca1400_spanish2_nopad_as_cs -utf8mb4_la_0900_as_cs utf8mb4 294 Yes 8 Alias for utf8mb4_uca1400_roman_nopad_as_cs -utf8mb4_eo_0900_as_cs utf8mb4 296 Yes 8 Alias for utf8mb4_uca1400_esperanto_nopad_as_cs -utf8mb4_hu_0900_as_cs utf8mb4 297 Yes 8 Alias for utf8mb4_uca1400_hungarian_nopad_as_cs -utf8mb4_hr_0900_as_cs utf8mb4 298 Yes 8 Alias for utf8mb4_uca1400_croatian_nopad_as_cs -utf8mb4_vi_0900_as_cs utf8mb4 300 Yes 8 Alias for utf8mb4_uca1400_vietnamese_nopad_as_cs -utf8mb4_0900_as_ci utf8mb4 305 Yes 8 Alias for utf8mb4_uca1400_nopad_as_ci -utf8mb4_0900_bin utf8mb4 309 Yes 1 Alias for utf8mb4_nopad_bin +COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN PAD_ATTRIBUTE COMMENT +utf8mb4_0900_ai_ci utf8mb4 255 Yes 8 NO PAD Alias for utf8mb4_uca1400_nopad_ai_ci +utf8mb4_de_pb_0900_ai_ci utf8mb4 256 Yes 8 NO PAD Alias for utf8mb4_uca1400_german2_nopad_ai_ci +utf8mb4_is_0900_ai_ci utf8mb4 257 Yes 8 NO PAD Alias for utf8mb4_uca1400_icelandic_nopad_ai_ci +utf8mb4_lv_0900_ai_ci utf8mb4 258 Yes 8 NO PAD Alias for utf8mb4_uca1400_latvian_nopad_ai_ci +utf8mb4_ro_0900_ai_ci utf8mb4 259 Yes 8 NO PAD Alias for utf8mb4_uca1400_romanian_nopad_ai_ci +utf8mb4_sl_0900_ai_ci utf8mb4 260 Yes 8 NO PAD Alias for utf8mb4_uca1400_slovenian_nopad_ai_ci +utf8mb4_pl_0900_ai_ci utf8mb4 261 Yes 8 NO PAD Alias for utf8mb4_uca1400_polish_nopad_ai_ci +utf8mb4_et_0900_ai_ci utf8mb4 262 Yes 8 NO PAD Alias for utf8mb4_uca1400_estonian_nopad_ai_ci +utf8mb4_es_0900_ai_ci utf8mb4 263 Yes 8 NO PAD Alias for utf8mb4_uca1400_spanish_nopad_ai_ci +utf8mb4_sv_0900_ai_ci utf8mb4 264 Yes 8 NO PAD Alias for utf8mb4_uca1400_swedish_nopad_ai_ci +utf8mb4_tr_0900_ai_ci utf8mb4 265 Yes 8 NO PAD Alias for utf8mb4_uca1400_turkish_nopad_ai_ci +utf8mb4_cs_0900_ai_ci utf8mb4 266 Yes 8 NO PAD Alias for utf8mb4_uca1400_czech_nopad_ai_ci +utf8mb4_da_0900_ai_ci utf8mb4 267 Yes 8 NO PAD Alias for utf8mb4_uca1400_danish_nopad_ai_ci +utf8mb4_lt_0900_ai_ci utf8mb4 268 Yes 8 NO PAD Alias for utf8mb4_uca1400_lithuanian_nopad_ai_ci +utf8mb4_sk_0900_ai_ci utf8mb4 269 Yes 8 NO PAD Alias for utf8mb4_uca1400_slovak_nopad_ai_ci +utf8mb4_es_trad_0900_ai_ci utf8mb4 270 Yes 8 NO PAD Alias for utf8mb4_uca1400_spanish2_nopad_ai_ci +utf8mb4_la_0900_ai_ci utf8mb4 271 Yes 8 NO PAD Alias for utf8mb4_uca1400_roman_nopad_ai_ci +utf8mb4_eo_0900_ai_ci utf8mb4 273 Yes 8 NO PAD Alias for utf8mb4_uca1400_esperanto_nopad_ai_ci +utf8mb4_hu_0900_ai_ci utf8mb4 274 Yes 8 NO PAD Alias for utf8mb4_uca1400_hungarian_nopad_ai_ci +utf8mb4_hr_0900_ai_ci utf8mb4 275 Yes 8 NO PAD Alias for utf8mb4_uca1400_croatian_nopad_ai_ci +utf8mb4_vi_0900_ai_ci utf8mb4 277 Yes 8 NO PAD Alias for utf8mb4_uca1400_vietnamese_nopad_ai_ci +utf8mb4_0900_as_cs utf8mb4 278 Yes 8 NO PAD Alias for utf8mb4_uca1400_nopad_as_cs +utf8mb4_de_pb_0900_as_cs utf8mb4 279 Yes 8 NO PAD Alias for utf8mb4_uca1400_german2_nopad_as_cs +utf8mb4_is_0900_as_cs utf8mb4 280 Yes 8 NO PAD Alias for utf8mb4_uca1400_icelandic_nopad_as_cs +utf8mb4_lv_0900_as_cs utf8mb4 281 Yes 8 NO PAD Alias for utf8mb4_uca1400_latvian_nopad_as_cs +utf8mb4_ro_0900_as_cs utf8mb4 282 Yes 8 NO PAD Alias for utf8mb4_uca1400_romanian_nopad_as_cs +utf8mb4_sl_0900_as_cs utf8mb4 283 Yes 8 NO PAD Alias for utf8mb4_uca1400_slovenian_nopad_as_cs +utf8mb4_pl_0900_as_cs utf8mb4 284 Yes 8 NO PAD Alias for utf8mb4_uca1400_polish_nopad_as_cs +utf8mb4_et_0900_as_cs utf8mb4 285 Yes 8 NO PAD Alias for utf8mb4_uca1400_estonian_nopad_as_cs +utf8mb4_es_0900_as_cs utf8mb4 286 Yes 8 NO PAD Alias for utf8mb4_uca1400_spanish_nopad_as_cs +utf8mb4_sv_0900_as_cs utf8mb4 287 Yes 8 NO PAD Alias for utf8mb4_uca1400_swedish_nopad_as_cs +utf8mb4_tr_0900_as_cs utf8mb4 288 Yes 8 NO PAD Alias for utf8mb4_uca1400_turkish_nopad_as_cs +utf8mb4_cs_0900_as_cs utf8mb4 289 Yes 8 NO PAD Alias for utf8mb4_uca1400_czech_nopad_as_cs +utf8mb4_da_0900_as_cs utf8mb4 290 Yes 8 NO PAD Alias for utf8mb4_uca1400_danish_nopad_as_cs +utf8mb4_lt_0900_as_cs utf8mb4 291 Yes 8 NO PAD Alias for utf8mb4_uca1400_lithuanian_nopad_as_cs +utf8mb4_sk_0900_as_cs utf8mb4 292 Yes 8 NO PAD Alias for utf8mb4_uca1400_slovak_nopad_as_cs +utf8mb4_es_trad_0900_as_cs utf8mb4 293 Yes 8 NO PAD Alias for utf8mb4_uca1400_spanish2_nopad_as_cs +utf8mb4_la_0900_as_cs utf8mb4 294 Yes 8 NO PAD Alias for utf8mb4_uca1400_roman_nopad_as_cs +utf8mb4_eo_0900_as_cs utf8mb4 296 Yes 8 NO PAD Alias for utf8mb4_uca1400_esperanto_nopad_as_cs +utf8mb4_hu_0900_as_cs utf8mb4 297 Yes 8 NO PAD Alias for utf8mb4_uca1400_hungarian_nopad_as_cs +utf8mb4_hr_0900_as_cs utf8mb4 298 Yes 8 NO PAD Alias for utf8mb4_uca1400_croatian_nopad_as_cs +utf8mb4_vi_0900_as_cs utf8mb4 300 Yes 8 NO PAD Alias for utf8mb4_uca1400_vietnamese_nopad_as_cs +utf8mb4_0900_as_ci utf8mb4 305 Yes 8 NO PAD Alias for utf8mb4_uca1400_nopad_as_ci +utf8mb4_0900_bin utf8mb4 309 Yes 1 NO PAD Alias for utf8mb4_nopad_bin # # MDEV-20912 Add support for utf8mb4_0900_* collations in MariaDB Server # diff --git a/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.result b/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.result index f13fac20e43a7..1bfd04802d239 100644 --- a/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.result +++ b/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.result @@ -618,5 +618,10 @@ Warnings: Note 1003 select `test`.`t1`.`c1` AS `c1` from `test`.`t1` where concat(`test`.`t1`.`c1`) = 'ä' and concat(`test`.`t1`.`c1`) like 'ae' DROP TABLE IF EXISTS t1; # +# MDEV-38608 TO_DATE: Server crash in my_uca_strnncoll_multilevel_generic +# +CREATE TABLE t1 (f ENUM('foo','bar')) COLLATE uca1400_ai_cs; +DROP TABLE t1; +# # End of 10.0 tests # diff --git a/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.test b/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.test index 862053ed97717..83c630abb580d 100644 --- a/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.test +++ b/mysql-test/main/ctype_utf8mb4_uca1400_ai_ci.test @@ -47,6 +47,13 @@ SET NAMES utf8mb4 COLLATE uca1400_ai_ci; --source include/ctype_like_cond_propagation.inc --source include/ctype_like_cond_propagation_utf8_german.inc +--echo # +--echo # MDEV-38608 TO_DATE: Server crash in my_uca_strnncoll_multilevel_generic +--echo # + +CREATE TABLE t1 (f ENUM('foo','bar')) COLLATE uca1400_ai_cs; +DROP TABLE t1; + --echo # --echo # End of 10.0 tests --echo # diff --git a/mysql-test/main/ddl_i18n_koi8r.result b/mysql-test/main/ddl_i18n_koi8r.result index 3e6cd07c3117d..a1e3e45a8c4d8 100644 --- a/mysql-test/main/ddl_i18n_koi8r.result +++ b/mysql-test/main/ddl_i18n_koi8r.result @@ -2844,9 +2844,7 @@ Table Create Table t2 CREATE TABLE `t2` ( `col1` varchar(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_general_cs -connection con2; disconnect con2; -connection con3; disconnect con3; connection default; USE test; diff --git a/mysql-test/main/ddl_i18n_koi8r.test b/mysql-test/main/ddl_i18n_koi8r.test index f80dab8a04125..e6dbb278536be 100644 --- a/mysql-test/main/ddl_i18n_koi8r.test +++ b/mysql-test/main/ddl_i18n_koi8r.test @@ -1110,12 +1110,8 @@ SHOW CREATE TABLE mysqltest2.t2| # delimiter ;| ---connection con2 --disconnect con2 ---source include/wait_until_disconnected.inc ---connection con3 --disconnect con3 ---source include/wait_until_disconnected.inc --connection default USE test; DROP DATABASE mysqltest1; diff --git a/mysql-test/main/ddl_i18n_utf8.result b/mysql-test/main/ddl_i18n_utf8.result index ff31607c22d69..951717e178827 100644 --- a/mysql-test/main/ddl_i18n_utf8.result +++ b/mysql-test/main/ddl_i18n_utf8.result @@ -2844,9 +2844,7 @@ Table Create Table t2 CREATE TABLE `t2` ( `col1` varchar(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=cp1251 COLLATE=cp1251_general_cs -connection con2; disconnect con2; -connection con3; disconnect con3; connection default; USE test; diff --git a/mysql-test/main/ddl_i18n_utf8.test b/mysql-test/main/ddl_i18n_utf8.test index a6ca726bb9e4c..a4ba10bd689ef 100644 --- a/mysql-test/main/ddl_i18n_utf8.test +++ b/mysql-test/main/ddl_i18n_utf8.test @@ -1113,12 +1113,8 @@ SHOW CREATE TABLE mysqltest2.t2| # delimiter ;| ---connection con2 --disconnect con2 ---source include/wait_until_disconnected.inc ---connection con3 --disconnect con3 ---source include/wait_until_disconnected.inc --connection default USE test; DROP DATABASE mysqltest1; diff --git a/mysql-test/main/deadlock_ftwrl.test b/mysql-test/main/deadlock_ftwrl.test index fc943bcf95347..1114a16e41fc4 100644 --- a/mysql-test/main/deadlock_ftwrl.test +++ b/mysql-test/main/deadlock_ftwrl.test @@ -3,7 +3,7 @@ # Deadlock detector should resolve conflicts between FTWRL and user locks. --source include/have_debug_sync.inc ---source include/count_sessions.inc +--source include/no_view_protocol.inc CREATE TABLE t1(a INT); SELECT GET_LOCK("l1", 0); @@ -32,5 +32,3 @@ UNLOCK TABLES; DROP TABLE t1; set debug_sync='reset'; - ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/debug_sync.result b/mysql-test/main/debug_sync.result index 6bc2a5cbe245f..4c1711a6d6b3b 100644 --- a/mysql-test/main/debug_sync.result +++ b/mysql-test/main/debug_sync.result @@ -320,30 +320,3 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC'; Variable_name Value debug_sync ON - current signals: 's2,s7,s1,s5' SET DEBUG_SYNC= 'RESET'; -# -# MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode -# -create table t (c int) engine=innodb; -connect con1,localhost,root; -set debug_sync='get_schema_column WAIT_FOR go'; -select column_name from information_schema.columns -where table_schema='test' and table_name='t'; -connection default; -lock table t write; -alter table t discard tablespace; -connect con2,localhost,root; -disconnect con2; -connection default; -ERROR 70100: Query execution was interrupted -set debug_sync='now SIGNAL go'; -connection con1; -column_name -c -disconnect con1; -connection default; -unlock tables; -drop table t; -set debug_sync= 'reset'; -# -# End of 10.6 tests -# diff --git a/mysql-test/main/debug_sync.test b/mysql-test/main/debug_sync.test index 1c8638832c139..4c39ed39bfe0b 100644 --- a/mysql-test/main/debug_sync.test +++ b/mysql-test/main/debug_sync.test @@ -448,43 +448,3 @@ SHOW VARIABLES LIKE 'DEBUG_SYNC'; # Otherwise signal would confuse the next test. # SET DEBUG_SYNC= 'RESET'; - ---echo # ---echo # MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode ---echo # -create table t (c int) engine=innodb; ---connect con1,localhost,root -set debug_sync='get_schema_column WAIT_FOR go'; -send select column_name from information_schema.columns -where table_schema='test' and table_name='t'; - ---connection default -let $wait_condition=select 1 from information_schema.processlist where state like 'debug sync point%'; ---source include/wait_condition.inc -let $connid=`select connection_id()`; -lock table t write; -send alter table t discard tablespace; - ---connect con2,localhost,root ---disable_query_log ---eval kill query $connid ---enable_query_log ---disconnect con2 - ---connection default ---error ER_QUERY_INTERRUPTED -reap; -set debug_sync='now SIGNAL go'; - ---connection con1 -reap; ---disconnect con1 - ---connection default -unlock tables; -drop table t; -set debug_sync= 'reset'; - ---echo # ---echo # End of 10.6 tests ---echo # diff --git a/mysql-test/main/default.result b/mysql-test/main/default.result index d1fa23369c3a6..a1437dfe622a3 100644 --- a/mysql-test/main/default.result +++ b/mysql-test/main/default.result @@ -3122,7 +3122,7 @@ create table t3 as select max(a), max(b), max(c) from t1; show create table t2; Table Create Table t2 CREATE TABLE `t2` ( - `a` int(11) DEFAULT 5 CHECK (`a` > 10), + `a` int(11) DEFAULT 5, `b` int(11) DEFAULT (5 + 5), `c` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci diff --git a/mysql-test/main/delayed.result b/mysql-test/main/delayed.result index 73e1ed40c6a58..30d8fe99ccd6e 100644 --- a/mysql-test/main/delayed.result +++ b/mysql-test/main/delayed.result @@ -420,3 +420,11 @@ CREATE TABLE t1 (c0 INT,UNIQUE (c0) USING HASH) ENGINE=MYISAM; INSERT DELAYED INTO t1 VALUES (0); INSERT DELAYED INTO t1 VALUES (0); DROP TABLE t1; +# +# MDEV-38726: Assertion `table->default_field != dfield_ptr' failed in +# bool parse_vcol_defs(THD *, MEM_ROOT *, TABLE *, bool *, +# vcol_init_mode) +# +CREATE TABLE t_38726 (a TIMESTAMP ON UPDATE CURRENT_TIMESTAMP()) ENGINE=MYISAM; +INSERT DELAYED INTO t_38726 VALUES (); +DROP TABLE t_38726; diff --git a/mysql-test/main/delayed.test b/mysql-test/main/delayed.test index 36f2b6653c9e6..a578a76dbd4f8 100644 --- a/mysql-test/main/delayed.test +++ b/mysql-test/main/delayed.test @@ -534,12 +534,8 @@ INSERT DELAYED INTO t2 VALUES (8); UNLOCK TABLES; SET AUTOCOMMIT= 1; -connection con2; disconnect con2; ---source include/wait_until_disconnected.inc -connection con1; disconnect con1; ---source include/wait_until_disconnected.inc connection default; DROP TABLE t1, t2, t3; @@ -585,7 +581,6 @@ connection con1; --reap disconnect con1; ---source include/wait_until_disconnected.inc connection default; drop tables tm, t1, t2; @@ -637,3 +632,13 @@ INSERT DELAYED INTO t1 VALUES (0); DROP TABLE t1; --enable_view_protocol + +--echo # +--echo # MDEV-38726: Assertion `table->default_field != dfield_ptr' failed in +--echo # bool parse_vcol_defs(THD *, MEM_ROOT *, TABLE *, bool *, +--echo # vcol_init_mode) +--echo # + +CREATE TABLE t_38726 (a TIMESTAMP ON UPDATE CURRENT_TIMESTAMP()) ENGINE=MYISAM; +INSERT DELAYED INTO t_38726 VALUES (); +DROP TABLE t_38726; diff --git a/mysql-test/main/delete.result b/mysql-test/main/delete.result index ee1f00729d81e..f07dab64076a3 100644 --- a/mysql-test/main/delete.result +++ b/mysql-test/main/delete.result @@ -779,6 +779,22 @@ id Warnings: Warning 4207 Index hints are ignored because they are incompatible with RETURNING clause drop table t2; -# # End of 11.4 test # +# MDEV-38068 Query doesn't delete all data it should after update to 11.8.4 +# +create table t1 (id varchar(32), d1 char, key (id), key (d1)) engine=myisam; +insert into t1 values ('1','A'), ('1','B'), ('1','C'), ('2','D'), ('2','E'); +select count(*) from t1; +count(*) +5 +need "range" below +explain delete from t1 where id = '1'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range id id 131 NULL 3 Using where +delete from t1 where id = '1'; +select count(*) from t1; +count(*) +2 +drop table t1; +# End of 11.8 test diff --git a/mysql-test/main/delete.test b/mysql-test/main/delete.test index c6534f55f4941..99f05f327352d 100644 --- a/mysql-test/main/delete.test +++ b/mysql-test/main/delete.test @@ -825,6 +825,18 @@ DELETE FROM t2 ignore index(primary) ORDER BY (id) LIMIT 2 RETURNING id; drop table t2; ---echo # --echo # End of 11.4 test + --echo # +--echo # MDEV-38068 Query doesn't delete all data it should after update to 11.8.4 +--echo # +create table t1 (id varchar(32), d1 char, key (id), key (d1)) engine=myisam; +insert into t1 values ('1','A'), ('1','B'), ('1','C'), ('2','D'), ('2','E'); +select count(*) from t1; +--echo need "range" below +explain delete from t1 where id = '1'; +delete from t1 where id = '1'; +select count(*) from t1; +drop table t1; + +--echo # End of 11.8 test diff --git a/mysql-test/main/derived.result b/mysql-test/main/derived.result index 8a837b2ffde3c..1aa234e2aaba2 100644 --- a/mysql-test/main/derived.result +++ b/mysql-test/main/derived.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; ALTER DATABASE test CHARACTER SET latin1 COLLATE latin1_swedish_ci; set @save_derived_optimizer_switch=@@optimizer_switch; set optimizer_switch='derived_merge=off,derived_with_keys=off'; @@ -398,7 +397,6 @@ ID DATA FID select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID; ID DATA FID drop table t1, t2; -connection con1; disconnect con1; connection default; drop user mysqltest_1; diff --git a/mysql-test/main/derived.test b/mysql-test/main/derived.test index 1350aed6d73ea..c5c27c940c840 100644 --- a/mysql-test/main/derived.test +++ b/mysql-test/main/derived.test @@ -1,11 +1,6 @@ # Initialize --source include/default_optimizer_switch.inc --source include/have_sequence.inc - ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings - --source include/test_db_charset_latin1.inc set @save_derived_optimizer_switch=@@optimizer_switch; @@ -290,9 +285,7 @@ select t2.* from ((select * from t1) as A inner join t2 on A.ID = t2.FID); select t2.* from (select * from t1) as A inner join t2 on A.ID = t2.FID; drop table t1, t2; -connection con1; disconnect con1; ---source include/wait_until_disconnected.inc connection default; drop user mysqltest_1; @@ -1201,6 +1194,7 @@ drop table t1,t2,t3; --echo # query includes a derived table containing unnamed column --echo # (eg: `SELECT '' from t`). --echo # +--disable_view_protocol --echo # Tests from the bug report @@ -1301,6 +1295,7 @@ SELECT * FROM v6_t; DROP VIEW v1_t, v2_t, v3_t, v4_t, v5_t, v6_t; DROP TABLE t; +--enable_view_protocol --echo # End of 10.11 tests diff --git a/mysql-test/main/derived_cond_pushdown.result b/mysql-test/main/derived_cond_pushdown.result index 1f0d1514cb91d..8a03938837520 100644 --- a/mysql-test/main/derived_cond_pushdown.result +++ b/mysql-test/main/derived_cond_pushdown.result @@ -1930,7 +1930,7 @@ a b max_c avg_c a b c d explain select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.a 2 +1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.a 1 2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort explain format=json select * from v1,t2 where (v1.a=v1.b) and (v1.a=t2.a); EXPLAIN @@ -1960,7 +1960,7 @@ EXPLAIN "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.a"], "loops": 9, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "materialized": { @@ -2993,7 +2993,7 @@ where t1.a>5 group by a,b having max_c < 707) v1, t2 where (v1.a=t2.a) and (v1.max_c>300) and (v1.a=v1.b); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.a 2 Using where +1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.a 1 Using where 2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort explain format=json select * from (select a, b, max(c) as max_c, avg(c) as avg_c from t1 @@ -3026,7 +3026,7 @@ EXPLAIN "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.a"], "loops": 9, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "attached_condition": "v1.max_c > 300", @@ -3155,7 +3155,7 @@ a b max_c avg_c a b c d explain select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.b 2 +1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.b 1 2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using temporary; Using filesort explain format=json select * from v1,t2 where (v1.a=t2.a) and (v1.b=t2.b); EXPLAIN @@ -3185,7 +3185,7 @@ EXPLAIN "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.b"], "loops": 9, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "materialized": { @@ -4041,7 +4041,7 @@ explain select * from v1,v2,t2 where (v1.a=t2.a) and (v1.a=v1.b) and (v1.a=v2.a) and (v2.max_c<300); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 9 Using where -1 PRIMARY ref key1 key1 10 test.t2.a,test.t2.a 2 +1 PRIMARY ref key1 key1 10 test.t2.a,test.t2.a 1 1 PRIMARY ref key0 key0 5 test.t2.a 2 Using where 3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 2 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort @@ -4074,7 +4074,7 @@ EXPLAIN "used_key_parts": ["a", "b"], "ref": ["test.t2.a", "test.t2.a"], "loops": 9, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "materialized": { @@ -4113,7 +4113,7 @@ EXPLAIN "key_length": "5", "used_key_parts": ["a"], "ref": ["test.t2.a"], - "loops": 18, + "loops": 9, "rows": 2, "cost": "COST_REPLACED", "filtered": 100, @@ -8165,8 +8165,8 @@ a b min_c a b max_c avg_c explain select * from v4,v2 where (v4.a=v2.b) and (v4.a=v4.b) and (v4.min_c<100); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 20 Using where -1 PRIMARY ref key0 key0 5 v4.a 2 +1 PRIMARY ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY ref key0 key0 10 v2.b,v2.b 1 Using where 4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 2 DERIVED ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort @@ -8180,56 +8180,31 @@ EXPLAIN "nested_loop": [ { "table": { - "table_name": "", + "table_name": "", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "v4.b = v4.a and v4.min_c < 100 and v4.a is not null", + "attached_condition": "v2.b is not null and v2.b is not null", "materialized": { "query_block": { - "select_id": 2, + "select_id": 4, "cost": "COST_REPLACED", - "having_condition": "min_c < 100", + "having_condition": "max_c < 707", "filesort": { - "sort_key": "v1.a, v1.b", + "sort_key": "t1.a, t1.b", "temporary_table": { "nested_loop": [ { "table": { - "table_name": "", + "table_name": "t1", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "v1.b = v1.a and v1.a < 15", - "materialized": { - "query_block": { - "select_id": 3, - "cost": "COST_REPLACED", - "having_condition": "max_c < 707", - "filesort": { - "sort_key": "t1.a, t1.b", - "temporary_table": { - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ALL", - "loops": 1, - "rows": 20, - "cost": "COST_REPLACED", - "filtered": 100, - "attached_condition": "t1.b = t1.a and t1.a < 15" - } - } - ] - } - } - } - } + "attached_condition": "t1.a > 5" } } ] @@ -8241,35 +8216,61 @@ EXPLAIN }, { "table": { - "table_name": "", + "table_name": "", "access_type": "ref", "possible_keys": ["key0"], "key": "key0", - "key_length": "5", - "used_key_parts": ["b"], - "ref": ["v4.a"], + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["v2.b", "v2.b"], "loops": 20, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, + "attached_condition": "v4.min_c < 100", "materialized": { "query_block": { - "select_id": 4, + "select_id": 2, "cost": "COST_REPLACED", - "having_condition": "max_c < 707", + "having_condition": "min_c < 100", "filesort": { - "sort_key": "t1.a, t1.b", + "sort_key": "v1.a, v1.b", "temporary_table": { "nested_loop": [ { "table": { - "table_name": "t1", + "table_name": "", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "t1.a > 5" + "attached_condition": "v1.b = v1.a and v1.a < 15", + "materialized": { + "query_block": { + "select_id": 3, + "cost": "COST_REPLACED", + "having_condition": "max_c < 707", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 20, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t1.b = t1.a and t1.a < 15" + } + } + ] + } + } + } + } } } ] @@ -8296,8 +8297,8 @@ a b min_c a b max_c avg_c explain select * from v4,v2 where (v4.a=v2.b) and (v4.a=v4.b) and (v2.b<30); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 20 Using where -1 PRIMARY ref key0 key0 5 v4.a 2 +1 PRIMARY ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY ref key0 key0 10 v2.b,v2.b 1 4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 2 DERIVED ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort @@ -8311,55 +8312,31 @@ EXPLAIN "nested_loop": [ { "table": { - "table_name": "", + "table_name": "", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "v4.b = v4.a and v4.a < 30 and v4.a is not null", + "attached_condition": "v2.b < 30 and v2.b is not null and v2.b is not null", "materialized": { "query_block": { - "select_id": 2, + "select_id": 4, "cost": "COST_REPLACED", + "having_condition": "max_c < 707", "filesort": { - "sort_key": "v1.a, v1.b", + "sort_key": "t1.a, t1.b", "temporary_table": { "nested_loop": [ { "table": { - "table_name": "", + "table_name": "t1", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "v1.b = v1.a and v1.a < 15 and v1.a < 30", - "materialized": { - "query_block": { - "select_id": 3, - "cost": "COST_REPLACED", - "having_condition": "max_c < 707", - "filesort": { - "sort_key": "t1.a, t1.b", - "temporary_table": { - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ALL", - "loops": 1, - "rows": 20, - "cost": "COST_REPLACED", - "filtered": 100, - "attached_condition": "t1.b = t1.a and t1.a < 15 and t1.a < 30" - } - } - ] - } - } - } - } + "attached_condition": "t1.a > 5 and t1.b < 30" } } ] @@ -8371,35 +8348,59 @@ EXPLAIN }, { "table": { - "table_name": "", + "table_name": "", "access_type": "ref", "possible_keys": ["key0"], "key": "key0", - "key_length": "5", - "used_key_parts": ["b"], - "ref": ["v4.a"], + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["v2.b", "v2.b"], "loops": 20, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { - "select_id": 4, + "select_id": 2, "cost": "COST_REPLACED", - "having_condition": "max_c < 707", "filesort": { - "sort_key": "t1.a, t1.b", + "sort_key": "v1.a, v1.b", "temporary_table": { "nested_loop": [ { "table": { - "table_name": "t1", + "table_name": "", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "t1.a > 5 and t1.b < 30" + "attached_condition": "v1.b = v1.a and v1.a < 15 and v1.a < 30", + "materialized": { + "query_block": { + "select_id": 3, + "cost": "COST_REPLACED", + "having_condition": "max_c < 707", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 20, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t1.b = t1.a and t1.a < 15 and t1.a < 30" + } + } + ] + } + } + } + } } } ] @@ -8426,8 +8427,8 @@ a b min_c a b max_c avg_c explain select * from v4,v2 where (v4.a=v2.b) and (v4.a=v4.b) and ((v2.b<30) or (v4.a>2)); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY ALL NULL NULL NULL NULL 20 Using where -1 PRIMARY ref key0 key0 5 v4.a 2 +1 PRIMARY ALL NULL NULL NULL NULL 20 Using where +1 PRIMARY ref key0 key0 10 v2.b,v2.b 1 4 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 2 DERIVED ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort 3 DERIVED t1 ALL NULL NULL NULL NULL 20 Using where; Using temporary; Using filesort @@ -8441,55 +8442,31 @@ EXPLAIN "nested_loop": [ { "table": { - "table_name": "", + "table_name": "", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "v4.b = v4.a and (v4.a < 30 or v4.a > 2) and v4.a is not null", + "attached_condition": "(v2.b < 30 or v2.b > 2) and v2.b is not null and v2.b is not null", "materialized": { "query_block": { - "select_id": 2, + "select_id": 4, "cost": "COST_REPLACED", + "having_condition": "max_c < 707", "filesort": { - "sort_key": "v1.a, v1.b", + "sort_key": "t1.a, t1.b", "temporary_table": { "nested_loop": [ { "table": { - "table_name": "", + "table_name": "t1", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "v1.b = v1.a and v1.a < 15 and (v1.a < 30 or v1.a > 2)", - "materialized": { - "query_block": { - "select_id": 3, - "cost": "COST_REPLACED", - "having_condition": "max_c < 707", - "filesort": { - "sort_key": "t1.a, t1.b", - "temporary_table": { - "nested_loop": [ - { - "table": { - "table_name": "t1", - "access_type": "ALL", - "loops": 1, - "rows": 20, - "cost": "COST_REPLACED", - "filtered": 100, - "attached_condition": "t1.b = t1.a and t1.a < 15 and (t1.a < 30 or t1.a > 2)" - } - } - ] - } - } - } - } + "attached_condition": "t1.a > 5 and (t1.b < 30 or t1.b > 2)" } } ] @@ -8501,35 +8478,59 @@ EXPLAIN }, { "table": { - "table_name": "", + "table_name": "", "access_type": "ref", "possible_keys": ["key0"], "key": "key0", - "key_length": "5", - "used_key_parts": ["b"], - "ref": ["v4.a"], + "key_length": "10", + "used_key_parts": ["a", "b"], + "ref": ["v2.b", "v2.b"], "loops": 20, - "rows": 2, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "materialized": { "query_block": { - "select_id": 4, + "select_id": 2, "cost": "COST_REPLACED", - "having_condition": "max_c < 707", "filesort": { - "sort_key": "t1.a, t1.b", + "sort_key": "v1.a, v1.b", "temporary_table": { "nested_loop": [ { "table": { - "table_name": "t1", + "table_name": "", "access_type": "ALL", "loops": 1, "rows": 20, "cost": "COST_REPLACED", "filtered": 100, - "attached_condition": "t1.a > 5 and (t1.b < 30 or t1.b > 2)" + "attached_condition": "v1.b = v1.a and v1.a < 15 and (v1.a < 30 or v1.a > 2)", + "materialized": { + "query_block": { + "select_id": 3, + "cost": "COST_REPLACED", + "having_condition": "max_c < 707", + "filesort": { + "sort_key": "t1.a, t1.b", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "loops": 1, + "rows": 20, + "cost": "COST_REPLACED", + "filtered": 100, + "attached_condition": "t1.b = t1.a and t1.a < 15 and (t1.a < 30 or t1.a > 2)" + } + } + ] + } + } + } + } } } ] @@ -20148,7 +20149,7 @@ where t2.b < 40 and t2.a=t3.a and t3.c=t.c; id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 90 60.00 Using where 1 PRIMARY t3 ref idx_a idx_a 5 test.t2.a 1 100.00 Using where -1 PRIMARY ref key0 key0 128 test.t3.c 5 100.00 +1 PRIMARY ref key0 key0 128 test.t3.c 1 100.00 2 DERIVED t4 ALL idx_c NULL NULL NULL 160 100.00 Using temporary; Using filesort Warnings: Note 1003 /* select#1 */ select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`t`.`c` AS `t_c`,`t`.`max` AS `max`,`t`.`min` AS `min` from `test`.`t2` join `test`.`t3` join (/* select#2 */ select `test`.`t4`.`c` AS `c`,max(`test`.`t4`.`b`) AS `max`,min(`test`.`t4`.`b`) AS `min` from `test`.`t4` group by `test`.`t4`.`c`) `t` where `test`.`t3`.`a` = `test`.`t2`.`a` and `t`.`c` = `test`.`t3`.`c` and `test`.`t2`.`b` < 40 @@ -20198,7 +20199,7 @@ EXPLAIN "used_key_parts": ["c"], "ref": ["test.t3.c"], "loops": 80.99999987, - "rows": 5, + "rows": 1, "cost": "COST_REPLACED", "filtered": 100, "materialized": { @@ -21318,7 +21319,7 @@ id a explain extended select id, a from t1 where id in (select id from v1); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 20 100.00 -1 PRIMARY ref key0 key0 4 test.t1.id 2 50.00 FirstMatch(t1) +1 PRIMARY ref key0 key0 4 test.t1.id 1 100.00 FirstMatch(t1) 3 DERIVED t1 ALL PRIMARY NULL NULL NULL 20 100.00 Using temporary; Using filesort 3 DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where Warnings: @@ -21356,7 +21357,7 @@ on (t1.id = t2.ro_id AND t2.flag = 1) group by t1.id) dt); id select_type table type possible_keys key key_len ref rows filtered Extra 1 PRIMARY t1 ALL PRIMARY NULL NULL NULL 20 100.00 -1 PRIMARY ref key1,distinct_key key1 4 test.t1.id 2 50.00 FirstMatch(t1) +1 PRIMARY ref key1,distinct_key key1 4 test.t1.id 1 100.00 FirstMatch(t1) 3 DERIVED t1 ALL PRIMARY NULL NULL NULL 20 100.00 Using temporary; Using filesort 3 DERIVED t2 ref ro_id ro_id 4 test.t1.id 1 100.00 Using where Warnings: @@ -22025,7 +22026,7 @@ WHERE t1.id BETWEEN 200 AND 100000; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 range t1_id t1_id 5 NULL 47 Using where; Using index 1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 test.t3.t1_id 1 Using index -1 PRIMARY ref key0 key0 5 test.t3.t1_id 10 +1 PRIMARY ref key0 key0 5 test.t3.t1_id 1 2 DERIVED t2 ALL t1_id NULL NULL NULL 2408 Using where; Using temporary; Using filesort set optimizer_switch='split_materialized=default'; DROP TABLE t1,t2,t3; @@ -22302,7 +22303,7 @@ from_agg_items.ledger_id = charges.from_ledger_id WHERE charges.to_ledger_id = 2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY charges ref PRIMARY,fk_charge_from_ledger,fk_charge_to_ledger fk_charge_to_ledger 8 const 8 -1 PRIMARY ref key0 key0 17 test.charges.from_ledger_id,test.charges.id 4 +1 PRIMARY ref key0 key0 17 test.charges.from_ledger_id,test.charges.id 1 2 DERIVED transaction_items ALL fk_items_transaction NULL NULL NULL 40 Using temporary; Using filesort 2 DERIVED transactions eq_ref PRIMARY PRIMARY 8 test.transaction_items.transaction_id 1 INSERT INTO charges (id, from_ledger_id, to_ledger_id, amount) VALUES @@ -22507,7 +22508,7 @@ from_agg_items.ledger_id = charges.from_ledger_id WHERE charges.to_ledger_id = 2; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY charges ref fk_charge_to_ledger fk_charge_to_ledger 8 const 10 -1 PRIMARY ref key0 key0 18 test.charges.from_ledger_id,test.charges.id 4 +1 PRIMARY ref key0 key0 18 test.charges.from_ledger_id,test.charges.id 1 2 DERIVED transaction_items ALL fk_items_transaction NULL NULL NULL 40 Using temporary; Using filesort 2 DERIVED transactions eq_ref PRIMARY PRIMARY 8 test.transaction_items.transaction_id 1 set optimizer_switch='split_materialized=default'; @@ -22845,6 +22846,8 @@ INSERT INTO t1 VALUES (95,3290880,487,'2021-02-15 18:59:35'),(96,3290798,0,'2021-02-15 18:59:52'), (97,3290777,983,'2021-02-15 19:00:10'),(98,3290811,488,'2021-02-15 19:00:10'), (99,3290917,1283,'2021-02-15 19:00:36'),(100,3290858,482,'2021-02-15 19:00:42'); +insert into t1 select seq, 3300000+seq, 100+seq, '2021-02-09 18:31:35' +from seq_101_to_1000; CREATE TABLE t2 (a int) ENGINE=MYISAM; INSERT INTO t2 VALUES (3289475),(3289496),(3289562),(3289593),(3289594),(3289595),(3289626), @@ -22853,7 +22856,7 @@ INSERT INTO t2 VALUES ANALYZE TABLE t1,t2; Table Op Msg_type Msg_text test.t1 analyze status Engine-independent statistics collected -test.t1 analyze status Table is already up to date +test.t1 analyze status OK test.t2 analyze status Engine-independent statistics collected test.t2 analyze status OK EXPLAIN SELECT t1.valdouble, t1.valint1 @@ -22865,9 +22868,9 @@ t1.valdate = dt.maxdate AND t1.valint1 IN (SELECT * FROM t2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 ALL NULL NULL NULL NULL 21 Using where; Start temporary -1 PRIMARY t1 ref valint1,valint1_2 valint1 5 test.t2.a 2 Using index condition; Using where; End temporary +1 PRIMARY t1 ref valint1,valint1_2 valint1 5 test.t2.a 1 Using index condition; Using where; End temporary 1 PRIMARY ref key0 key0 11 test.t1.valdate,test.t1.valint1 1 -2 LATERAL DERIVED t ref valint1,valint1_2 valint1 5 test.t2.a 2 Using index condition +2 LATERAL DERIVED t ref valint1,valint1_2 valint1 5 test.t2.a 1 Using index condition SELECT t1.valdouble, t1.valint1 FROM t1, (SELECT max(t.valdate) AS maxdate, t.valint1 FROM t1 t GROUP BY t.valint1) @@ -23629,6 +23632,113 @@ a drop table t; # End of 10.5 tests # +# MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +# +CREATE TABLE t (a INT, b INT); +INSERT INTO t VALUES (1, 10), (1, 20), (2, 50), (3, 100); +explain format=JSON SELECT * FROM (SELECT a, MAX(b) as max_b FROM t GROUP BY a) as dt WHERE dt.max_b > 25; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.010178738, + "nested_loop": [ + { + "table": { + "table_name": "", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": 0.010178738, + "filtered": 100, + "attached_condition": "dt.max_b > 25", + "materialized": { + "query_block": { + "select_id": 2, + "cost": 0.013196268, + "having_condition": "max_b > 25", + "filesort": { + "sort_key": "t.a", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": 0.01066122, + "filtered": 100 + } + } + ] + } + } + } + } + } + } + ] + } +} +SELECT * FROM (SELECT a, MAX(b) as max_b FROM t GROUP BY a) as dt WHERE dt.max_b > 25; +a max_b +2 50 +3 100 +CREATE VIEW v AS SELECT a, MAX(b) as max_b FROM t GROUP BY a; +explain format=JSON SELECT * FROM v where max_b > 25; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.010178738, + "nested_loop": [ + { + "table": { + "table_name": "", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": 0.010178738, + "filtered": 100, + "attached_condition": "v.max_b > 25", + "materialized": { + "query_block": { + "select_id": 2, + "cost": 0.013196268, + "having_condition": "max_b > 25", + "filesort": { + "sort_key": "t.a", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t", + "access_type": "ALL", + "loops": 1, + "rows": 4, + "cost": 0.01066122, + "filtered": 100 + } + } + ] + } + } + } + } + } + } + ] + } +} +SELECT * FROM v where max_b > 25; +a max_b +2 50 +3 100 +DROP VIEW v; +DROP TABLE t; +# End of 10.6 tests +# # MDEV-28958: condition pushable into view after simplification # contains constant TRUE/FALSE as subformula # @@ -23645,3 +23755,14 @@ a b drop view v1,v2; drop table t1,t2; # End of 10.7 tests +# +# MDEV-36686: Crash with DEFAULT() in WHERE clause with nested views +# +create table t1 (a varchar(128)); +create view v1 as select a, count(*) from t1 group by a; +create view v2 as select * from v1; +select * from v2 where greatest(a, default(a)); +a count(*) +drop view v2, v1; +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/derived_cond_pushdown.test b/mysql-test/main/derived_cond_pushdown.test index 45840e710a313..0714dab783361 100644 --- a/mysql-test/main/derived_cond_pushdown.test +++ b/mysql-test/main/derived_cond_pushdown.test @@ -4280,6 +4280,9 @@ INSERT INTO t1 VALUES (97,3290777,983,'2021-02-15 19:00:10'),(98,3290811,488,'2021-02-15 19:00:10'), (99,3290917,1283,'2021-02-15 19:00:36'),(100,3290858,482,'2021-02-15 19:00:42'); +insert into t1 select seq, 3300000+seq, 100+seq, '2021-02-09 18:31:35' +from seq_101_to_1000; + CREATE TABLE t2 (a int) ENGINE=MYISAM; INSERT INTO t2 VALUES (3289475),(3289496),(3289562),(3289593),(3289594),(3289595),(3289626), @@ -4495,6 +4498,28 @@ drop table t; --echo # End of 10.5 tests +--echo # +--echo # MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +--echo # + +CREATE TABLE t (a INT, b INT); +INSERT INTO t VALUES (1, 10), (1, 20), (2, 50), (3, 100); + +# outer where to inner having pushdown +let $q= SELECT * FROM (SELECT a, MAX(b) as max_b FROM t GROUP BY a) as dt WHERE dt.max_b > 25; +eval explain format=JSON $q; +eval $q; + +CREATE VIEW v AS SELECT a, MAX(b) as max_b FROM t GROUP BY a; +let $q= SELECT * FROM v where max_b > 25; +eval explain format=JSON $q; +eval $q; + +DROP VIEW v; +DROP TABLE t; + +--echo # End of 10.6 tests + --echo # --echo # MDEV-28958: condition pushable into view after simplification --echo # contains constant TRUE/FALSE as subformula @@ -4515,3 +4540,18 @@ drop view v1,v2; drop table t1,t2; --echo # End of 10.7 tests + +--echo # +--echo # MDEV-36686: Crash with DEFAULT() in WHERE clause with nested views +--echo # + +create table t1 (a varchar(128)); +create view v1 as select a, count(*) from t1 group by a; +create view v2 as select * from v1; + +select * from v2 where greatest(a, default(a)); + +drop view v2, v1; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/derived_opt.result b/mysql-test/main/derived_opt.result index 446de335131de..984c8070870d0 100644 --- a/mysql-test/main/derived_opt.result +++ b/mysql-test/main/derived_opt.result @@ -566,4 +566,501 @@ DROP TABLE t1, t2; # # End of 10.3 tests # +# +# MDEV-36321 keys generated on derived tables produce wrong out_rows estimates +# +create table t1 ( +grp_id int, +value int, +index (grp_id) +); +insert into t1 select +A.seq, B.seq +from +seq_1_to_100 A, +seq_1_to_100 B; +create table t2 (a int); +insert into t2 select seq from seq_1_to_5; +create table t3 (b int); +insert into t3 select seq from seq_1_to_5; +analyze table t1,t2; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +SET optimizer_trace='enabled=on'; +SET optimizer_trace_max_mem_size=10485760; +select * from +t2, +(select max(value), grp_id from t1 group by grp_id) DT +where +t2.a= DT.grp_id; +a max(value) grp_id +1 100 1 +2 100 2 +3 100 3 +4 100 4 +5 100 5 +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "DT", + "key_name": "key0", + "key_parts": 1, + "select": + ["group_list_in_key"], + "rec_per_key_estimate": 1 + } +] +# Same as above, but try a UNION: +select * from +t2, +(select max(value), grp_id from t1 group by grp_id +union all +select max(value), grp_id from t1 group by grp_id) DT +where +t2.a= DT.grp_id; +a max(value) grp_id +1 100 1 +1 100 1 +2 100 2 +2 100 2 +3 100 3 +3 100 3 +4 100 4 +4 100 4 +5 100 5 +5 100 5 +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "DT", + "key_name": "key0", + "key_parts": 1, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + } +] +# Same as the previous query but unhandled group by expression +explain +select * from +t2, +(select max(value), grp_id from t1 group by grp_id +union all +select max(value), grp_id from t1 group by MOD(grp_id,2)) DT +where +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 101 +2 DERIVED t1 ALL NULL NULL NULL NULL 10000 Using temporary; Using filesort +3 UNION t1 ALL NULL NULL NULL NULL 10000 Using temporary; Using filesort +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "DT", + "key_name": "key0", + "key_parts": 1, + "select": + [ + "group_list_in_key", + "unhandled query" + ] + } +] +# view/cte/derived merged inside our derived table +create view v1 as select * from t1; +explain +select * from +t2, +(select grp_id, max(value) as maxval from v1 group by grp_id) DT +where +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 +2 DERIVED t1 ALL grp_id NULL NULL NULL 10000 Using temporary; Using filesort +drop view v1; +explain +with cte1 as (select * from t1) +select * from +t2, +(select grp_id, max(value) as maxval from cte1 group by grp_id) DT +where +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 +3 DERIVED t1 ALL grp_id NULL NULL NULL 10000 Using temporary; Using filesort +explain +select * from +t2, +( +select grp_id, max(value) as maxval from +( +select * from t1, t3 +where t1.grp_id = t3.b +) dt1 +group by grp_id +) DT +where +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 1 +2 DERIVED t3 ALL NULL NULL NULL NULL 5 Using where; Using temporary; Using filesort +2 DERIVED t1 ref grp_id grp_id 5 test.t3.b 100 +# Example with equalities on GROUP BY columns and other columns +# Must produce {table=, ref=test.t2.col2,test.t2.a, rows=1} +alter table t2 add col2 int; +explain +select * from +t2, +(select max(value) as maxval, grp_id from t1 group by grp_id) DT +where +t2.col2=maxval and +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 10 test.t2.col2,test.t2.a 1 +2 DERIVED t1 ALL grp_id NULL NULL NULL 10000 Using temporary; Using filesort +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "DT", + "key_name": "key0", + "key_parts": 2, + "select": + ["group_list_in_key"], + "rec_per_key_estimate": 1 + } +] +explain +select * from +t2, +(select grp_id, max(value) as maxval from t1 group by grp_id) DT +where +t2.col2=maxval and +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.col2 1 +2 DERIVED t1 ALL grp_id NULL NULL NULL 10000 Using temporary; Using filesort +delete from t1; +insert into t1 select 1, a.seq from seq_1_to_10 a; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +explain +select * from +t2, +(select distinct grp_id from t1 +union all +select distinct value from t1) DT +where +t2.a= DT.grp_id; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 ALL NULL NULL NULL NULL 5 Using where +1 PRIMARY ref key0 key0 5 test.t2.a 2 +2 DERIVED t1 range NULL grp_id 5 NULL 2 Using index for group-by +3 UNION t1 ALL NULL NULL NULL NULL 10 Using temporary +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "DT", + "key_name": "key0", + "key_parts": 1, + "select": + [ + "distinct_in_query_block", + "distinct_in_query_block" + ], + "rec_per_key_estimate": 2 + } +] +drop table t1, t2; +create table t1 +( +a int not null, +b int, +c int, +d int, +amount decimal, +key t1_ix1 (a,b) +); +# More complex examples +insert into t1 values (0, NULL, 0, NULL, 10.0000), (1, 1, 1, 1, 10.0000), +(2, 2, 2, 2, 20.0000), (3, 3, 3, 3, 30.0000), (4, 4, 4, 4, 40.0000), +(5, 5, 5, 5, NULL), (6, 6, 6, 6, NULL), (7, 7, 7, 7, 70.0000), +(8, 8, 8, 8, 80.0000); +create table t2 +( +a int NOT NULL, +b int, +name varchar(50), +key t2_ix1 (a,b) +) engine = innodb; +insert into t2 values (0, NULL, 'a'), (1, NULL, 'A'), (2, 2, 'B'), (3,3, 'C'), +(4,4, 'D'), (5,5, NULL), (6,6, NULL), (7,7, 'E'), (8,8, 'F'), (9,9, 'G'), +(10,10,'H'), (11,11, NULL), (12,12, NULL); +drop table t3; +create table t3 +( +a int not null, +b int, +description varchar(50), +key t3_ix1 (a,b) +) engine = innodb; +insert into t3 values (1, 1, 'bar'),(2,2,'buz'), (3,3, 'silver'); +insert into t3 select seq, seq, 'junk' from seq_3_to_13; +create table t4 +( +c int not null, +d int, +descr varchar(50), +key t4_ix1 (c,d) +) engine = innodb; +insert into t4 values (1, 1, 'iron'), (2,2,'aluminium'), (3,3, 'silver'); +insert into t4 select seq, seq, 'junk' from seq_3_to_13; +# split materialized +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( +select a, b, description from t3 group by a, b +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_ix1 t1_ix1 4 NULL 1 Using index condition +1 PRIMARY t2 ref t2_ix1 t2_ix1 9 test.t1.a,test.t1.b 1 +1 PRIMARY ref key0 key0 9 test.t1.a,test.t1.b 1 +2 LATERAL DERIVED t3 ref t3_ix1 t3_ix1 9 test.t1.a,test.t1.b 1 Using index condition +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "dt", + "key_name": "key0", + "key_parts": 2, + "select": + ["group_list_in_key"], + "rec_per_key_estimate": 1 + }, + { + "table_alias": "dt", + "key_name": "key1", + "key_parts": 2, + "select": + ["group_list_in_key"], + "rec_per_key_estimate": 1 + } +] +# union with distinct rows +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( +select a, b, description from t3 group by a, b +union +select c, d, descr from t4 group by c, d +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_ix1 t1_ix1 4 NULL 1 Using index condition +1 PRIMARY t2 ref t2_ix1 t2_ix1 9 test.t1.a,test.t1.b 1 +1 PRIMARY ref key1,distinct_key key1 9 test.t1.a,test.t1.b 2 +2 DERIVED t3 range t3_ix1 t3_ix1 4 NULL 1 Using index condition +3 UNION t4 range t4_ix1 t4_ix1 4 NULL 1 Using index condition +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "dt", + "key_name": "key1", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + }, + { + "table_alias": "dt", + "key_name": "key2", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + } +] +# union without distinct rows +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( +select a, b, description from t3 group by a, b +union all +select c, d, descr from t4 group by c, d +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_ix1 t1_ix1 4 NULL 1 Using index condition +1 PRIMARY t2 ref t2_ix1 t2_ix1 9 test.t1.a,test.t1.b 1 +1 PRIMARY ref key0 key0 9 test.t1.a,test.t1.b 2 +2 DERIVED t3 range t3_ix1 t3_ix1 4 NULL 1 Using index condition +3 UNION t4 range t4_ix1 t4_ix1 4 NULL 1 Using index condition +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "dt", + "key_name": "key0", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + }, + { + "table_alias": "dt", + "key_name": "key1", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + } +] +# union without distinct rows with simple non grouping 2nd select +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( +select a, b, description from t3 group by a, b +union all +select c, d, descr from t4 +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_ix1 t1_ix1 4 NULL 1 Using index condition +1 PRIMARY t2 ref t2_ix1 t2_ix1 9 test.t1.a,test.t1.b 1 +1 PRIMARY ref key0 key0 9 test.t1.a,test.t1.b 1 +2 DERIVED t3 range t3_ix1 t3_ix1 4 NULL 1 Using index condition +3 UNION t4 range t4_ix1 t4_ix1 4 NULL 1 Using index condition +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "dt", + "key_name": "key0", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "unhandled query" + ] + }, + { + "table_alias": "dt", + "key_name": "key1", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "unhandled query" + ] + } +] +# intersect +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( +select a, b, description from t3 group by a, b +intersect +select c, d, descr from t4 group by c, d +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a > 2 and dt.a < 4; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 range t1_ix1 t1_ix1 4 NULL 1 Using index condition +1 PRIMARY t2 ref t2_ix1 t2_ix1 9 test.t1.a,test.t1.b 1 +1 PRIMARY ref key1,distinct_key key1 9 test.t1.a,test.t1.b 2 +2 DERIVED t3 range t3_ix1 t3_ix1 4 NULL 2 Using index condition +3 INTERSECT t4 range t4_ix1 t4_ix1 4 NULL 2 Using index condition +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +select +json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; +t +[ + { + "table_alias": "dt", + "key_name": "key1", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + }, + { + "table_alias": "dt", + "key_name": "key2", + "key_parts": 2, + "select": + [ + "group_list_in_key", + "group_list_in_key" + ], + "rec_per_key_estimate": 2 + } +] +drop table t1, t2, t3, t4; +# +# End of 11.4 tests +# set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/main/derived_opt.test b/mysql-test/main/derived_opt.test index 778a4f0dbe82b..99c18a840d17e 100644 --- a/mysql-test/main/derived_opt.test +++ b/mysql-test/main/derived_opt.test @@ -1,4 +1,6 @@ # Initialize +--source include/not_embedded.inc +--source include/have_innodb.inc --disable_warnings drop table if exists t0,t1,t2,t3; drop database if exists test1; @@ -439,5 +441,277 @@ DROP TABLE t1, t2; --echo # End of 10.3 tests --echo # +--echo # +--echo # MDEV-36321 keys generated on derived tables produce wrong out_rows estimates +--echo # +--source include/have_sequence.inc + +create table t1 ( + grp_id int, + value int, + index (grp_id) +); + +insert into t1 select + A.seq, B.seq +from + seq_1_to_100 A, + seq_1_to_100 B; + +create table t2 (a int); +insert into t2 select seq from seq_1_to_5; + +create table t3 (b int); +insert into t3 select seq from seq_1_to_5; + +analyze table t1,t2; + +SET optimizer_trace='enabled=on'; +SET optimizer_trace_max_mem_size=10485760; + +select * from + t2, + (select max(value), grp_id from t1 group by grp_id) DT +where + t2.a= DT.grp_id; + +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + + +--echo # Same as above, but try a UNION: +select * from + t2, + (select max(value), grp_id from t1 group by grp_id + union all + select max(value), grp_id from t1 group by grp_id) DT +where + t2.a= DT.grp_id; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +--echo # Same as the previous query but unhandled group by expression +explain +select * from + t2, + (select max(value), grp_id from t1 group by grp_id + union all + select max(value), grp_id from t1 group by MOD(grp_id,2)) DT +where + t2.a= DT.grp_id; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +--echo # view/cte/derived merged inside our derived table + +create view v1 as select * from t1; + +explain +select * from + t2, + (select grp_id, max(value) as maxval from v1 group by grp_id) DT +where + t2.a= DT.grp_id; + +drop view v1; + +explain +with cte1 as (select * from t1) +select * from + t2, + (select grp_id, max(value) as maxval from cte1 group by grp_id) DT +where + t2.a= DT.grp_id; + +explain +select * from + t2, + ( + select grp_id, max(value) as maxval from + ( + select * from t1, t3 + where t1.grp_id = t3.b + ) dt1 + group by grp_id + ) DT +where + t2.a= DT.grp_id; + +--echo # Example with equalities on GROUP BY columns and other columns +--echo # Must produce {table=, ref=test.t2.col2,test.t2.a, rows=1} +alter table t2 add col2 int; +explain +select * from + t2, + (select max(value) as maxval, grp_id from t1 group by grp_id) DT +where + t2.col2=maxval and + t2.a= DT.grp_id; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +# Same as above but swap the column order. +# Now we'll get {table=, ref=test.t2.a,test.t2.col2, rows=1} +explain +select * from + t2, + (select grp_id, max(value) as maxval from t1 group by grp_id) DT +where + t2.col2=maxval and + t2.a= DT.grp_id; + + +delete from t1; +insert into t1 select 1, a.seq from seq_1_to_10 a; + +analyze table t1; + +explain +select * from + t2, + (select distinct grp_id from t1 + union all + select distinct value from t1) DT +where + t2.a= DT.grp_id; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +drop table t1, t2; + +create table t1 +( + a int not null, + b int, + c int, + d int, + amount decimal, + key t1_ix1 (a,b) +); + +--echo # More complex examples +insert into t1 values (0, NULL, 0, NULL, 10.0000), (1, 1, 1, 1, 10.0000), +(2, 2, 2, 2, 20.0000), (3, 3, 3, 3, 30.0000), (4, 4, 4, 4, 40.0000), +(5, 5, 5, 5, NULL), (6, 6, 6, 6, NULL), (7, 7, 7, 7, 70.0000), +(8, 8, 8, 8, 80.0000); + +create table t2 +( + a int NOT NULL, + b int, + name varchar(50), + key t2_ix1 (a,b) +) engine = innodb; + +insert into t2 values (0, NULL, 'a'), (1, NULL, 'A'), (2, 2, 'B'), (3,3, 'C'), +(4,4, 'D'), (5,5, NULL), (6,6, NULL), (7,7, 'E'), (8,8, 'F'), (9,9, 'G'), +(10,10,'H'), (11,11, NULL), (12,12, NULL); + +drop table t3; + +create table t3 +( + a int not null, + b int, + description varchar(50), + key t3_ix1 (a,b) +) engine = innodb; +insert into t3 values (1, 1, 'bar'),(2,2,'buz'), (3,3, 'silver'); +insert into t3 select seq, seq, 'junk' from seq_3_to_13; + +create table t4 +( + c int not null, + d int, + descr varchar(50), + key t4_ix1 (c,d) +) engine = innodb; +insert into t4 values (1, 1, 'iron'), (2,2,'aluminium'), (3,3, 'silver'); +insert into t4 select seq, seq, 'junk' from seq_3_to_13; + +--echo # split materialized +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( + select a, b, description from t3 group by a, b +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +--echo # union with distinct rows +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( + select a, b, description from t3 group by a, b + union + select c, d, descr from t4 group by c, d +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +--echo # union without distinct rows +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( + select a, b, description from t3 group by a, b + union all + select c, d, descr from t4 group by c, d +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +--echo # union without distinct rows with simple non grouping 2nd select +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( + select a, b, description from t3 group by a, b + union all + select c, d, descr from t4 +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a < 1; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +--echo # intersect +explain +select * from t1 +join t2 on t1.a = t2.a and t1.b = t2.b +join +( + select a, b, description from t3 group by a, b + intersect + select c, d, descr from t4 group by c, d +) dt on dt.a = t1.a and dt.b = t1.b and dt.b = t2.b +where dt.a > 2 and dt.a < 4; +select + json_detailed(json_extract(trace, '$**.infer_derived_key_statistics')) as t +from information_schema.optimizer_trace; + +drop table t1, t2, t3, t4; + +--echo # +--echo # End of 11.4 tests +--echo # + # The following command must be the last one the file set optimizer_switch=@exit_optimizer_switch; diff --git a/mysql-test/main/derived_split_innodb.result b/mysql-test/main/derived_split_innodb.result index 809b15859bbae..6951da7371816 100644 --- a/mysql-test/main/derived_split_innodb.result +++ b/mysql-test/main/derived_split_innodb.result @@ -283,7 +283,7 @@ on t3.a=t.a and t3.c=t.c where t3.b > 15; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t3 range idx_b idx_b 5 NULL 2 Using index condition; Using where -1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 2 +1 PRIMARY ref key0 key0 133 test.t3.a,test.t3.c 1 2 DERIVED t4 ALL NULL NULL NULL NULL 40 Using filesort drop table t3, t4; # End of 10.3 tests @@ -348,7 +348,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1 PRIMARY t2 ref a a 5 test.t1.b 2 Using where 1 PRIMARY t3 ref a a 5 test.t1.b 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 LATERAL DERIVED t10 ref grp_id grp_id 5 test.t1.b 100 2 LATERAL DERIVED t11 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) # The important part in the below output is: @@ -449,7 +449,7 @@ ANALYZE "ref": ["test.t1.b"], "loops": 30, "r_loops": 30, - "rows": 10, + "rows": 1, "r_rows": 1, "cost": "REPLACED", "r_table_time_ms": "REPLACED", @@ -546,7 +546,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1 PRIMARY t2 ref a a 5 test.t1.b 2 Using where 1 PRIMARY t3 ref a a 5 test.t1.b 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 LATERAL DERIVED t10 ref grp_id grp_id 5 test.t1.b 100 2 LATERAL DERIVED t11 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) explain @@ -568,7 +568,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1 PRIMARY t2 ref a a 5 test.t1.b 2 Using where 1 PRIMARY t3 ref a a 5 test.t1.b 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 LATERAL DERIVED t22 const PRIMARY PRIMARY 4 const 1 Using index 2 LATERAL DERIVED t10 ref grp_id grp_id 5 test.t1.b 100 2 LATERAL DERIVED t11 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) @@ -596,7 +596,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t5 eq_ref PRIMARY PRIMARY 4 test.t1.b 1 Using index 1 PRIMARY t2 ref a a 5 test.t1.b 2 1 PRIMARY t3 ref a a 5 test.t1.b 3 -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 LATERAL DERIVED t22 const PRIMARY PRIMARY 4 const 1 Using index 2 LATERAL DERIVED t10 ref grp_id grp_id 5 test.t5.pk 100 Using index condition 2 LATERAL DERIVED t11 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) @@ -660,7 +660,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1 PRIMARY t2 ref a a 5 test.t1.b 2 Using where 1 PRIMARY t3 ref a a 5 test.t1.b 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 LATERAL DERIVED t10 ref grp_id grp_id 5 test.t1.b 100 2 LATERAL DERIVED t11 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) select * @@ -737,7 +737,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1 PRIMARY t2 ref a a 5 test.t1.b 2 Using where 1 PRIMARY t3 ref a a 5 test.t1.b 3 Using where -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 LATERAL DERIVED t10 ref grp_id grp_id 5 test.t1.b 100 2 LATERAL DERIVED t11 hash_ALL NULL #hash#$hj 5 test.t10.col1 100 Using where; Using join buffer (flat, BNLH join) select * @@ -815,7 +815,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 5 1 PRIMARY t2 ALL NULL NULL NULL NULL 50 Using where; Using join buffer (flat, BNL join) 1 PRIMARY t3 ALL NULL NULL NULL NULL 15 Using where; Using join buffer (incremental, BNL join) -1 PRIMARY ref key0 key0 5 test.t1.b 10 Using where +1 PRIMARY ref key0 key0 5 test.t1.b 1 Using where 2 DERIVED t10 ALL grp_id NULL NULL NULL 10000 Using temporary; Using filesort 2 DERIVED t11 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join) select * @@ -997,10 +997,110 @@ T.grp_id=v1.COL10; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 ALL NULL NULL NULL NULL 2 1 PRIMARY t2 ref a a 5 test.t1.a 1 Using where; Using index -1 PRIMARY ref key0 key0 5 func 10 Using where +1 PRIMARY ref key0 key0 5 func 1 Using where 2 DERIVED t10 index grp_id grp_id 5 NULL 10000 Using index; Using temporary; Using filesort drop table t1,t2, t10; drop view v1; +# +# MDEV-37407 Wrong result with LATERAL DERIVED +# +CREATE TABLE t1 ( +a int NOT NULL, +b int default null, +amount decimal DEFAULT NULL, +KEY t1_IDX (a,b) USING BTREE +) ENGINE=INNODB; +CREATE TABLE t2 ( +a int NOT NULL, +b int default null, +name varchar(50) DEFAULT NULL, +KEY t2_IDX (a,b) USING BTREE +) ENGINE=INNODB; +INSERT INTO t1 VALUES +(1, NULL, 10.0000), (2, 2, 20.0000), (3, 3, 30.0000), (4, 4, 40.0000), +(5, 5, NULL), (6, 6, NULL), (7, 7, 70.0000), (8, 8, 80.0000); +INSERT INTO t2 VALUES +(1, NULL, 'A'), (2,2, 'B'), (3,3, 'C'), (4,4, 'D'), (5,5, NULL), (6,6, NULL), +(7,7, 'E'), (8,8, 'F'), (9,9, 'G'), (10,10,'H'), (11,11, NULL), (12,12, NULL); +# Must use Split-Materialized: +explain $query; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t2 range t2_IDX t2_IDX 4 NULL 1 Using index condition +1 PRIMARY ref key0 key0 10 test.t2.a,test.t2.b 1 Using where +2 LATERAL DERIVED t1 ref t1_IDX t1_IDX 9 test.t2.a,test.t2.b 1 Using index condition +$query; +a b name total_amt +1 NULL A 10 +# Compare with correct result: +set statement optimizer_switch='split_materialized=off' for $query; +a b name total_amt +1 NULL A 10 +DROP TABLE t1,t2; +# +# MDEV-37407 Wrong result with ORDER BY LIMIT +# Both, with and without split_materialized should +# produce the same results +# +SET @save_optimizer_switch= @@optimizer_switch; +CREATE TABLE t1 +(a varchar(35), b varchar(4), KEY (a)) +ENGINE=InnoDB; +INSERT INTO t1 VALUES +('Albania','AXA'), ('Australia','AUS'), ('Myanmar','MMR'), +('Bahamas','BS'), ('Brazil','BRA'), ('Barbados','BRB'); +CREATE TABLE t2 +(a varchar(4), b varchar(50), PRIMARY KEY (b,a), KEY (a)) +ENGINE=InnoDB; +INSERT INTO t2 VALUES +('AUS','Anglican'), ('MMR','Baptist'), ('BS','Anglican'), +('BS','Baptist'), ('BS','Methodist'), ('BRB','Methodist'), +('BRA','Baptist'), ('USA','Baptist'); +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 +ANALYZE TABLE t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +set optimizer_switch='split_materialized=off'; +SELECT t1.a +FROM (SELECT a FROM t2 GROUP BY a ORDER BY a, COUNT(DISTINCT b) LIMIT 1) dt +JOIN t1 ON +dt.a=t1.b +WHERE t1.a LIKE 'B%'; +a +set optimizer_switch='split_materialized=on'; +SELECT t1.a +FROM (SELECT a FROM t2 GROUP BY a ORDER BY a, COUNT(DISTINCT b) LIMIT 1) dt +JOIN t1 ON +dt.a=t1.b +WHERE t1.a LIKE 'B%'; +a +DROP TABLE t1,t2; +SET optimizer_switch= @save_optimizer_switch; +# +# MDEV-29638 Crash when considering Split-Materialized plan +# +set @save_optimizer_switch= @@optimizer_switch; +set optimizer_switch='condition_pushdown_for_derived=off,split_materialized=on'; +CREATE TABLE t1 (id int PRIMARY KEY)engine=innodb; +CREATE TABLE t2 (id int PRIMARY KEY, c int) engine=innodb; +CREATE TABLE t3 (id int PRIMARY KEY, a int , b int, KEY (a))engine=innodb; +SELECT * FROM +( +SELECT DISTINCT t1.id +FROM t1 JOIN +( +SELECT t2.id FROM t2 JOIN t3 +ON t3.id = t2.c +WHERE (t3.a > 2 AND t3.b = 2) +GROUP BY t2.id +) m2 ON m2.id = t1.id +) dt; +id +drop table t1, t2, t3; +SET optimizer_switch= @save_optimizer_switch; # End of 10.11 tests # # MDEV-37057 Wrong result with LATERAL DERIVED diff --git a/mysql-test/main/derived_split_innodb.test b/mysql-test/main/derived_split_innodb.test index ead2796165cd6..207d5e084d4a2 100644 --- a/mysql-test/main/derived_split_innodb.test +++ b/mysql-test/main/derived_split_innodb.test @@ -590,6 +590,119 @@ where drop table t1,t2, t10; drop view v1; +--echo # +--echo # MDEV-37407 Wrong result with LATERAL DERIVED +--echo # + +CREATE TABLE t1 ( + a int NOT NULL, + b int default null, + amount decimal DEFAULT NULL, + KEY t1_IDX (a,b) USING BTREE +) ENGINE=INNODB; + +CREATE TABLE t2 ( + a int NOT NULL, + b int default null, + name varchar(50) DEFAULT NULL, + KEY t2_IDX (a,b) USING BTREE +) ENGINE=INNODB; + +INSERT INTO t1 VALUES +(1, NULL, 10.0000), (2, 2, 20.0000), (3, 3, 30.0000), (4, 4, 40.0000), +(5, 5, NULL), (6, 6, NULL), (7, 7, 70.0000), (8, 8, 80.0000); + +INSERT INTO t2 VALUES +(1, NULL, 'A'), (2,2, 'B'), (3,3, 'C'), (4,4, 'D'), (5,5, NULL), (6,6, NULL), +(7,7, 'E'), (8,8, 'F'), (9,9, 'G'), (10,10,'H'), (11,11, NULL), (12,12, NULL); + +let $query= +SELECT t2.a,t2.b,t2.name,t.total_amt FROM t2 +LEFT JOIN +( + SELECT a, b, sum(amount) total_amt FROM t1 GROUP BY a, b +) AS t ON t2.a=t.a and t2.b<=>t.b +WHERE t2.a < 2; + +--echo # Must use Split-Materialized: +evalp explain $query; +evalp $query; +--echo # Compare with correct result: +evalp set statement optimizer_switch='split_materialized=off' for $query; + +DROP TABLE t1,t2; + +--echo # +--echo # MDEV-37407 Wrong result with ORDER BY LIMIT +--echo # Both, with and without split_materialized should +--echo # produce the same results +--echo # + +SET @save_optimizer_switch= @@optimizer_switch; + +CREATE TABLE t1 + (a varchar(35), b varchar(4), KEY (a)) +ENGINE=InnoDB; + +INSERT INTO t1 VALUES +('Albania','AXA'), ('Australia','AUS'), ('Myanmar','MMR'), +('Bahamas','BS'), ('Brazil','BRA'), ('Barbados','BRB'); + +CREATE TABLE t2 + (a varchar(4), b varchar(50), PRIMARY KEY (b,a), KEY (a)) +ENGINE=InnoDB; + +INSERT INTO t2 VALUES +('AUS','Anglican'), ('MMR','Baptist'), ('BS','Anglican'), +('BS','Baptist'), ('BS','Methodist'), ('BRB','Methodist'), +('BRA','Baptist'), ('USA','Baptist'); + +ANALYZE TABLE t1 PERSISTENT FOR ALL; +ANALYZE TABLE t2 PERSISTENT FOR ALL; + +let $q= +SELECT t1.a +FROM (SELECT a FROM t2 GROUP BY a ORDER BY a, COUNT(DISTINCT b) LIMIT 1) dt + JOIN t1 ON + dt.a=t1.b +WHERE t1.a LIKE 'B%'; + +set optimizer_switch='split_materialized=off'; +eval $q; + +set optimizer_switch='split_materialized=on'; +eval $q; + +DROP TABLE t1,t2; + +SET optimizer_switch= @save_optimizer_switch; + +--echo # +--echo # MDEV-29638 Crash when considering Split-Materialized plan +--echo # + +set @save_optimizer_switch= @@optimizer_switch; +set optimizer_switch='condition_pushdown_for_derived=off,split_materialized=on'; + +CREATE TABLE t1 (id int PRIMARY KEY)engine=innodb; +CREATE TABLE t2 (id int PRIMARY KEY, c int) engine=innodb; +CREATE TABLE t3 (id int PRIMARY KEY, a int , b int, KEY (a))engine=innodb; + +SELECT * FROM +( + SELECT DISTINCT t1.id + FROM t1 JOIN + ( + SELECT t2.id FROM t2 JOIN t3 + ON t3.id = t2.c + WHERE (t3.a > 2 AND t3.b = 2) + GROUP BY t2.id + ) m2 ON m2.id = t1.id +) dt; + +drop table t1, t2, t3; +SET optimizer_switch= @save_optimizer_switch; + --echo # End of 10.11 tests --echo # diff --git a/mysql-test/main/derived_view.result b/mysql-test/main/derived_view.result index c819460c07976..c2aa35e3ca6f9 100644 --- a/mysql-test/main/derived_view.result +++ b/mysql-test/main/derived_view.result @@ -1242,7 +1242,7 @@ SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1 system NULL NULL NULL NULL 1 1 PRIMARY t2 ref a a 4 const 1 Using index -1 PRIMARY ref key0 key0 8 const,const 1 +1 PRIMARY ref key1 key1 8 func,func 1 2 DERIVED t3 ALL NULL NULL NULL NULL 12 Using temporary; Using filesort SELECT * FROM t1, t2, v1 WHERE t2.a=t1.a AND t2.a=v1.a AND t2.a=v1.b; a a a b @@ -2431,7 +2431,7 @@ GROUP BY TABLE_SCHEMA) AS UNIQUES ON ( COLUMNS.TABLE_SCHEMA = UNIQUES.TABLE_SCHEMA); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY COLUMNS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases -1 PRIMARY ref key0 key0 194 information_schema.COLUMNS.TABLE_SCHEMA 10 +1 PRIMARY ref key0 key0 194 information_schema.COLUMNS.TABLE_SCHEMA 1 2 DERIVED STATISTICS ALL NULL NULL NULL NULL NULL Open_frm_only; Scanned all databases; Using filesort SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.COLUMNS @@ -4488,3 +4488,17 @@ deallocate prepare stmt; drop view v1,v2; drop table t1,t2; # End of 10.6 tests +# +# MDEV-37266: Assertion in create_ref_for_key() with +# derived_merge OFF +# +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_with_keys=on'; +CREATE TABLE t1 AS SELECT 1 AS a FROM seq_1_to_2; +SELECT md5(a) IN (SELECT * FROM (SELECT '' FROM t1) as x) FROM t1; +md5(a) IN (SELECT * FROM (SELECT '' FROM t1) as x) +0 +0 +DROP table t1; +SET optimizer_switch=@save_optimizer_switch; +# End of 11.4 tests diff --git a/mysql-test/main/derived_view.test b/mysql-test/main/derived_view.test index 5338bcd34c6dd..97b9e1932db8d 100644 --- a/mysql-test/main/derived_view.test +++ b/mysql-test/main/derived_view.test @@ -2946,3 +2946,19 @@ drop view v1,v2; drop table t1,t2; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-37266: Assertion in create_ref_for_key() with +--echo # derived_merge OFF +--echo # + +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch='derived_with_keys=on'; + +CREATE TABLE t1 AS SELECT 1 AS a FROM seq_1_to_2; +SELECT md5(a) IN (SELECT * FROM (SELECT '' FROM t1) as x) FROM t1; + +DROP table t1; +SET optimizer_switch=@save_optimizer_switch; + +--echo # End of 11.4 tests diff --git a/mysql-test/main/dirty_close.result b/mysql-test/main/dirty_close.result index d13fdb09192da..988f73750f41d 100644 --- a/mysql-test/main/dirty_close.result +++ b/mysql-test/main/dirty_close.result @@ -3,7 +3,6 @@ connect con2,localhost,root,,; connection con1; disconnect con1; connection con2; -DROP TABLE IF EXISTS t1; CREATE TABLE t1 (n INT); INSERT INTO t1 VALUES (1),(2),(3); SELECT * FROM t1; diff --git a/mysql-test/main/dirty_close.test b/mysql-test/main/dirty_close.test index e49618170ab96..eb120ff7132d2 100644 --- a/mysql-test/main/dirty_close.test +++ b/mysql-test/main/dirty_close.test @@ -1,18 +1,11 @@ --source include/not_embedded.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; dirty_close con1; connection con2; ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1 (n INT); INSERT INTO t1 VALUES (1),(2),(3); SELECT * FROM t1; @@ -54,7 +47,3 @@ connection con1; --reap connection default; disconnect con1; - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/distinct.result b/mysql-test/main/distinct.result index c3f4fae80e682..38371c34a35aa 100644 --- a/mysql-test/main/distinct.result +++ b/mysql-test/main/distinct.result @@ -212,7 +212,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 index NULL PRIMARY 4 NULL 1 Using index explain SELECT distinct a from t3 order by a desc limit 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t3 index NULL a 5 NULL 40 Using index +1 SIMPLE t3 range a a 5 NULL 10 Using index for group-by; Using temporary; Using filesort explain SELECT distinct a,b from t3 order by a+1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 204 Using temporary; Using filesort diff --git a/mysql-test/main/drop.result b/mysql-test/main/drop.result index f4415117dc9ae..7344a085c7065 100644 --- a/mysql-test/main/drop.result +++ b/mysql-test/main/drop.result @@ -97,7 +97,6 @@ unlock tables; connection addconroot1; connection addconroot2; disconnect addconroot2; -connection addconroot1; disconnect addconroot1; connection default; drop table if exists t1,t2; diff --git a/mysql-test/main/drop.test b/mysql-test/main/drop.test index 6b926d3f0c1c1..3f2e6770eb309 100644 --- a/mysql-test/main/drop.test +++ b/mysql-test/main/drop.test @@ -123,10 +123,7 @@ connection addconroot1; connection addconroot2; --reap disconnect addconroot2; ---source include/wait_until_disconnected.inc -connection addconroot1; disconnect addconroot1; ---source include/wait_until_disconnected.inc connection default; --enable_service_connection diff --git a/mysql-test/main/dyncol.result b/mysql-test/main/dyncol.result index 9e1d3aabbb7c3..740e7c445d120 100644 --- a/mysql-test/main/dyncol.result +++ b/mysql-test/main/dyncol.result @@ -1427,9 +1427,9 @@ SELECT column_get(column_create(1, -999999999999999 AS int), 1 AS TIME) AS t1, column_get(column_create(1, -9223372036854775808 AS int), 1 AS TIME) AS t2; t1 t2 --838:59:59 -838:59:59 +NULL -838:59:59 Warnings: -Warning 1292 Truncated incorrect time value: '-999999999999999' +Warning 1292 Incorrect time value: '-999999999999999' Warning 1292 Truncated incorrect time value: '-9223372036854775808' # # end of 5.3 tests diff --git a/mysql-test/main/error_simulation.result b/mysql-test/main/error_simulation.result index ba4c8bcf47751..009f5323b37d8 100644 --- a/mysql-test/main/error_simulation.result +++ b/mysql-test/main/error_simulation.result @@ -125,13 +125,4 @@ SELECT f1(1); Got one of the listed errors DROP FUNCTION f1; SET debug_dbug= @saved_dbug; -# -# MDEV-27978 wrong option name in error when exceeding max_session_mem_used -# -SET SESSION max_session_mem_used = 8192; -SELECT * FROM information_schema.processlist; -ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement -SET SESSION max_session_mem_used = DEFAULT; -# # End of 10.2 tests -# diff --git a/mysql-test/main/error_simulation.test b/mysql-test/main/error_simulation.test index fc5d9c537c73c..3beeefce39fde 100644 --- a/mysql-test/main/error_simulation.test +++ b/mysql-test/main/error_simulation.test @@ -144,8 +144,6 @@ SELECT a FROM t1 ORDER BY rand(1); --echo #cleanup DROP TABLE t1, pid_table; - - --echo # --echo # MDEV-12416 OOM in create_virtual_tmp_table() makes the server crash --echo # @@ -158,15 +156,4 @@ SELECT f1(1); DROP FUNCTION f1; SET debug_dbug= @saved_dbug; ---echo # ---echo # MDEV-27978 wrong option name in error when exceeding max_session_mem_used ---echo # -SET SESSION max_session_mem_used = 8192; ---error ER_OPTION_PREVENTS_STATEMENT -SELECT * FROM information_schema.processlist; -SET SESSION max_session_mem_used = DEFAULT; - - ---echo # --echo # End of 10.2 tests ---echo # diff --git a/mysql-test/main/errors.result b/mysql-test/main/errors.result index e056867695234..e4ccc8a73196e 100644 --- a/mysql-test/main/errors.result +++ b/mysql-test/main/errors.result @@ -1,4 +1,3 @@ -drop table if exists t1; insert into t1 values(1); ERROR 42S02: Table 'test.t1' doesn't exist delete from t1; @@ -170,12 +169,6 @@ UPDATE t1 SET a = 'new' WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; ERROR 22007: Illegal value used as argument of dynamic column function drop table t1; -set @max_session_mem_used_save= @@max_session_mem_used; -set max_session_mem_used = 50000; -select * from seq_1_to_1000; -set max_session_mem_used = 8192; -select * from seq_1_to_1000; -set max_session_mem_used = @max_session_mem_used_save; # # MDEV-20604: Duplicate key value is silently truncated to 64 # characters in print_keydup_error @@ -231,16 +224,3 @@ Error 1327 Undeclared variable: foo Error 1305 PROCEDURE P1 does not exist drop procedure P1; # End of 10.4 tests -# -# MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself -# -CREATE TEMPORARY TABLE t1 (a INT,b INT); -INSERT INTO t1 VALUES (1,1),(2,2); -SET -@tmp=@@max_session_mem_used, -max_session_mem_used=8192; -SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1; -ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement -DROP TABLE t1; -SET max_session_mem_used=@tmp; -# End of 10.6 tests diff --git a/mysql-test/main/errors.test b/mysql-test/main/errors.test index 87d6d2fdec9fd..e748b3bef2d40 100644 --- a/mysql-test/main/errors.test +++ b/mysql-test/main/errors.test @@ -3,31 +3,28 @@ # --source include/have_sequence.inc ---disable_warnings -drop table if exists t1; ---enable_warnings ---error 1146 +--error ER_NO_SUCH_TABLE insert into t1 values(1); ---error 1146 +--error ER_NO_SUCH_TABLE delete from t1; ---error 1146 +--error ER_NO_SUCH_TABLE update t1 set a=1; create table t1 (a int); ---error 1054 +--error ER_BAD_FIELD_ERROR select count(test.t1.b) from t1; ---error 1054 +--error ER_BAD_FIELD_ERROR select count(not_existing_database.t1) from t1; ---error 1054 +--error ER_BAD_FIELD_ERROR select count(not_existing_database.t1.a) from t1; ---error 1044,1146 +--error ER_DBACCESS_DENIED_ERROR,ER_NO_SUCH_TABLE select count(not_existing_database.t1.a) from not_existing_database.t1; ---error 1054 +--error ER_BAD_FIELD_ERROR select 1 from t1 order by 2; ---error 1054 +--error ER_BAD_FIELD_ERROR select 1 from t1 group by 2; ---error 1054 +--error ER_BAD_FIELD_ERROR select 1 from t1 order by t1.b; ---error 1054 +--error ER_BAD_FIELD_ERROR select count(*),b from t1; drop table t1; @@ -36,10 +33,10 @@ drop table t1; # # Bug #6080: Error message for a field with a display width that is too long # ---error 1439 +--error ER_TOO_BIG_DISPLAYWIDTH create table t1 (a int(256)); set sql_mode='traditional'; ---error 1074 +--error ER_TOO_BIG_FIELDLENGTH create table t1 (a varchar(66000)); set sql_mode=default; @@ -95,7 +92,7 @@ delimiter ;| flush status; --disable_ps2_protocol ---error 1062 +--error ER_DUP_ENTRY select f1(), f2(); --enable_ps2_protocol show status like 'Com_insert'; @@ -202,24 +199,6 @@ UPDATE t1 SET a = 'new' WHERE COLUMN_CREATE( 1, 'v', 1, 'w' ) IS NULL; drop table t1; -# -# errors caused by max_session_mem_used -# -set @max_session_mem_used_save= @@max_session_mem_used; - ---disable_result_log -set max_session_mem_used = 50000; ---error 0,ER_OPTION_PREVENTS_STATEMENT -select * from seq_1_to_1000; -set max_session_mem_used = 8192; ---error 0,ER_OPTION_PREVENTS_STATEMENT -select * from seq_1_to_1000; ---enable_result_log -# We may not be able to execute any more queries with this connection -# because of too little memory# - -set max_session_mem_used = @max_session_mem_used_save; - --echo # --echo # MDEV-20604: Duplicate key value is silently truncated to 64 --echo # characters in print_keydup_error @@ -283,24 +262,4 @@ show warnings; drop procedure P1; --- echo # End of 10.4 tests - - ---echo # ---echo # MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself ---echo # -CREATE TEMPORARY TABLE t1 (a INT,b INT); -INSERT INTO t1 VALUES (1,1),(2,2); - -SET - @tmp=@@max_session_mem_used, - max_session_mem_used=8192; - ---error ER_OPTION_PREVENTS_STATEMENT -SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1; - -DROP TABLE t1; -SET max_session_mem_used=@tmp; - - ---echo # End of 10.6 tests +--echo # End of 10.4 tests diff --git a/mysql-test/main/explain_json_format_partitions.result b/mysql-test/main/explain_json_format_partitions.result index 2ad33b3783b7d..16f624254847b 100644 --- a/mysql-test/main/explain_json_format_partitions.result +++ b/mysql-test/main/explain_json_format_partitions.result @@ -81,7 +81,8 @@ ANALYZE "rows": 10, "r_rows": 10, "r_total_filtered": 30, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t1.a in (2,3,4)", "r_filtered": 30 @@ -106,7 +107,8 @@ ANALYZE "rows": 10, "r_rows": 10, "r_total_filtered": 0, - "r_total_time_ms": "REPLACED", + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", "r_engine_stats": REPLACED, "attached_condition": "t1.a in (20,30,40)", "r_filtered": 0 diff --git a/mysql-test/main/explain_non_select.result b/mysql-test/main/explain_non_select.result index ca8aa246c98aa..aa3c4787dc7f0 100644 --- a/mysql-test/main/explain_non_select.result +++ b/mysql-test/main/explain_non_select.result @@ -72,7 +72,7 @@ id select_type table type possible_keys key key_len ref rows Extra # This should use an index, possible_keys=NULL because there is no WHERE explain update t1 set a=a+1 order by a limit 2; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 512 Using filesort +1 SIMPLE t1 index NULL a 5 NULL 2 Using buffer # This should use range, possible_keys={a,b} explain update t1 set filler='fooo' where a<20 and b < 10; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/failed_auth_3909.result b/mysql-test/main/failed_auth_3909.result index 5586997430185..8d16b0310a402 100644 --- a/mysql-test/main/failed_auth_3909.result +++ b/mysql-test/main/failed_auth_3909.result @@ -6,12 +6,15 @@ connect fail,localhost,u1; ERROR 28000: Access denied for user 'u1'@'localhost' (using password: NO) connect(localhost,uu2,,test,MASTER_PORT,MASTER_SOCKET); connect fail,localhost,uu2; -ERROR HY000: Server is running in --secure-auth mode, but 'uu2'@'localhost' has a password in the old format; please change the password to the new format +ERROR HY000: User 'uu2'@'localhost' has a password in the old format; please change the password to the new format connect(localhost,uu2,password,test,MASTER_PORT,MASTER_SOCKET); connect fail,localhost,uu2,password; -ERROR HY000: Server is running in --secure-auth mode, but 'uu2'@'localhost' has a password in the old format; please change the password to the new format +ERROR HY000: User 'uu2'@'localhost' has a password in the old format; please change the password to the new format +change_user u1,,; ERROR 28000: Access denied for user 'u1'@'localhost' (using password: NO) -ERROR HY000: Server is running in --secure-auth mode, but 'uu2'@'localhost' has a password in the old format; please change the password to the new format -ERROR HY000: Server is running in --secure-auth mode, but 'uu2'@'localhost' has a password in the old format; please change the password to the new format +change_user uu2,,; +ERROR HY000: User 'uu2'@'localhost' has a password in the old format; please change the password to the new format +change_user uu2,password,; +ERROR HY000: User 'uu2'@'localhost' has a password in the old format; please change the password to the new format delete from mysql.user where plugin = 'mysql_old_password'; flush privileges; diff --git a/mysql-test/main/failed_auth_unixsocket.result b/mysql-test/main/failed_auth_unixsocket.result index 084eb2fab64c5..94a3a70f46d30 100644 --- a/mysql-test/main/failed_auth_unixsocket.result +++ b/mysql-test/main/failed_auth_unixsocket.result @@ -4,6 +4,7 @@ delete from mysql.global_priv where user != 'root'; flush privileges; connect(localhost,USER,,test,MASTER_PORT,MASTER_SOCKET); ERROR 28000: Access denied for user 'USER'@'localhost' +change_user USER,,; ERROR 28000: Access denied for user 'USER'@'localhost' replace mysql.global_priv select * from global_priv_backup; flush privileges; diff --git a/mysql-test/main/failed_auth_unixsocket.test b/mysql-test/main/failed_auth_unixsocket.test index 5a77e1cdbda16..58c57be97b332 100644 --- a/mysql-test/main/failed_auth_unixsocket.test +++ b/mysql-test/main/failed_auth_unixsocket.test @@ -20,7 +20,7 @@ let $replace=Access denied for user '$USER'; connect (fail,localhost,$USER); --enable_query_log ---replace_result $replace "Access denied for user 'USER'" +--replace_result $USER USER --error ER_ACCESS_DENIED_NO_PASSWORD_ERROR change_user $USER; diff --git a/mysql-test/main/features.result b/mysql-test/main/features.result index cae4a37ca64e2..2f0c41936986e 100644 --- a/mysql-test/main/features.result +++ b/mysql-test/main/features.result @@ -20,6 +20,7 @@ Feature_subquery 0 Feature_system_versioning 0 Feature_timezone 0 Feature_trigger 0 +Feature_vector_index 0 Feature_window_functions 0 Feature_xml 0 # @@ -209,3 +210,19 @@ show status like "feature_into_%"; Variable_name Value Feature_into_outfile 4 Feature_into_variable 2 +# +# Feature vector index +# +create table t1 (id int auto_increment primary key, +u vector(5) not null, vector index (u)); +select * from t1; +id u +select * from t1; +id u +select * from t1; +id u +show status like "Feature_vector_index"; +Variable_name Value +Feature_vector_index 2 +drop table t1; +# End of 11.8 tests diff --git a/mysql-test/main/features.test b/mysql-test/main/features.test index 6ef617159e6ca..15cc5630c5525 100644 --- a/mysql-test/main/features.test +++ b/mysql-test/main/features.test @@ -166,3 +166,19 @@ drop table t1; --remove_file $MYSQLTEST_VARDIR/tmp/features_outfile.1 --remove_file $MYSQLTEST_VARDIR/tmp/features_outfile.2 show status like "feature_into_%"; + +--echo # +--echo # Feature vector index +--echo # + +--disable_service_connection +create table t1 (id int auto_increment primary key, + u vector(5) not null, vector index (u)); +select * from t1; +select * from t1; +select * from t1; +show status like "Feature_vector_index"; +drop table t1; +--enable_service_connection + +--echo # End of 11.8 tests diff --git a/mysql-test/main/fetch_first.result b/mysql-test/main/fetch_first.result index 775595783b9fd..861273030e8ae 100644 --- a/mysql-test/main/fetch_first.result +++ b/mysql-test/main/fetch_first.result @@ -846,7 +846,7 @@ group by first_name, last_name order by first_name fetch first 2 rows with ties; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range t1_name t1_name 206 NULL 3 Using where; Using index for group-by +1 SIMPLE t1 range t1_name t1_name 206 NULL 3 Using where; Using index for group-by; Using temporary; Using filesort select first_name, last_name from t1 where first_name != 'John' @@ -871,7 +871,7 @@ select * from temp_table order by first_name, last_name; id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY ALL NULL NULL NULL NULL 2 Using filesort -2 DERIVED t1 range t1_name t1_name 206 NULL 3 Using where; Using index for group-by +2 DERIVED t1 range t1_name t1_name 206 NULL 3 Using where; Using index for group-by; Using temporary; Using filesort with temp_table as ( select first_name, last_name from t1 @@ -1462,3 +1462,88 @@ a b 3 bar 3 zzz DROP TABLE t1; +# +# MDEV-37901: Wrong result with Loose Scan on QUICK_GROUP_MIN_MAX_SELECT WITH TIES +# +create table t1 ( +country varchar(100), +city varchar(100), +user_score int, +index (country, city, user_score) +); +insert into t1 +select 'China', 'Shenzhen', seq from seq_10_to_100; +insert into t1 +select 'India', 'New Delhi', seq from seq_10_to_100; +insert into t1 +select 'Sri Lanka', 'Colombo', seq from seq_10_to_100; +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 +insert into t1 +select 'Finland', 'Espoo', seq from seq_10_to_200; +insert into t1 +select 'Greece', 'Chania', seq from seq_10_to_20; +insert into t1 +select 'Estonia', 'Narva', seq from seq_10_to_20; +insert into t1 +select 'Russia', 'St Petersburg', seq from seq_10_to_20; +# Must use "Using index for group-by": +explain +select country, city, min(user_score) +from t1 +where user_score between 9 and 199 +group by country, city +order by country +fetch first 5 rows with ties; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL country 811 NULL 4 Using where; Using index for group-by; Using temporary; Using filesort +# Must not use "Using index for group-by": +explain +select country, city, sum(user_score) +from t1 +where user_score between 9 and 199 +group by country, concat(city,'AA') +order by country +fetch first 5 rows with ties; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL country 811 NULL 273 Using where; Using index; Using temporary; Using filesort +select country, city, sum(user_score) +from t1 +where user_score between 9 and 199 +group by country, concat(city,'AA') +order by country +fetch first 5 rows with ties; +country city sum(user_score) +China Shenzhen 5005 +Estonia Narva 165 +Finland Espoo 19855 +Greece Chania 165 +India New Delhi 5005 +# both using index and index with group by should produce same result +select country, city, min(user_score) +from t1 +where user_score between 9 and 199 +group by country, city +order by country +fetch first 5 rows with ties; +country city min(user_score) +China Shenzhen 10 +Estonia Narva 10 +Finland Espoo 10 +Greece Chania 10 +India New Delhi 10 +select country, city, min(user_score) +from t1 use index() +where user_score between 9 and 199 +group by country, city +order by country +fetch first 5 rows with ties; +country city min(user_score) +China Shenzhen 10 +Estonia Narva 10 +Finland Espoo 10 +Greece Chania 10 +India New Delhi 10 +drop table t1; diff --git a/mysql-test/main/fetch_first.test b/mysql-test/main/fetch_first.test index 71e45f5c28880..d4cb8edaa0d4f 100644 --- a/mysql-test/main/fetch_first.test +++ b/mysql-test/main/fetch_first.test @@ -1095,3 +1095,77 @@ SELECT DISTINCT a, b FROM t1 ORDER BY a FETCH FIRST 3 ROWS WITH TIES; # Cleanup DROP TABLE t1; + + +--echo # +--echo # MDEV-37901: Wrong result with Loose Scan on QUICK_GROUP_MIN_MAX_SELECT WITH TIES +--echo # + +--source include/have_sequence.inc + +create table t1 ( + country varchar(100), + city varchar(100), + user_score int, + index (country, city, user_score) +); + +insert into t1 +select 'China', 'Shenzhen', seq from seq_10_to_100; +insert into t1 +select 'India', 'New Delhi', seq from seq_10_to_100; +insert into t1 +select 'Sri Lanka', 'Colombo', seq from seq_10_to_100; +analyze table t1 persistent for all; + +insert into t1 +select 'Finland', 'Espoo', seq from seq_10_to_200; +insert into t1 +select 'Greece', 'Chania', seq from seq_10_to_20; +insert into t1 +select 'Estonia', 'Narva', seq from seq_10_to_20; +insert into t1 +select 'Russia', 'St Petersburg', seq from seq_10_to_20; + +--echo # Must use "Using index for group-by": +explain +select country, city, min(user_score) +from t1 +where user_score between 9 and 199 +group by country, city +order by country +fetch first 5 rows with ties; + +--echo # Must not use "Using index for group-by": +explain +select country, city, sum(user_score) +from t1 +where user_score between 9 and 199 +group by country, concat(city,'AA') +order by country +fetch first 5 rows with ties; + +select country, city, sum(user_score) +from t1 +where user_score between 9 and 199 +group by country, concat(city,'AA') +order by country +fetch first 5 rows with ties; + +--echo # both using index and index with group by should produce same result + +select country, city, min(user_score) +from t1 +where user_score between 9 and 199 +group by country, city +order by country +fetch first 5 rows with ties; + +select country, city, min(user_score) +from t1 use index() +where user_score between 9 and 199 +group by country, city +order by country +fetch first 5 rows with ties; + +drop table t1; diff --git a/mysql-test/main/file_contents.result b/mysql-test/main/file_contents.result deleted file mode 100644 index 2b5e6e6229b6c..0000000000000 --- a/mysql-test/main/file_contents.result +++ /dev/null @@ -1,6 +0,0 @@ - -Checking 'INFO_SRC' and 'INFO_BIN' -INFO_SRC: Found MariaDB version number / Found GIT revision id -INFO_BIN: Found 'Compiler ... used' line / Found 'Feature flags' line - -End of tests diff --git a/mysql-test/main/file_contents.test b/mysql-test/main/file_contents.test deleted file mode 100644 index 4734a0294f03b..0000000000000 --- a/mysql-test/main/file_contents.test +++ /dev/null @@ -1,70 +0,0 @@ -# -# Testing files that were built to be packaged, both for existence and for contents -# - -# -# Bug #42969: Create MANIFEST files -# -# Use a Perl script to verify that files "docs/INFO_BIN" and "docs/INFO_SRC" do exist -# and have the expected contents. - ---perl -print "\nChecking 'INFO_SRC' and 'INFO_BIN'\n"; -$dir_bin = $ENV{'MYSQL_BINDIR'}; -if ($dir_bin eq '/usr/') { - # RPM package - $dir_docs = $dir_bin; - $dir_docs =~ s|/lib|/share/doc|; - if(-d "$dir_docs/packages") { - # SuSE: "packages/" in the documentation path - $dir_docs = glob "$dir_docs/packages/MariaDB-server*"; - } else { - # RedHat: version number in directory name - $dir_docs = glob "$dir_docs/MariaDB-server*"; - } -} elsif ($dir_bin eq '/usr') { - # RPM build during development - $dir_docs = "$dir_bin/share/doc"; - if(-d "$dir_docs/packages") { - # SuSE: "packages/" in the documentation path - $dir_docs = glob "$dir_docs/packages/MariaDB-server*"; - } else { - # RedHat/Debian: version number in directory name - $dir_docs = glob "$dir_docs/mariadb-server-*"; - $dir_docs = glob "$dir_docs/MariaDB-server*" unless -d $dir_docs; - } - # Slackware - $dir_docs = glob "$dir_bin/doc/mariadb-[0-9]*" unless -d $dir_docs; -} else { - # tar.gz package, Windows, or developer work (in git) - $dir_docs = $dir_bin; - if(-d "$dir_docs/docs") { - $dir_docs = "$dir_docs/docs"; # package - } else { - $dir_docs = "$dir_docs/Docs"; # development tree - } -} -$found_version = "No line 'MariaDB source #.#.#' in $dir_docs/INFO_SRC"; -$found_revision = "No line 'revision-id: .....' in $dir_docs/INFO_SRC"; -open(I_SRC,"<","$dir_docs/INFO_SRC") or print "Cannot open 'INFO_SRC' in '$dir_docs' (starting from bindir '$dir_bin')\n"; -while(defined ($line = )) { - if ($line =~ m|^MariaDB source \d+\.\d\.\d+|) {$found_version = "Found MariaDB version number";} - if ($line =~ m|^commit: \w{40}$|) {$found_revision = "Found GIT revision id";} -} -close I_SRC; -print "INFO_SRC: $found_version / $found_revision\n"; -$found_compiler = "No line about compiler information"; -$found_features = "No line 'Feature flags'"; -open(I_BIN,"<","$dir_docs/INFO_BIN") or print "Cannot open 'INFO_BIN' in '$dir_docs' (starting from bindir '$dir_bin')\n"; -while(defined ($line = )) { - # "generator" on Windows, "flags" on Unix: - if (($line =~ m| Compiler / generator used: |) || - ($line =~ m| Compiler flags used |)) {$found_compiler = "Found 'Compiler ... used' line";} - if ($line =~ m| Feature flags used:|) {$found_features = "Found 'Feature flags' line";} -} -close I_BIN; -print "INFO_BIN: $found_compiler / $found_features\n"; -EOF - ---echo ---echo End of tests diff --git a/mysql-test/main/filesort_debug.test b/mysql-test/main/filesort_debug.test index 8f0fba099bcc4..d78087d27bbb9 100644 --- a/mysql-test/main/filesort_debug.test +++ b/mysql-test/main/filesort_debug.test @@ -1,6 +1,5 @@ --source include/have_debug.inc --source include/have_debug_sync.inc ---source include/count_sessions.inc call mtr.add_suppression("Sort aborted.*"); @@ -53,7 +52,6 @@ SET DEBUG_SYNC='now SIGNAL filesort_killed'; connection default; disconnect con1; disconnect con2; ---source include/wait_until_count_sessions.inc SET DEBUG_SYNC= "RESET"; DROP TABLE t1; diff --git a/mysql-test/main/fix_priv_tables.result b/mysql-test/main/fix_priv_tables.result index c39ebfb922722..db1edd79c05f4 100644 --- a/mysql-test/main/fix_priv_tables.result +++ b/mysql-test/main/fix_priv_tables.result @@ -1,4 +1,3 @@ -drop table if exists t1,t1aa,t2aa; set sql_mode=""; DROP DATABASE IF EXISTS testdb; CREATE DATABASE testdb; @@ -19,7 +18,7 @@ Grants for select_only_c1@localhost GRANT USAGE ON *.* TO `select_only_c1`@`localhost` GRANT SELECT (`c1`) ON `testdb`.`v1` TO `select_only_c1`@`localhost` -"after fix privs" +# after fix privs SHOW GRANTS FOR 'show_view_tbl'@'localhost'; Grants for show_view_tbl@localhost GRANT USAGE ON *.* TO `show_view_tbl`@`localhost` @@ -35,3 +34,4 @@ DROP USER 'select_only_c1'@'localhost'; DROP VIEW testdb.v1; DROP TABLE testdb.t1; DROP DATABASE testdb; +# End of 4.1 tests diff --git a/mysql-test/main/fix_priv_tables.test b/mysql-test/main/fix_priv_tables.test index 382417a6b1010..7ac99f3357cda 100644 --- a/mysql-test/main/fix_priv_tables.test +++ b/mysql-test/main/fix_priv_tables.test @@ -19,10 +19,6 @@ if (!$MYSQL_FIX_PRIVILEGE_TABLES) # mysql_fix_system_tables which should be ignored. # Instead, concentrate on the errors in r/system_mysql_db.reject ---disable_warnings -drop table if exists t1,t1aa,t2aa; ---enable_warnings - set sql_mode=""; # @@ -50,22 +46,16 @@ GRANT SELECT(c1) on testdb.v1 to 'select_only_c1'@localhost; SHOW GRANTS FOR 'select_only_c1'@'localhost'; echo; --- disable_result_log --- disable_query_log +--disable_result_log +--disable_query_log -# Run the mysql_fix_privilege_tables.sql using "mysql --force" -# Determine the number of open sessions ---source include/count_sessions.inc --exec $MYSQL --force mysql < $MYSQL_FIX_PRIVILEGE_TABLES > $MYSQLTEST_VARDIR/tmp/fix_priv_tables.log 2>&1 --remove_file $MYSQLTEST_VARDIR/tmp/fix_priv_tables.log -# Wait till the number of open sessions is <= the number before the run with $MYSQL -# = The session caused by mysql has finished its disconnect ---source include/wait_until_count_sessions.inc --- enable_query_log --- enable_result_log +--enable_query_log +--enable_result_log -echo "after fix privs"; +echo # after fix privs; SHOW GRANTS FOR 'show_view_tbl'@'localhost'; echo; @@ -79,4 +69,4 @@ DROP VIEW testdb.v1; DROP TABLE testdb.t1; DROP DATABASE testdb; -# End of 4.1 tests +--echo # End of 4.1 tests diff --git a/mysql-test/main/flush-innodb-notembedded.test b/mysql-test/main/flush-innodb-notembedded.test index 1f73ba50fc44b..0677fa62a48f3 100644 --- a/mysql-test/main/flush-innodb-notembedded.test +++ b/mysql-test/main/flush-innodb-notembedded.test @@ -18,7 +18,6 @@ GRANT RELOAD, LOCK TABLES ON *.* TO user5@localhost; FLUSH TABLE db1.t1 FOR EXPORT; UNLOCK TABLES; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default @@ -26,7 +25,6 @@ UNLOCK TABLES; --error ER_SPECIFIC_ACCESS_DENIED_ERROR FLUSH TABLE db1.t1 FOR EXPORT; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default @@ -34,7 +32,6 @@ FLUSH TABLE db1.t1 FOR EXPORT; --error ER_DBACCESS_DENIED_ERROR FLUSH TABLE db1.t1 FOR EXPORT; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default @@ -42,7 +39,6 @@ FLUSH TABLE db1.t1 FOR EXPORT; --error ER_SPECIFIC_ACCESS_DENIED_ERROR FLUSH TABLE db1.t1 FOR EXPORT; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default @@ -50,7 +46,6 @@ FLUSH TABLE db1.t1 FOR EXPORT; --error ER_TABLEACCESS_DENIED_ERROR FLUSH TABLE db1.t1 FOR EXPORT; --disconnect con1 ---source include/wait_until_disconnected.inc --connection default DROP USER user1@localhost, user2@localhost, user3@localhost, diff --git a/mysql-test/main/flush-innodb.result b/mysql-test/main/flush-innodb.result index 5df79e4cc0c05..351ca0a34d254 100644 --- a/mysql-test/main/flush-innodb.result +++ b/mysql-test/main/flush-innodb.result @@ -157,7 +157,6 @@ CREATE TABLE t1(a INT) engine= MEMORY; FLUSH TABLE t1 FOR EXPORT; ERROR HY000: Storage engine MEMORY of the table `test`.`t1` doesn't have this option DROP TABLE t1; -connection con1; disconnect con1; connection default; # Test 7: Check privileges required. @@ -198,7 +197,6 @@ LOCK TABLE t1 READ; UNLOCK TABLES; connection default; UNLOCK TABLES; -connection con1; disconnect con1; connection default; DROP TABLE t1, t2; @@ -294,7 +292,6 @@ ERROR HY000: Can't execute the given command because you have active locked tabl LOCK TABLES test.t1 WRITE; UNLOCK TABLES; DROP TABLE t1; -connection con1; disconnect con1; connection default; # End of 5.6 tests diff --git a/mysql-test/main/flush-innodb.test b/mysql-test/main/flush-innodb.test index fcb0608373e32..cf62ba6aec67e 100644 --- a/mysql-test/main/flush-innodb.test +++ b/mysql-test/main/flush-innodb.test @@ -222,8 +222,6 @@ UNLOCK TABLES; --echo # Reaping DROP TABLE t1 --reap --disconnect con2 ---source include/wait_until_disconnected.inc - --connection default DROP TABLE t2; @@ -250,10 +248,7 @@ CREATE TABLE t1(a INT) engine= MEMORY; FLUSH TABLE t1 FOR EXPORT; DROP TABLE t1; ---connection con1 --disconnect con1 ---source include/wait_until_disconnected.inc - --connection default --echo # Test 7: Check privileges required. @@ -313,10 +308,7 @@ UNLOCK TABLES; --connection default UNLOCK TABLES; ---connection con1 --disconnect con1 ---source include/wait_until_disconnected.inc - --connection default DROP TABLE t1, t2; @@ -423,9 +415,7 @@ LOCK TABLES test.t1 WRITE; UNLOCK TABLES; DROP TABLE t1; ---connection con1 --disconnect con1 ---source include/wait_until_disconnected.inc --connection default --echo # End of 5.6 tests diff --git a/mysql-test/main/flush.result b/mysql-test/main/flush.result index 584e79e72db6a..ccc7dc8b771a6 100644 --- a/mysql-test/main/flush.result +++ b/mysql-test/main/flush.result @@ -281,7 +281,6 @@ lock table t1 read, t2 read; unlock tables; connection default; unlock tables; -connection con1; disconnect con1; connection default; drop table t1, t2, t3; @@ -399,9 +398,7 @@ connection con2; connection default; commit; # Cleanup -connection con1; disconnect con1; -connection con2; disconnect con2; connection default; drop table t1; @@ -480,9 +477,7 @@ connection default; # Reap INSERT. handler t1 close; # Cleanup. -connection con1; disconnect con1; -connection con2; disconnect con2; connection default; drop tables t1, t2; diff --git a/mysql-test/main/flush.test b/mysql-test/main/flush.test index 1085b469a0393..cb81f6e0fbcb1 100644 --- a/mysql-test/main/flush.test +++ b/mysql-test/main/flush.test @@ -177,7 +177,6 @@ set session low_priority_updates=default; connect (con1,localhost,root,,); send select benchmark(200, (select sin(1))) > 1000; disconnect con1; ---source include/wait_until_disconnected.inc connection default; --echo End of 5.0 tests @@ -361,9 +360,7 @@ unlock tables; connection default; unlock tables; -connection con1; disconnect con1; ---source include/wait_until_disconnected.inc connection default; drop table t1, t2, t3; @@ -490,12 +487,8 @@ commit; --echo # Cleanup -connection con1; disconnect con1; ---source include/wait_until_disconnected.inc -connection con2; disconnect con2; ---source include/wait_until_disconnected.inc connection default; drop table t1; --enable_view_protocol @@ -571,12 +564,8 @@ connection default; handler t1 close; --echo # Cleanup. -connection con1; disconnect con1; ---source include/wait_until_disconnected.inc -connection con2; disconnect con2; ---source include/wait_until_disconnected.inc connection default; drop tables t1, t2; --enable_view_protocol @@ -629,7 +618,6 @@ connect(con1, localhost, root); FLUSH TABLES WITH READ LOCK; UNLOCK TABLES; disconnect con1; ---source include/wait_until_disconnected.inc connection default; COMMIT; diff --git a/mysql-test/main/flush_block_commit.result b/mysql-test/main/flush_block_commit.result index 73ea8859f1d07..1f577004ebd60 100644 --- a/mysql-test/main/flush_block_commit.result +++ b/mysql-test/main/flush_block_commit.result @@ -1,9 +1,7 @@ -# Save the initial number of concurrent sessions connect con1,localhost,root,,; connect con2,localhost,root,,; connect con3,localhost,root,,; connection con1; -DROP TABLE IF EXISTS t1; CREATE TABLE t1 (a INT) ENGINE=innodb; BEGIN; INSERT INTO t1 VALUES(1); @@ -65,4 +63,3 @@ disconnect con3; # drop the table. DROP TABLE t1; # End of 4.1 tests -# Wait till all disconnects are completed diff --git a/mysql-test/main/flush_block_commit.test b/mysql-test/main/flush_block_commit.test index 0280aedf2ca73..a54cb67d53a2a 100644 --- a/mysql-test/main/flush_block_commit.test +++ b/mysql-test/main/flush_block_commit.test @@ -4,19 +4,14 @@ # This is intended to mimick how mysqldump and innobackup work. # And it requires InnoDB +--source include/no_view_protocol.inc --source include/have_innodb.inc ---echo # Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connect (con3,localhost,root,,); connection con1; ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings CREATE TABLE t1 (a INT) ENGINE=innodb; # blocks COMMIT ? @@ -92,7 +87,3 @@ disconnect con3; --echo # drop the table. DROP TABLE t1; --echo # End of 4.1 tests - ---echo # Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/flush_block_commit_notembedded.result b/mysql-test/main/flush_block_commit_notembedded.result index 7dd6410ac709e..d96eae85ceabe 100644 --- a/mysql-test/main/flush_block_commit_notembedded.result +++ b/mysql-test/main/flush_block_commit_notembedded.result @@ -1,4 +1,3 @@ -# Save the initial number of concurrent sessions connect con1,localhost,root,,; connect con2,localhost,root,,; connection con1; @@ -33,4 +32,3 @@ drop table t1; connection default; disconnect con1; disconnect con2; -# Wait till all disconnects are completed diff --git a/mysql-test/main/flush_block_commit_notembedded.test b/mysql-test/main/flush_block_commit_notembedded.test index 024640893d9c0..13899a24558e5 100644 --- a/mysql-test/main/flush_block_commit_notembedded.test +++ b/mysql-test/main/flush_block_commit_notembedded.test @@ -9,9 +9,6 @@ --source include/have_log_bin.inc --source include/have_innodb.inc ---echo # Save the initial number of concurrent sessions ---source include/count_sessions.inc - --disable_query_log # This may be triggered on a slow system or one that lacks native AIO. call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations"); @@ -62,7 +59,3 @@ drop table t1; connection default; disconnect con1; disconnect con2; - ---echo # Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/flush_read_lock.result b/mysql-test/main/flush_read_lock.result index a8f8431e1253b..8f5d39274809d 100644 --- a/mysql-test/main/flush_read_lock.result +++ b/mysql-test/main/flush_read_lock.result @@ -50,19 +50,6 @@ set local sql_mode=""; # check that DDL statements on temporary tables # are compatible with FTRWL. call mtr.add_suppression("BINLOG_BASE64_EVENT: Error executing row event.*error code: 1223"); -drop tables if exists t1_base, t2_base, t3_trans; -drop tables if exists tm_base, tm_base_temp; -drop database if exists mysqltest1; -# We're going to test ALTER DATABASE UPGRADE -drop database if exists `#mysql50#mysqltest-2`; -drop procedure if exists p1; -drop function if exists f1; -drop view if exists v1; -drop procedure if exists p2; -drop function if exists f2_base; -drop function if exists f2_temp; -drop event if exists e1; -drop event if exists e2; create table t1_base(i int) engine=myisam; create table t2_base(j int) engine=myisam; create table t3_trans(i int) engine=innodb; diff --git a/mysql-test/main/flush_read_lock.test b/mysql-test/main/flush_read_lock.test index 358f020d4bc0d..619780df0dcf9 100644 --- a/mysql-test/main/flush_read_lock.test +++ b/mysql-test/main/flush_read_lock.test @@ -9,9 +9,8 @@ --source include/have_debug_sync.inc # Parts of this test use DDL on events, BINLOG statement and # other statements which are not supported in embedded server. --- source include/not_embedded.inc -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc +--source include/not_embedded.inc +--source include/no_view_protocol.inc set global sql_mode=""; set local sql_mode=""; @@ -68,21 +67,6 @@ set local sql_mode=""; call mtr.add_suppression("BINLOG_BASE64_EVENT: Error executing row event.*error code: 1223"); ---disable_warnings -drop tables if exists t1_base, t2_base, t3_trans; -drop tables if exists tm_base, tm_base_temp; -drop database if exists mysqltest1; ---echo # We're going to test ALTER DATABASE UPGRADE -drop database if exists `#mysql50#mysqltest-2`; -drop procedure if exists p1; -drop function if exists f1; -drop view if exists v1; -drop procedure if exists p2; -drop function if exists f2_base; -drop function if exists f2_temp; -drop event if exists e1; -drop event if exists e2; ---enable_warnings create table t1_base(i int) engine=myisam; create table t2_base(j int) engine=myisam; create table t3_trans(i int) engine=innodb; @@ -2144,10 +2128,6 @@ disconnect con2; disconnect con3; set global sql_mode=default; -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc - --echo # --echo # Deadlock between FTWRL under open handler and DDL/LOCK TABLES diff --git a/mysql-test/main/flush_read_lock_kill.test b/mysql-test/main/flush_read_lock_kill.test index 8b76c0652272b..8807ea70ca791 100644 --- a/mysql-test/main/flush_read_lock_kill.test +++ b/mysql-test/main/flush_read_lock_kill.test @@ -13,9 +13,6 @@ # won't block FLUSH TABLES WITH GLOBAL READ LOCK. --source include/have_innodb.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; @@ -75,7 +72,3 @@ connection default; disconnect con2; DROP TABLE t1; SET DEBUG_SYNC= 'RESET'; - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/foreign_key.result b/mysql-test/main/foreign_key.result index 82bef2b23dee7..04067cb824c38 100644 --- a/mysql-test/main/foreign_key.result +++ b/mysql-test/main/foreign_key.result @@ -18,7 +18,7 @@ create table t2 (id int PRIMARY KEY, FOREIGN KEY (id) REFERENCES t1(id)) engine= insert into t1 values (1), (2), (3), (4), (5), (6); insert into t2 values (3), (5); delete from t1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) select * from t1; id 1 @@ -29,8 +29,8 @@ id 6 delete ignore from t1; Warnings: -Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) -Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) +Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) +Warning 1451 Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`id`) REFERENCES `t1` (`id`)) select row_count(); row_count() -1 diff --git a/mysql-test/main/foreign_key_lowercase0.result b/mysql-test/main/foreign_key_lowercase0.result new file mode 100644 index 0000000000000..d3322459ae285 --- /dev/null +++ b/mysql-test/main/foreign_key_lowercase0.result @@ -0,0 +1,21 @@ +CREATE TABLE `FAMILY_PARENT` ( +`PARENT_ID` char(36) NOT NULL, +`PARENT_NAME` varchar(200) NOT NULL, +PRIMARY KEY (`PARENT_ID`) +) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin; +CREATE TABLE `FAMILY_CHILD` ( +`PARENT_ID` char(36) NOT NULL, +`CHILD_NAME` varchar(200) NOT NULL, +PRIMARY KEY (`PARENT_ID`,`CHILD_NAME`), +CONSTRAINT `CHILD_FK` FOREIGN KEY (`PARENT_ID`) REFERENCES `FAMILY_PARENT` (`PARENT_ID`) ON DELETE CASCADE +) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin; +SHOW CREATE TABLE FAMILY_CHILD; +Table Create Table +FAMILY_CHILD CREATE TABLE `FAMILY_CHILD` ( + `PARENT_ID` char(36) NOT NULL, + `CHILD_NAME` varchar(200) NOT NULL, + PRIMARY KEY (`PARENT_ID`,`CHILD_NAME`), + CONSTRAINT `CHILD_FK` FOREIGN KEY (`PARENT_ID`) REFERENCES `FAMILY_PARENT` (`PARENT_ID`) ON DELETE CASCADE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin +DROP TABLE FAMILY_CHILD; +DROP TABLE FAMILY_PARENT; diff --git a/mysql-test/main/foreign_key_lowercase0.test b/mysql-test/main/foreign_key_lowercase0.test new file mode 100644 index 0000000000000..eafd3755166d2 --- /dev/null +++ b/mysql-test/main/foreign_key_lowercase0.test @@ -0,0 +1,22 @@ +# echo MDEV-34953 tablename of CONSTRAINT FOREIGN KEY REFERENCES +--source include/have_lowercase0.inc +--source include/have_innodb.inc +CREATE TABLE `FAMILY_PARENT` ( + `PARENT_ID` char(36) NOT NULL, + `PARENT_NAME` varchar(200) NOT NULL, + PRIMARY KEY (`PARENT_ID`) +) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +CREATE TABLE `FAMILY_CHILD` ( + `PARENT_ID` char(36) NOT NULL, + `CHILD_NAME` varchar(200) NOT NULL, + PRIMARY KEY (`PARENT_ID`,`CHILD_NAME`), + CONSTRAINT `CHILD_FK` FOREIGN KEY (`PARENT_ID`) REFERENCES `FAMILY_PARENT` (`PARENT_ID`) ON DELETE CASCADE +) ENGINE=InnoDB CHARSET=utf8mb4 COLLATE=utf8mb4_bin; + +# check that foreign key constraint name +SHOW CREATE TABLE FAMILY_CHILD; + +DROP TABLE FAMILY_CHILD; +DROP TABLE FAMILY_PARENT; + diff --git a/mysql-test/main/func_compress.test b/mysql-test/main/func_compress.test index d1822a099a357..a8170eed2db79 100644 --- a/mysql-test/main/func_compress.test +++ b/mysql-test/main/func_compress.test @@ -59,7 +59,6 @@ set @@global.max_allowed_packet=1048576*100; --connect (newconn, localhost, root,,) eval select compress(repeat('aaaaaaaaaa', IF('$LOW_MEMORY', 10, 10000000))) is null; disconnect newconn; ---source include/wait_until_disconnected.inc connection default; set @@global.max_allowed_packet=@save_max_allowed_packet; diff --git a/mysql-test/main/func_crypt.result b/mysql-test/main/func_crypt.result index 87c55dd21c38e..f97262238cd13 100644 --- a/mysql-test/main/func_crypt.result +++ b/mysql-test/main/func_crypt.result @@ -45,6 +45,8 @@ select password(NULL); password(NULL) set global old_passwords=on; +Warnings: +Warning 4200 The setting 'old_passwords' is ignored. It only exists for compatibility with old installations and will be removed in a future release select password(''); password('') @@ -58,20 +60,26 @@ select old_password('idkfa'); old_password('idkfa') 5c078dc54ca0fcca set old_passwords=on; +Warnings: +Warning 4200 The setting 'old_passwords' is ignored. It only exists for compatibility with old installations and will be removed in a future release select password('idkfa'); password('idkfa') -5c078dc54ca0fcca +*B669C9DAC3AA6F2254B03CDEF8DFDD6B2D1054BA select old_password('idkfa'); old_password('idkfa') 5c078dc54ca0fcca set global old_passwords=off; +Warnings: +Warning 4200 The setting 'old_passwords' is ignored. It only exists for compatibility with old installations and will be removed in a future release select password('idkfa'); password('idkfa') -5c078dc54ca0fcca +*B669C9DAC3AA6F2254B03CDEF8DFDD6B2D1054BA select old_password('idkfa'); old_password('idkfa') 5c078dc54ca0fcca set old_passwords=off; +Warnings: +Warning 4200 The setting 'old_passwords' is ignored. It only exists for compatibility with old installations and will be removed in a future release select password('idkfa '); password('idkfa ') *2DC31D90647B4C1ABC9231563D2236E96C9A2DB2 diff --git a/mysql-test/main/func_des_encrypt.result b/mysql-test/main/func_des_encrypt.result deleted file mode 100644 index e24f6b32b566b..0000000000000 --- a/mysql-test/main/func_des_encrypt.result +++ /dev/null @@ -1,101 +0,0 @@ -select des_encrypt('hello'); -des_encrypt('hello') -2nV} -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -# -# Bug #11643: des_encrypt() causes server to die -# -CREATE TABLE t1 (des VARBINARY(200) NOT NULL DEFAULT '') ENGINE=MyISAM; -INSERT INTO t1 VALUES ('1234'), ('12345'), ('123456'), ('1234567'); -UPDATE t1 SET des=DES_ENCRYPT('1234'); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -SELECT LENGTH(des) FROM t1; -LENGTH(des) -9 -9 -9 -9 -SELECT DES_DECRYPT(des) FROM t1; -DES_DECRYPT(des) -1234 -1234 -1234 -1234 -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -SELECT -LENGTH(DES_ENCRYPT('1234')), -LENGTH(DES_ENCRYPT('12345')), -LENGTH(DES_ENCRYPT('123456')), -LENGTH(DES_ENCRYPT('1234567')); -LENGTH(DES_ENCRYPT('1234')) LENGTH(DES_ENCRYPT('12345')) LENGTH(DES_ENCRYPT('123456')) LENGTH(DES_ENCRYPT('1234567')) -9 9 9 9 -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -SELECT -DES_DECRYPT(DES_ENCRYPT('1234')), -DES_DECRYPT(DES_ENCRYPT('12345')), -DES_DECRYPT(DES_ENCRYPT('123456')), -DES_DECRYPT(DES_ENCRYPT('1234567')); -DES_DECRYPT(DES_ENCRYPT('1234')) DES_DECRYPT(DES_ENCRYPT('12345')) DES_DECRYPT(DES_ENCRYPT('123456')) DES_DECRYPT(DES_ENCRYPT('1234567')) -1234 12345 123456 1234567 -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -DROP TABLE t1; -End of 5.0 tests -# -# MDEV-23330 Server crash or ASAN negative-size-param in -# my_strnncollsp_binary / SORT_FIELD_ATTR::compare_packed_varstrings -# -CREATE TABLE t1 (a CHAR(240), b BIT(48)); -INSERT INTO t1 VALUES ('a',b'0001'),('b',b'0010'),('c',b'0011'),('d',b'0100'),('e',b'0001'),('f',b'0101'),('g',b'0110'),('h',b'0111'),('i',b'1000'),('j',b'1001'); -SELECT DES_DECRYPT(a, 'x'), HEX(BINARY b) FROM t1 GROUP BY 1, 2 WITH ROLLUP; -DES_DECRYPT(a, 'x') HEX(BINARY b) -a 000000000001 -a NULL -b 000000000002 -b NULL -c 000000000003 -c NULL -d 000000000004 -d NULL -e 000000000001 -e NULL -f 000000000005 -f NULL -g 000000000006 -g NULL -h 000000000007 -h NULL -i 000000000008 -i NULL -j 000000000009 -j NULL -NULL NULL -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -DROP TABLE t1; -CREATE TABLE t1 (a INT); -INSERT t1 VALUES (1),(2); -SELECT CHAR_LENGTH(a), DES_DECRYPT(a) FROM (SELECT _utf8 0xC2A2 AS a FROM t1) AS t2; -CHAR_LENGTH(a) DES_DECRYPT(a) -1 -1 -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -DROP TABLE t1; -# -# End of 10.5 tests -# diff --git a/mysql-test/main/func_des_encrypt.test b/mysql-test/main/func_des_encrypt.test deleted file mode 100644 index 20f4c46fbf55c..0000000000000 --- a/mysql-test/main/func_des_encrypt.test +++ /dev/null @@ -1,70 +0,0 @@ --- source include/have_des.inc -#double warning for view protocol ---source include/no_view_protocol.inc - -# This test can't be in func_encrypt.test, because it requires -# --des-key-file to not be set. - -# -# Bug #11643: des_encrypt() causes server to die -# -select des_encrypt('hello'); - -# End of 4.1 tests - ---echo # ---echo # Bug #11643: des_encrypt() causes server to die ---echo # - -CREATE TABLE t1 (des VARBINARY(200) NOT NULL DEFAULT '') ENGINE=MyISAM; - -INSERT INTO t1 VALUES ('1234'), ('12345'), ('123456'), ('1234567'); - -UPDATE t1 SET des=DES_ENCRYPT('1234'); - -SELECT LENGTH(des) FROM t1; -SELECT DES_DECRYPT(des) FROM t1; - -SELECT - LENGTH(DES_ENCRYPT('1234')), - LENGTH(DES_ENCRYPT('12345')), - LENGTH(DES_ENCRYPT('123456')), - LENGTH(DES_ENCRYPT('1234567')); -SELECT - DES_DECRYPT(DES_ENCRYPT('1234')), - DES_DECRYPT(DES_ENCRYPT('12345')), - DES_DECRYPT(DES_ENCRYPT('123456')), - DES_DECRYPT(DES_ENCRYPT('1234567')); - -DROP TABLE t1; - ---Echo End of 5.0 tests - ---echo # ---echo # MDEV-23330 Server crash or ASAN negative-size-param in ---echo # my_strnncollsp_binary / SORT_FIELD_ATTR::compare_packed_varstrings ---echo # - -CREATE TABLE t1 (a CHAR(240), b BIT(48)); -INSERT INTO t1 VALUES ('a',b'0001'),('b',b'0010'),('c',b'0011'),('d',b'0100'),('e',b'0001'),('f',b'0101'),('g',b'0110'),('h',b'0111'),('i',b'1000'),('j',b'1001'); -SELECT DES_DECRYPT(a, 'x'), HEX(BINARY b) FROM t1 GROUP BY 1, 2 WITH ROLLUP; -DROP TABLE t1; - -# -# don't change the charset of a literal Item_string -# - -CREATE TABLE t1 (a INT); -INSERT t1 VALUES (1),(2); -# There is a problem with cursor-protocol and DES_DECRYPT(), -# but DES_DECRYPT has been deprecated from MariaDB 10.10.0, -# and will be removed in a future release. That's why this -# case is excluded without bug ---disable_cursor_protocol -SELECT CHAR_LENGTH(a), DES_DECRYPT(a) FROM (SELECT _utf8 0xC2A2 AS a FROM t1) AS t2; ---enable_cursor_protocol -DROP TABLE t1; - ---echo # ---echo # End of 10.5 tests ---echo # diff --git a/mysql-test/main/func_encrypt.result b/mysql-test/main/func_encrypt.result deleted file mode 100644 index d58f1ef5ef4be..0000000000000 --- a/mysql-test/main/func_encrypt.result +++ /dev/null @@ -1,373 +0,0 @@ -drop table if exists t1; -create table t1 (x blob); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('dog!','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('dog!!','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('dog!!!','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('dog!!!!','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('dog!!!!!','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala')); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -select hex(x), hex(des_decrypt(x,'sabakala')) from t1; -hex(x) hex(des_decrypt(x,'sabakala')) -FFA185A4656D113445E31D7A5B31BB57671A4CA9E21E63FE5D9C801E0CC7AA6190C13E269C2AE8D8060D3FB3FEA94FEC7FB006B9DCAC3E3E41 NULL -FFC620C3B84E926A54 NULL -FFA4F77D4220A16C980AF7CB576F8DC0A864F357825C16F329F24F66EBA775765B7C1538B90970740F853B556AEBD35AC31B962EA9B12B5AD4 NULL -FFACFF5921BB876A90 NULL -FFA6F18760E7CC5A4C325244B8486F692AAA11D229AF9ED4E4C9D56D7C0278C0DDA58F73E15E2B5F6C1DDD19B22B8071C454C930585449AAEB NULL -FF3736DFEDC4B765F4 NULL -FF598681EA5F03CD6D6AEA2B118DF4885DD78BECDFB012BBB05386E436DC403D3CB9DE3BE8D5D3BB7FD90A1F9F9A3E055BB3B4FD3F6A869473 NULL -FF15B8B5952D630CAE NULL -FF11EE3A400685226B76D5EC567681FA90247CE3C9DBE43341311C22F74562B1199957D80E300737791F6345BBC61AE03F28F52E5A6DCC78B2 NULL -FF0A832AE10DC85483 NULL -FF6F5C0BF4C5F899B4E7C091D9B1F1E92A7623B651B150CA3E7F420B4DD316D2C1BF76FCF9F9A046C000A9E21C106591E8C1930201B1750269 NULL -FFA08D5FB849A9FC90 NULL -FFF7331312FE153A39B1EC0D65BC1D3A0B6FCD49DA8C95D6161F53B11D297BAE142BCA6B9492DAE9A02AF455F16CA2C1CF4E1AD17297E947E2 NULL -FFDEE60A938478E059 NULL -FF95A729E73D5D87416A53055029E8CAA95B4F7B49F3D2D821A95D1FCE70F4B7A3226077176723F3DCC0A44D3B2EE9EFBC4D31AA87C948916C NULL -FF1C78557F542A1FDC91943761B2EED14F NULL -FF1E35B0775EEE512544A75BDAF58EA1655F5C899D3C5191A47263E2D11C3E688F662AB79F66D3B1DF9C75BD869EB8E04FDAE85719CB573A43 NULL -FF1C78557F542A1FDCDC4182B5314185E5 NULL -FF783123DCB36F98A51C39A560C92E129F1DDEEAB170825406A61260FBFBBFB0F2E48DB3282588A975C9C71E0EACA71A2B642A8C9C2E921A9F NULL -FF1C78557F542A1FDCAC4B1B6B47206306 NULL -FF6D9B450837017D06CA1F1C9A0E700D03DEF06A4F954527A961CA805F70320E9F3F0007636B80768A253A5F7ADABC18B78F1A2FA560CC0B21 NULL -FF1C78557F542A1FDCE9038BD99DD43F2E NULL -FF23FD03BA7548DD0957EBA7A8FBF7A18589762F3913E9A935BDA72F6F28202DC64572E0D633A54EA55BFD2C749E408C8632CCE36A7AE00619 NULL -FFD8DD3C4ABCB02FCDFE1383ECC0F61E7D02CD3BA72BBAEA26384D14835796501B3DC9A2F7EC2FC1633BDA6D56464536FE12010049C53A1991 54686520717569636B2072656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67 -FFACC5C5479575CBCA518B05778139B1BFC10F07299C98D04F580BC2F816828722D65A89C1831BD29DA626D319813BD374 717569636B2072656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67 -FF128D5517241DEEC631ABD2A47FA66E57930001417F18204328B0B2CB13F7AD2F50B8336EFAE7DE21 72656420666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67 -FF7CF971283B4DC2D050B3DB22684737B74B5B1CF12CF2FAC5A5995A298505F56D82BBFB9FC3E70059 666F78206A756D706564206F76657220746865206C617A792062726F776E20646F67 -FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67 -FFE8CB7FD80E6262C5FEB042A2DCC73B699CEEDCA6DC4458A0 6F76657220746865206C617A792062726F776E20646F67 -FFA29334D7CDB1B403DF3EB992067DD524C7D568E8D98EBFE5 746865206C617A792062726F776E20646F67 -FF4F0C5858FE2358D400E38831D5577C85 6C617A792062726F776E20646F67 -FFB370CD6BAFD1CB95974D21DCCA2DD9D7 62726F776E20646F67 -FF8F7777B28C7A459A 646F67 -FF75213A4D7D01D715 646F6721 -FF2DCAF574B173FB4D 646F672121 -FFFA775787BE776B15 646F67212121 -FF3FC2E42D7C840905 646F6721212121 -FF9723312D26D9E6DA01D01A784A64DB9D 646F672121212121 -FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67 -FF8333F3DD21E4488F967E03DD12394813A49F72848BB49473D3CB1C8A1AACF220 6A756D706564206F76657220746865206C617A792062726F776E20646F67 -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%'; -s -The quick red fox jumped over the lazy brown dog -quick red fox jumped over the lazy brown dog -red fox jumped over the lazy brown dog -fox jumped over the lazy brown dog -jumped over the lazy brown dog -over the lazy brown dog -the lazy brown dog -lazy brown dog -brown dog -dog -dog! -dog!! -dog!!! -dog!!!! -dog!!!!! -jumped over the lazy brown dog -jumped over the lazy brown dog -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -drop table t1; -select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello")); -hex(des_encrypt("hello")) des_decrypt(des_encrypt("hello")) -85D6DC8859F9759BBB hello -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(des_encrypt("hello",4)); -des_decrypt(des_encrypt("hello",4)) -hello -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(des_encrypt("hello",'test'),'test'); -des_decrypt(des_encrypt("hello",'test'),'test') -hello -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password')); -hex(des_encrypt("hello")) hex(des_encrypt("hello",5)) hex(des_encrypt("hello",'default_password')) -85D6DC8859F9759BBB 85D6DC8859F9759BBB FFD6DC8859F9759BBB -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -select des_decrypt(des_encrypt("hello"),'default_password'); -des_decrypt(des_encrypt("hello"),'default_password') -hello -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(des_encrypt("hello",4),'password4'); -des_decrypt(des_encrypt("hello",4),'password4') -hello -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_encrypt("hello",10); -des_encrypt("hello",10) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1108 Incorrect parameters to procedure 'des_encrypt' -select des_encrypt(NULL); -des_encrypt(NULL) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -select des_encrypt(NULL, 10); -des_encrypt(NULL, 10) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -select des_encrypt(NULL, NULL); -des_encrypt(NULL, NULL) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -select des_encrypt(10, NULL); -des_encrypt(10, NULL) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1108 Incorrect parameters to procedure 'des_encrypt' -select des_encrypt("hello", NULL); -des_encrypt("hello", NULL) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1108 Incorrect parameters to procedure 'des_encrypt' -select des_decrypt("hello",10); -des_decrypt("hello",10) -hello -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(NULL); -des_decrypt(NULL) -NULL -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(NULL, 10); -des_decrypt(NULL, 10) -NULL -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(NULL, NULL); -des_decrypt(NULL, NULL) -NULL -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt(10, NULL); -des_decrypt(10, NULL) -10 -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select des_decrypt("hello", NULL); -des_decrypt("hello", NULL) -hello -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -SET @a=des_decrypt(des_encrypt("hello")); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -flush des_key_file; -select @a = des_decrypt(des_encrypt("hello")); -@a = des_decrypt(des_encrypt("hello")) -1 -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select hex("hello"); -hex("hello") -68656C6C6F -select hex(des_decrypt(des_encrypt("hello",4),'password2')); -hex(des_decrypt(des_encrypt("hello",4),'password2')) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select hex(des_decrypt(des_encrypt("hello","hidden"))); -hex(des_decrypt(des_encrypt("hello","hidden"))) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1108 Incorrect parameters to procedure 'des_decrypt' -explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_decrypt(des_encrypt("hello","hidden")); -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Note 1003 select des_decrypt(des_encrypt('hello',4),'password2') AS `des_decrypt(des_encrypt("hello",4),'password2')`,des_decrypt(des_encrypt('hello','hidden')) AS `des_decrypt(des_encrypt("hello","hidden"))` -# -# Start of 10.1 tests -# -# -# MDEV-8369 Unexpected impossible WHERE for a condition on a ZEROFILL field -# -CREATE TABLE t1 (a INT(6) ZEROFILL); -INSERT INTO t1 VALUES (1),(2); -EXPLAIN EXTENDED -SELECT * FROM t1 WHERE a=1 AND DES_ENCRYPT('test',a)=_latin1 'abc' COLLATE latin1_bin; -id select_type table type possible_keys key key_len ref rows filtered Extra -1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 Using where -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = 1 and des_encrypt('test',`test`.`t1`.`a`) = 'abc' -DROP TABLE t1; -# -# End of 10.1 tests -# -# -# Start of 10.2 tests -# -# -# MDEV-10134 Add full support for DEFAULT -# -CREATE TABLE t1 ( -a VARCHAR(30), -b BLOB DEFAULT DES_ENCRYPT(a, 'passwd'), -c TEXT DEFAULT DES_DECRYPT(b, 'passwd') -); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `a` varchar(30) DEFAULT NULL, - `b` blob DEFAULT des_encrypt(`a`,'passwd'), - `c` text DEFAULT des_decrypt(`b`,'passwd') -) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci -INSERT INTO t1 (a) VALUES ('test'); -SELECT c FROM t1; -c -test -DROP TABLE t1; -# -# End of 10.2 tests -# diff --git a/mysql-test/main/func_encrypt.test b/mysql-test/main/func_encrypt.test deleted file mode 100644 index 306939ef2ac85..0000000000000 --- a/mysql-test/main/func_encrypt.test +++ /dev/null @@ -1,134 +0,0 @@ --- source include/have_des.inc -#double warning for view protocol ---source include/no_view_protocol.inc - ---disable_warnings -drop table if exists t1; ---enable_warnings - -create table t1 (x blob); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('a','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','a')); -insert into t1 values (des_encrypt('ab','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','ab')); -insert into t1 values (des_encrypt('abc','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abc')); -insert into t1 values (des_encrypt('abcd','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcd')); -insert into t1 values (des_encrypt('abcde','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcde')); -insert into t1 values (des_encrypt('abcdef','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdef')); -insert into t1 values (des_encrypt('abcdefg','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefg')); -insert into t1 values (des_encrypt('abcdefgh','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefgh')); -insert into t1 values (des_encrypt('abcdefghi','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghi')); -insert into t1 values (des_encrypt('abcdefghij','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghij')); -insert into t1 values (des_encrypt('abcdefghijk','The quick red fox jumped over the lazy brown dog')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','abcdefghijk')); -insert into t1 values (des_encrypt('The quick red fox jumped over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('quick red fox jumped over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('red fox jumped over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('fox jumped over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('brown dog','sabakala')); -insert into t1 values (des_encrypt('dog','sabakala')); -insert into t1 values (des_encrypt('dog!','sabakala')); -insert into t1 values (des_encrypt('dog!!','sabakala')); -insert into t1 values (des_encrypt('dog!!!','sabakala')); -insert into t1 values (des_encrypt('dog!!!!','sabakala')); -insert into t1 values (des_encrypt('dog!!!!!','sabakala')); -insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala')); -insert into t1 values (des_encrypt('jumped over the lazy brown dog','sabakala')); -select hex(x), hex(des_decrypt(x,'sabakala')) from t1; -select des_decrypt(x,'sabakala') as s from t1 having s like '%dog%'; -drop table t1; - -# -# Test default keys -# -select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello")); -select des_decrypt(des_encrypt("hello",4)); -select des_decrypt(des_encrypt("hello",'test'),'test'); -select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password')); -select des_decrypt(des_encrypt("hello"),'default_password'); -select des_decrypt(des_encrypt("hello",4),'password4'); - -# Test use of invalid parameters -select des_encrypt("hello",10); -select des_encrypt(NULL); -select des_encrypt(NULL, 10); -select des_encrypt(NULL, NULL); -select des_encrypt(10, NULL); -select des_encrypt("hello", NULL); - -select des_decrypt("hello",10); -select des_decrypt(NULL); -select des_decrypt(NULL, 10); -select des_decrypt(NULL, NULL); -select des_decrypt(10, NULL); -select des_decrypt("hello", NULL); - - -# Test flush -SET @a=des_decrypt(des_encrypt("hello")); -flush des_key_file; -select @a = des_decrypt(des_encrypt("hello")); - -# Test usage of wrong password -select hex("hello"); -select hex(des_decrypt(des_encrypt("hello",4),'password2')); -select hex(des_decrypt(des_encrypt("hello","hidden"))); - -explain extended select des_decrypt(des_encrypt("hello",4),'password2'), des_decrypt(des_encrypt("hello","hidden")); - -# End of 4.1 tests - ---echo # ---echo # Start of 10.1 tests ---echo # - ---echo # ---echo # MDEV-8369 Unexpected impossible WHERE for a condition on a ZEROFILL field ---echo # -CREATE TABLE t1 (a INT(6) ZEROFILL); -INSERT INTO t1 VALUES (1),(2); -# This should not propagate a=1 into DES_ENCRYPT -EXPLAIN EXTENDED -SELECT * FROM t1 WHERE a=1 AND DES_ENCRYPT('test',a)=_latin1 'abc' COLLATE latin1_bin; -DROP TABLE t1; - ---echo # ---echo # End of 10.1 tests ---echo # - ---echo # ---echo # Start of 10.2 tests ---echo # - ---echo # ---echo # MDEV-10134 Add full support for DEFAULT ---echo # - -CREATE TABLE t1 ( - a VARCHAR(30), - b BLOB DEFAULT DES_ENCRYPT(a, 'passwd'), - c TEXT DEFAULT DES_DECRYPT(b, 'passwd') -); ---disable_warnings -SHOW CREATE TABLE t1; ---enable_warnings -INSERT INTO t1 (a) VALUES ('test'); -SELECT c FROM t1; -DROP TABLE t1; - ---echo # ---echo # End of 10.2 tests ---echo # diff --git a/mysql-test/main/func_encrypt_nossl.result b/mysql-test/main/func_encrypt_nossl.result deleted file mode 100644 index 274db05fd8cea..0000000000000 --- a/mysql-test/main/func_encrypt_nossl.result +++ /dev/null @@ -1,131 +0,0 @@ -select des_encrypt("test", 'akeystr'); -des_encrypt("test", 'akeystr') -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_encrypt("test", 1); -des_encrypt("test", 1) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_encrypt("test", 9); -des_encrypt("test", 9) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_encrypt("test", 100); -des_encrypt("test", 100) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_encrypt("test", NULL); -des_encrypt("test", NULL) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_encrypt(NULL, NULL); -des_encrypt(NULL, NULL) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt("test", 'anotherkeystr'); -des_decrypt("test", 'anotherkeystr') -NULL -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt(1, 1); -des_decrypt(1, 1) -NULL -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt(des_encrypt("test", 'thekey')); -des_decrypt(des_encrypt("test", 'thekey')) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello")); -hex(des_encrypt("hello")) des_decrypt(des_encrypt("hello")) -NULL NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt(des_encrypt("hello",4)); -des_decrypt(des_encrypt("hello",4)) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt(des_encrypt("hello",'test'),'test'); -des_decrypt(des_encrypt("hello",'test'),'test') -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password')); -hex(des_encrypt("hello")) hex(des_encrypt("hello",5)) hex(des_encrypt("hello",'default_password')) -NULL NULL NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -Warning 1289 The 'des_encrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt(des_encrypt("hello"),'default_password'); -des_decrypt(des_encrypt("hello"),'default_password') -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select des_decrypt(des_encrypt("hello",4),'password4'); -des_decrypt(des_encrypt("hello",4),'password4') -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -SET @a=des_decrypt(des_encrypt("hello")); -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -flush des_key_file; -select @a = des_decrypt(des_encrypt("hello")); -@a = des_decrypt(des_encrypt("hello")) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -select hex("hello"); -hex("hello") -68656C6C6F -select hex(des_decrypt(des_encrypt("hello",4),'password2')); -hex(des_decrypt(des_encrypt("hello",4),'password2')) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working -select hex(des_decrypt(des_encrypt("hello","hidden"))); -hex(des_decrypt(des_encrypt("hello","hidden"))) -NULL -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1289 The 'des_decrypt' feature is disabled; you need MariaDB built with 'openssl des cipher (HAVE_des)' to have it working diff --git a/mysql-test/main/func_encrypt_nossl.test b/mysql-test/main/func_encrypt_nossl.test deleted file mode 100644 index a9718a1644ad4..0000000000000 --- a/mysql-test/main/func_encrypt_nossl.test +++ /dev/null @@ -1,38 +0,0 @@ --- source include/is_embedded.inc - -# -# Test output from des_encrypt and des_decrypt when server is -# compiled without openssl support -# -select des_encrypt("test", 'akeystr'); -select des_encrypt("test", 1); -select des_encrypt("test", 9); -select des_encrypt("test", 100); -select des_encrypt("test", NULL); -select des_encrypt(NULL, NULL); -select des_decrypt("test", 'anotherkeystr'); -select des_decrypt(1, 1); -select des_decrypt(des_encrypt("test", 'thekey')); - - -# -# Test default keys -# -select hex(des_encrypt("hello")),des_decrypt(des_encrypt("hello")); -select des_decrypt(des_encrypt("hello",4)); -select des_decrypt(des_encrypt("hello",'test'),'test'); -select hex(des_encrypt("hello")),hex(des_encrypt("hello",5)),hex(des_encrypt("hello",'default_password')); -select des_decrypt(des_encrypt("hello"),'default_password'); -select des_decrypt(des_encrypt("hello",4),'password4'); - -# Test flush -SET @a=des_decrypt(des_encrypt("hello")); -flush des_key_file; -select @a = des_decrypt(des_encrypt("hello")); - -# Test usage of wrong password -select hex("hello"); -select hex(des_decrypt(des_encrypt("hello",4),'password2')); -select hex(des_decrypt(des_encrypt("hello","hidden"))); - -# End of 4.1 tests diff --git a/mysql-test/main/func_encrypt_ucs2.result b/mysql-test/main/func_encrypt_ucs2.result deleted file mode 100644 index 0aed95c3eabb5..0000000000000 --- a/mysql-test/main/func_encrypt_ucs2.result +++ /dev/null @@ -1,25 +0,0 @@ -# -# Bug#59648 my_strtoll10_mb2: Assertion `(*endptr - s) % 2 == 0' failed. -# -SELECT CHAR_LENGTH(DES_ENCRYPT(0, CHAR('1' USING ucs2))); -CHAR_LENGTH(DES_ENCRYPT(0, CHAR('1' USING ucs2))) -9 -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -SELECT CONVERT(DES_ENCRYPT(0, CHAR('1' USING ucs2)),UNSIGNED); -CONVERT(DES_ENCRYPT(0, CHAR('1' USING ucs2)),UNSIGNED) -0 -Warnings: -Warning 1287 'des_encrypt' is deprecated and will be removed in a future release -Warning 1292 Truncated incorrect INTEGER value: '\xFFT\xDCiK\x92j\xE6\xFC' -SELECT CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))) as a; -a -4 -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -SELECT CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED) as a; -a -0 -Warnings: -Warning 1287 'des_decrypt' is deprecated and will be removed in a future release -Warning 1292 Truncated incorrect INTEGER value: 'test' diff --git a/mysql-test/main/func_encrypt_ucs2.test b/mysql-test/main/func_encrypt_ucs2.test deleted file mode 100644 index aaf233fa0315e..0000000000000 --- a/mysql-test/main/func_encrypt_ucs2.test +++ /dev/null @@ -1,16 +0,0 @@ --- source include/have_des.inc --- source include/have_ucs2.inc -#double warning for view protocol ---source include/no_view_protocol.inc - ---echo # ---echo # Bug#59648 my_strtoll10_mb2: Assertion `(*endptr - s) % 2 == 0' failed. ---echo # - -SELECT CHAR_LENGTH(DES_ENCRYPT(0, CHAR('1' USING ucs2))); -SELECT CONVERT(DES_ENCRYPT(0, CHAR('1' USING ucs2)),UNSIGNED); - ---disable_view_protocol -SELECT CHAR_LENGTH(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' USING ucs2))) as a; -SELECT CONVERT(DES_DECRYPT(0xFF0DC9FC9537CA75F4, CHAR('1' using ucs2)), UNSIGNED) as a; ---enable_view_protocol diff --git a/mysql-test/main/func_extract.result b/mysql-test/main/func_extract.result index b8dcb86ae24af..05946fd2ec9f8 100644 --- a/mysql-test/main/func_extract.result +++ b/mysql-test/main/func_extract.result @@ -74,16 +74,22 @@ INSERT INTO t1 VALUES # Expect empty sets SELECT a, b, EXTRACT(DAY_HOUR FROM a), EXTRACT(DAY_HOUR FROM b) FROM t1 WHERE NOT (EXTRACT(DAY_HOUR FROM a)<=>EXTRACT(DAY_HOUR FROM b)); a b EXTRACT(DAY_HOUR FROM a) EXTRACT(DAY_HOUR FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(DAY FROM a), EXTRACT(DAY FROM b) FROM t1 WHERE NOT (EXTRACT(DAY FROM a)<=>EXTRACT(DAY FROM b)); a b EXTRACT(DAY FROM a) EXTRACT(DAY FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(HOUR FROM a), EXTRACT(HOUR FROM b) FROM t1 WHERE NOT (EXTRACT(HOUR FROM a)<=>EXTRACT(HOUR FROM b)); a b EXTRACT(HOUR FROM a) EXTRACT(HOUR FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(MINUTE FROM a), EXTRACT(MINUTE FROM b) FROM t1 WHERE NOT (EXTRACT(MINUTE FROM a)<=>EXTRACT(MINUTE FROM b)); a b EXTRACT(MINUTE FROM a) EXTRACT(MINUTE FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(SECOND FROM a), EXTRACT(SECOND FROM b) FROM t1 WHERE NOT (EXTRACT(SECOND FROM a)<=>EXTRACT(SECOND FROM b)); a b EXTRACT(SECOND FROM a) EXTRACT(SECOND FROM b) +0.999999 0.999999000 0 NULL SELECT a, b, EXTRACT(MICROSECOND FROM a), EXTRACT(MICROSECOND FROM b) FROM t1 WHERE NOT (EXTRACT(MICROSECOND FROM a)<=>EXTRACT(MICROSECOND FROM b)); a b EXTRACT(MICROSECOND FROM a) EXTRACT(MICROSECOND FROM b) +0.999999 0.999999000 999999 NULL # Detailed results SELECT a, @@ -118,32 +124,32 @@ Warnings: Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '9999-12-31 23:59:59.123456' Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '2001-01-01 10:20:30.123456' Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' -Warning 1292 Incorrect interval value: '4294967296:59:59.123456' +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect interval value: '4294967296:59:59.123456' for column `test`.`t1`.`a` at row 3 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' -Warning 1292 Incorrect interval value: '4294967295:59:59.123456' +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 +Warning 1292 Incorrect interval value: '4294967295:59:59.123456' for column `test`.`t1`.`a` at row 4 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' -Warning 1292 Incorrect interval value: '87649416:59:59.123456' +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 +Warning 1292 Incorrect interval value: '87649416:59:59.123456' for column `test`.`t1`.`a` at row 5 SELECT b, CAST(b AS INTERVAL DAY_SECOND(6)) AS cidm, @@ -166,7 +172,7 @@ b cidm dh EXTRACT(DAY_HOUR FROM b) EXTRACT(DAY FROM b) EXTRACT(HOUR FROM b) EXTR 99995959.123456000 416 15:59:59.123456 9999 41615 416 15 59 59 123456 99990101.123456000 416 15:01:01.123456 9999 41615 416 15 1 1 123456 99990101.000000000 416 15:01:01.000000 9999 41615 416 15 1 1 0 -0.999999000 00:00:00.999999 0 0 0 0 0 0 999999 +0.999999000 00:00:00.999999 NULL NULL NULL NULL NULL NULL NULL 0.999990000 00:00:00.999990 0 0 0 0 0 0 999990 0.999900000 00:00:00.999900 0 0 0 0 0 0 999900 0.999000000 00:00:00.999000 0 0 0 0 0 0 999000 @@ -209,6 +215,14 @@ Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '99995959.123456000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '99990101.123456000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '99990101.000000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999999000' +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 +Warning 1292 Incorrect interval value: '0.999999000' for column `test`.`t1`.`b` at row 11 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999990000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999900000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.999000000' @@ -252,15 +266,15 @@ a cidm EXTRACT(DAY_HOUR FROM a) EXTRACT(DAY_MINUTE FROM a) EXTRACT(DAY_SECOND FR NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' -Warning 1292 Incorrect interval value: '' +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect interval value: '' for column `test`.`t1`.`a` at row 1 DROP TABLE t1; # Backward compatibility # This still parses as DATETIME @@ -600,26 +614,26 @@ EXTRACT(DAY FROM a) EXTRACT(DAY_SECOND FROM a) a cidm 0 10203 01:02:03/ 01:02:03.000000 20 20102030 20 10:20:30 20 10:20:30.000000 Warnings: -Warning 1292 Truncated incorrect time value: '2024:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '2024:01:03 garbage /////' +Warning 1292 Incorrect time value: '2024:01:03 garbage /////' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect time value: '2024:01:03 garbage /////' for column `test`.`t1`.`a` at row 1 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '2024:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '24:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '24:01:03 garbage /////' +Warning 1292 Incorrect time value: '24:01:03 garbage /////' for column `test`.`t1`.`a` at row 2 +Warning 1292 Incorrect time value: '24:01:03 garbage /////' for column `test`.`t1`.`a` at row 2 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '24:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '01:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '01:01:03 garbage /////' +Warning 1292 Incorrect time value: '01:01:03 garbage /////' for column `test`.`t1`.`a` at row 3 +Warning 1292 Incorrect time value: '01:01:03 garbage /////' for column `test`.`t1`.`a` at row 3 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '01:01:03 garbage /////' -Warning 1292 Truncated incorrect time value: '01:02:03:' -Warning 1292 Truncated incorrect time value: '01:02:03:' +Warning 1292 Incorrect time value: '01:02:03:' for column `test`.`t1`.`a` at row 8 +Warning 1292 Incorrect time value: '01:02:03:' for column `test`.`t1`.`a` at row 8 Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03:' -Warning 1292 Truncated incorrect time value: '01:02:03-' -Warning 1292 Truncated incorrect time value: '01:02:03-' +Warning 1292 Incorrect time value: '01:02:03-' for column `test`.`t1`.`a` at row 9 +Warning 1292 Incorrect time value: '01:02:03-' for column `test`.`t1`.`a` at row 9 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '01:02:03-' -Warning 1292 Truncated incorrect time value: '01:02:03;' -Warning 1292 Truncated incorrect time value: '01:02:03;' +Warning 1292 Incorrect time value: '01:02:03;' for column `test`.`t1`.`a` at row 10 +Warning 1292 Incorrect time value: '01:02:03;' for column `test`.`t1`.`a` at row 10 Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03;' -Warning 1292 Truncated incorrect time value: '01:02:03/' -Warning 1292 Truncated incorrect time value: '01:02:03/' +Warning 1292 Incorrect time value: '01:02:03/' for column `test`.`t1`.`a` at row 11 +Warning 1292 Incorrect time value: '01:02:03/' for column `test`.`t1`.`a` at row 11 Warning 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '01:02:03/' DROP TABLE t1; # diff --git a/mysql-test/main/func_group.result b/mysql-test/main/func_group.result index b669f44b4e33d..c5a9a56fc52a0 100644 --- a/mysql-test/main/func_group.result +++ b/mysql-test/main/func_group.result @@ -1530,6 +1530,9 @@ DROP TABLE t1; # # Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) # +set old_mode=2_DIGIT_YEAR; +Warnings: +Warning 1287 '2_DIGIT_YEAR' is deprecated and will be removed in a future release create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime); Warnings: Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead @@ -1775,6 +1778,7 @@ f1 f2 f3 f4 f1 = f2 NULL NULL NULL NULL NULL 71 1971 1971-01-01 1971-11-11 22:22:22 1 drop table t1; +set old_mode=DEFAULT; # # Bug #54465: assert: field_types == 0 || field_types[field_pos] == # MYSQL_TYPE_LONGLONG @@ -2569,6 +2573,23 @@ concat(a,":",group_concat(b)) 1:2,7 4:5 drop table t1; -# # End of 10.3 tests # +# MDEV-37888 unexpected type changing after changing AVG to MAX +# +SELECT 1, MAX(1), AVG(1); +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def 1 3 1 1 N 32897 0 63 +def MAX(1) 8 1 1 Y 32896 0 63 +def AVG(1) 246 7 6 Y 32896 4 63 +1 MAX(1) AVG(1) +1 1 1.0000 +SELECT 1, MAX(1), AVG(1) UNION ALL SELECT 'one', 'max', 'avg'; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def 1 253 3 3 N 1 39 8 +def MAX(1) 253 3 3 Y 0 39 8 +def AVG(1) 253 7 7 Y 0 39 8 +1 MAX(1) AVG(1) +1 1 1.00000 +one max avg +# End of 10.11 tests diff --git a/mysql-test/main/func_group.test b/mysql-test/main/func_group.test index 4cfeb46f36808..4255dcac8bd7e 100644 --- a/mysql-test/main/func_group.test +++ b/mysql-test/main/func_group.test @@ -1069,6 +1069,7 @@ DROP TABLE t1; --echo # --echo # Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) --echo # +set old_mode=2_DIGIT_YEAR; --enable_prepare_warnings create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime); --disable_prepare_warnings @@ -1098,6 +1099,7 @@ select a.f1 as a, b.f4 as b, a.f1 > b.f4 as gt, from t1 a, t1 b; select *, f1 = f2 from t1; drop table t1; +set old_mode=DEFAULT; --echo # --echo # Bug #54465: assert: field_types == 0 || field_types[field_pos] == @@ -1802,6 +1804,16 @@ insert t1 values (1,2,3),(4,5,6),(1,7,8); select concat(a,":",group_concat(b)) from t1 group by a; drop table t1; ---echo # --echo # End of 10.3 tests + --echo # +--echo # MDEV-37888 unexpected type changing after changing AVG to MAX +--echo # +enable_metadata; +disable_view_protocol; +SELECT 1, MAX(1), AVG(1); +SELECT 1, MAX(1), AVG(1) UNION ALL SELECT 'one', 'max', 'avg'; +enable_view_protocol; +disable_metadata; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/func_hybrid_type.result b/mysql-test/main/func_hybrid_type.result index 9885a9a1c2489..40b288e9e69a3 100644 --- a/mysql-test/main/func_hybrid_type.result +++ b/mysql-test/main/func_hybrid_type.result @@ -3456,8 +3456,8 @@ SELECT DISTINCT - GREATEST( b, CAST( NULL AS DATETIME ) ) AS f FROM t1; f NULL Warnings: -Warning 1292 Truncated incorrect datetime value: 'foo' -Warning 1292 Truncated incorrect datetime value: 'bar' +Warning 1292 Incorrect datetime value: 'foo' for column `test`.`t1`.`b` at row 1 +Warning 1292 Incorrect datetime value: 'bar' for column `test`.`t1`.`b` at row 2 DROP TABLE t1; CREATE TABLE t1 (b LONGBLOB); INSERT IGNORE INTO t1 VALUES ('foo'),('bar'); @@ -3465,8 +3465,8 @@ SELECT DISTINCT - GREATEST( b, CAST( NULL AS TIME) ) AS f FROM t1; f NULL Warnings: -Warning 1292 Incorrect time value: 'foo' -Warning 1292 Incorrect time value: 'bar' +Warning 1292 Incorrect time value: 'foo' for column `test`.`t1`.`b` at row 1 +Warning 1292 Incorrect time value: 'bar' for column `test`.`t1`.`b` at row 2 DROP TABLE t1; CREATE TABLE t1 (b LONGBLOB); INSERT IGNORE INTO t1 VALUES ('foo'),('bar'); @@ -3474,8 +3474,8 @@ SELECT DISTINCT - GREATEST( b, CAST( NULL AS DATE) ) AS f FROM t1; f NULL Warnings: -Warning 1292 Truncated incorrect datetime value: 'foo' -Warning 1292 Truncated incorrect datetime value: 'bar' +Warning 1292 Incorrect datetime value: 'foo' for column `test`.`t1`.`b` at row 1 +Warning 1292 Incorrect datetime value: 'bar' for column `test`.`t1`.`b` at row 2 DROP TABLE t1; # # End of 10.1 tests diff --git a/mysql-test/main/func_json.result b/mysql-test/main/func_json.result index e4e26cd2cceba..a549cb73291e0 100644 --- a/mysql-test/main/func_json.result +++ b/mysql-test/main/func_json.result @@ -640,24 +640,20 @@ ex set @save_max_allowed_packet=@@max_allowed_packet; set @save_net_buffer_length=@@net_buffer_length; set @@global.net_buffer_length=1024; -set @@global.max_allowed_packet=2048; +set @@global.max_allowed_packet=4096; connect newconn, localhost, root,,; show variables like 'net_buffer_length'; Variable_name Value net_buffer_length 1024 show variables like 'max_allowed_packet'; Variable_name Value -max_allowed_packet 2048 +max_allowed_packet 4096 select json_array(repeat('a',1024),repeat('a',1024)) as ex; ex -NULL -Warnings: -Warning 1301 Result of json_array() was larger than max_allowed_packet (2048) - truncated +["aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"] select json_object("a", repeat('a',1024),"b", repeat('a',1024)) as ex; ex -NULL -Warnings: -Warning 1301 Result of json_object() was larger than max_allowed_packet (2048) - truncated +{"a": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "b": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"} connection default; set @@global.max_allowed_packet = @save_max_allowed_packet; set @@global.net_buffer_length = @save_net_buffer_length; @@ -679,7 +675,7 @@ JSON_SEARCH('{"foo":"bar"}', 'all' , @str, '%', @path) "$.foo" SELECT JSON_VALUE('[{"foo": 1},"bar"]', '$[*][0]'); JSON_VALUE('[{"foo": 1},"bar"]', '$[*][0]') -bar +NULL CREATE TABLE t1 (f INT NOT NULL); INSERT INTO t1 VALUES (0); SELECT JSON_KEYS(f) FROM t1 ORDER BY 1; @@ -1062,9 +1058,6 @@ SELECT JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a'); JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a') null # -# Start of 10.4 tests -# -# # MDEV-16351 JSON_OBJECT() treats hybrid functions with boolean arguments as numbers # SELECT @@ -1476,7 +1469,7 @@ SET @old_collation_connection= @@COLLATION_CONNECTION; SET COLLATION_CONNECTION= ucs2_unicode_ci; SELECT JSON_VALUE('["foo"]', '$**[0]') AS f; f -foo +NULL SET @@COLLATION_CONNECTION= @old_collation_connection; # # MDEV-32587 JSON_VALID fail to validate integer zero in scientific notation @@ -2404,7 +2397,7 @@ SET @json= '[ ]'; SELECT JSON_VALUE(@json, '$[0][1 to 2].key1'); JSON_VALUE(@json, '$[0][1 to 2].key1') -value1 +NULL SET @json='{ "A": [0, [1, 2, 3], @@ -2421,7 +2414,7 @@ SET @json='{ }'; SELECT JSON_QUERY(@json, '$.A[-2][-3 to -1]'); JSON_QUERY(@json, '$.A[-2][-3 to -1]') -[13, 14] +NULL SET @json= '[ [1, {"key1": "value1"}, 3], [false, 5, 6], @@ -2569,7 +2562,7 @@ SET @json1= '[ ]'; SELECT JSON_VALUE(@json1, '$[2][1 to 2].key1'); JSON_VALUE(@json1, '$[2][1 to 2].key1') -value7 +NULL SET @json= '[ [1.1, {"key1": "value1"}, 3], [false, 5, 6], @@ -2579,10 +2572,10 @@ SET @json= '[ ]'; SELECT JSON_VALUE(@json, '$[*][0]'); JSON_VALUE(@json, '$[*][0]') -1.1 +NULL SELECT JSON_VALUE(@json, '$[2 to 3][0]'); JSON_VALUE(@json, '$[2 to 3][0]') -7 +NULL # # MDEV-28072: JSON_EXTRACT has inconsistent behavior with '0' value in # json path (when range is used) @@ -2691,6 +2684,108 @@ NULL SET @@collation_connection= @save_collation_connection; # End of 10.9 Test # +# MDEV-30691 Assertion `strlen(Ptr) == str_length' failed in void Binary_string::chop() +# +set @@collation_connection=utf32_czech_ci; +select json_detailed('[[123],456]'); +json_detailed('[[123],456]') +[ + [123], + 456 +] +set @@collation_connection=@save_collation_connection; +select json_detailed('[[123],456]'); +json_detailed('[[123],456]') +[ + [123], + 456 +] +# +# MDEV-37428 JSON_VALUE returns NULL for a key with an empty string value rather than an empty string +# +SELECT JSON_VALUE(JSON_OBJECT("a", ""), '$.a') = "" AS not_null; +not_null +1 +# +# MDEV-36319: Wrong result json_table +# +SET @JSON=' +{ + "SZ": [ + { + "NAME": "S0", + "OFFERS": [ + { + "NAME": "S0A0" + } + ] + }, + { + "NAME": "S1", + "OFFERS": [ + { + "NAME": "S1A0" + }, + { + "NAME": "S1A1" + } + ] + }, + { + "NAME": "S2", + "OFFERS": [ + { + "NAME": "S2A0" + } + ] + }, + { + "NAME": "S3", + "OFFERS": [ + { + "NAME": "S3A0" + } + ] + }, + { + "NAME": "S4", + "OFFERS": [ + { + "NAME": "S4A0" + } + ] + }, + { + "NAME": "S5", + "OFFERS": [ + { + "NAME": "S5A0" + } + ] + } + ] +} + +' +; +# Should return EMPTY result +SELECT * FROM json_table(@JSON, '$.SZ[0].OFFERS[1]' +COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; +NAME +# Should return S1A1 +SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]' +COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; +NAME +S1A1 +# +# MDEV-25148: Unexpected success and result set upon erroneous +# JSON_VALUE call +# +SELECT JSON_VALUE('{"a":[1,2]}', '$.a[*]'); +JSON_VALUE('{"a":[1,2]}', '$.a[*]') +NULL +# End of 10.11 Test +# # MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-) # as first character in key # @@ -4842,16 +4937,16 @@ JSON_SCHEMA_VALID(@schema_array, '[') 0 Warnings: Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_schema_valid' -SELECT JSON_SCHEMA_VALID(repeat('[', 100000), json_object()); -JSON_SCHEMA_VALID(repeat('[', 100000), json_object()) +SELECT JSON_SCHEMA_VALID(repeat('[', 100), json_object()); +JSON_SCHEMA_VALID(repeat('[', 100), json_object()) NULL Warnings: -Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 1 to function 'json_schema_valid' at position 32 -SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000)); -JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000)) +Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_schema_valid' +SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 100)); +JSON_SCHEMA_VALID(json_object(), repeat('[', 100)) 0 Warnings: -Warning 4040 Limit of 32 on JSON nested structures depth is reached in argument 2 to function 'json_schema_valid' at position 32 +Warning 4037 Unexpected end of JSON text in argument 2 to function 'json_schema_valid' # # MDEV-30677: Incorrect result for "SELECT JSON_SCHEMA_VALID('{}', NULL)" # @@ -4895,6 +4990,8 @@ NULL SELECT JSON_KEY_VALUE('', '$.a'); JSON_KEY_VALUE('', '$.a') NULL +Warnings: +Warning 4037 Unexpected end of JSON text in argument 1 to function 'json_key_value' SELECT JSON_KEY_VALUE('[1,2,3]', ''); JSON_KEY_VALUE('[1,2,3]', '') NULL @@ -5069,6 +5166,7 @@ FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; k v id +# End of 11.2 test # # MDEV-26182: Implement json_array_intersect() # @@ -5265,4 +5363,405 @@ SET @obj1='{ "a": 1,"b": 2,"c": 3}'; SELECT JSON_OBJECT_FILTER_KEYS (@obj1,@arr1); JSON_OBJECT_FILTER_KEYS (@obj1,@arr1) NULL -# End of 11.2 Test +SET character_set_database=default; +SET CHARACTER SET default; +# +# MDEV-33149: JSON_ARRAY_INTERSECT function crashes the server when +# called with empty json arrays, UBSAN runtime error: member access +# within null pointer of type 'struct String' in +# Item_func_json_array_intersect::prepare_json_and_create_hash +# +SELECT json_array_intersect(@a,@b); +json_array_intersect(@a,@b) +NULL +# +# MDEV-36809: json_array_intersect crashs when unused table ref provided +# +select json_array_intersect('[["1", "7"], ["2", "6"], ["4", "5"], ["3", "8"]]', '[["2","6"],["3","8"],["4","5"],["1","7"]]') as result from (values (1),(2),(3),(4),(5)) x; +result +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +SELECT ( WITH x AS ( WITH x ( x ) AS ( SELECT ( 1.000000 ) ) SELECT x FROM x ) SELECT * FROM x WHERE ( SELECT AVG ( x ) OVER ( ORDER BY JSON_ARRAY_INTERSECT ( '[["1", "7"], ["2", "6"], ["3", "8"]]' , '[["2","6"],["3","8"],["4","5"],["1","7"]]' ) ) FROM x ) ) as result; +result +1.000000 +# +# MDEV-37864: mysql-test/mtr --cursor main.func_json fails +# +select json_array_intersect('[["1", "7"], ["2", "6"], ["4", "5"], ["3", "8"]]', '[["2","6"],["3","8"],["4","5"],["1","7"]]') as result from (values (1),(2),(3),(4),(5)) x; +result +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +[["2", "6"], ["3", "8"], ["4", "5"], ["1", "7"]] +# +# MDEV-33640: Server crashes at my_hash_free +# +SELECT JSON_SCHEMA_VALID('{"properties": "a_string": {"pattern": "^[5-9]$"}}}', '{"a_string": "8"}'); +ERROR HY000: Invalid value for keyword properties +# +# MDEV-38356 JSON_SCHEMA_VALID() crashes with a long enum +# +select json_schema_valid('{"enum":[0]}', sformat('"{:#>200}"','0')); +json_schema_valid('{"enum":[0]}', sformat('"{:#>200}"','0')) +0 +# End of 11.4 Test +# Beginning of 12.3 Test +# +# MDEV-37072: Implement IS JSON predicate +# +set names utf8mb4; +SELECT '[1, 2]' IS JSON; +'[1, 2]' IS JSON +1 +SELECT '{"key1":1, "key2":[2,3]}' IS JSON; +'{"key1":1, "key2":[2,3]}' IS JSON +1 +SELECT '123' IS JSON; +'123' IS JSON +1 +SELECT 'null' IS JSON; +'null' IS JSON +1 +SELECT 'invalid' IS JSON; +'invalid' IS JSON +0 +SELECT '{"key1":1, "key2":[2,3]' IS JSON; +'{"key1":1, "key2":[2,3]' IS JSON +0 +SELECT '[1, 2' IS JSON; +'[1, 2' IS JSON +0 +SELECT 'NULL' IS JSON; +'NULL' IS JSON +0 +SELECT 'invalid' IS NOT JSON; +'invalid' IS NOT JSON +1 +SELECT '{"key1":1, "key2":[2,3]' IS NOT JSON; +'{"key1":1, "key2":[2,3]' IS NOT JSON +1 +SELECT '[1, 2]' IS NOT JSON; +'[1, 2]' IS NOT JSON +0 +SELECT '{"key1":1, "key2":[2,3]}' IS NOT JSON; +'{"key1":1, "key2":[2,3]}' IS NOT JSON +0 +# Type constraints +SELECT js, +js IS JSON "json?", +js IS JSON VALUE "value?", +js IS JSON SCALAR "scalar?", +js IS JSON OBJECT "object?", +js IS JSON ARRAY "array?" +FROM (VALUES +('123'), ('"string"'), ('{"key":1}'), ('[1,2,3]'), ('[]'), ('{}'), +('true'), ('false'), ('null')) foo(js); +js json? value? scalar? object? array? +123 1 1 1 0 0 +"string" 1 1 1 0 0 +{"key":1} 1 1 0 1 0 +[1,2,3] 1 1 0 0 1 +[] 1 1 0 0 1 +{} 1 1 0 1 0 +true 1 1 1 0 0 +false 1 1 1 0 0 +null 1 1 1 0 0 +# UNIQUE KEYS constraint +SELECT '"a",1,1,2]' IS JSON WITH UNIQUE KEYS; +'"a",1,1,2]' IS JSON WITH UNIQUE KEYS +0 +SELECT '{"a": 42,"b": [{"c":1, "c":2}]}' IS JSON WITH UNIQUE KEYS; +'{"a": 42,"b": [{"c":1, "c":2}]}' IS JSON WITH UNIQUE KEYS +0 +SELECT '{"a": 42,"b": [{"a": {"a": [{"a" : "a", "a" : "a" }]} }]}' IS JSON WITH UNIQUE KEYS; +'{"a": 42,"b": [{"a": {"a": [{"a" : "a", "a" : "a" }]} }]}' IS JSON WITH UNIQUE KEYS +0 +SELECT '{"a": 42,"b": [{"a": {"a": [{"a" : "a"}]} }]}' IS JSON WITH UNIQUE KEYS; +'{"a": 42,"b": [{"a": {"a": [{"a" : "a"}]} }]}' IS JSON WITH UNIQUE KEYS +1 +SELECT '[{"a":1}, {"a":1}]' IS JSON WITH UNIQUE KEYS; +'[{"a":1}, {"a":1}]' IS JSON WITH UNIQUE KEYS +1 +SELECT '[{"a":1, "a":2}, {"b":1}]' IS JSON WITH UNIQUE KEYS; +'[{"a":1, "a":2}, {"b":1}]' IS JSON WITH UNIQUE KEYS +0 +SELECT '{"a": {"b":1, "b":2}}' IS JSON WITH UNIQUE KEYS; +'{"a": {"b":1, "b":2}}' IS JSON WITH UNIQUE KEYS +0 +SELECT '[{"a":1}, [{"b":1, "b":2}]]' IS JSON WITH UNIQUE KEYS; +'[{"a":1}, [{"b":1, "b":2}]]' IS JSON WITH UNIQUE KEYS +0 +SELECT '{"a": [{"b": {"c":1, "c":2}}]}' IS JSON WITH UNIQUE KEYS; +'{"a": [{"b": {"c":1, "c":2}}]}' IS JSON WITH UNIQUE KEYS +0 +SELECT '[{}]' IS JSON WITH UNIQUE KEYS; +'[{}]' IS JSON WITH UNIQUE KEYS +1 +SELECT '[1, {"a":1}, 2, {"b":2}]' IS JSON WITH UNIQUE KEYS; +'[1, {"a":1}, 2, {"b":2}]' IS JSON WITH UNIQUE KEYS +1 +SELECT '[{"a":1}, 1, {"a":1, "a":2}, 2]' IS JSON WITH UNIQUE KEYS; +'[{"a":1}, 1, {"a":1, "a":2}, 2]' IS JSON WITH UNIQUE KEYS +0 +SELECT '[{"a":1}, [{"b":1}], {"c":1}]' IS JSON WITH UNIQUE KEYS; +'[{"a":1}, [{"b":1}], {"c":1}]' IS JSON WITH UNIQUE KEYS +1 +SELECT '[{"a":1}, [{"b":1, "b":2}], {"c":1}]' IS JSON WITH UNIQUE KEYS; +'[{"a":1}, [{"b":1, "b":2}], {"c":1}]' IS JSON WITH UNIQUE KEYS +0 +SELECT '[[[[{"a":1, "a":2}]]]]' IS JSON WITH UNIQUE KEYS; +'[[[[{"a":1, "a":2}]]]]' IS JSON WITH UNIQUE KEYS +0 +SELECT '[[[{"a":1}]], [[{"b":1}]]]' IS JSON WITH UNIQUE KEYS; +'[[[{"a":1}]], [[{"b":1}]]]' IS JSON WITH UNIQUE KEYS +1 +SELECT '[[[{"a":1, "a":2}]], [[{"b":1}]]]' IS JSON WITH UNIQUE KEYS; +'[[[{"a":1, "a":2}]], [[{"b":1}]]]' IS JSON WITH UNIQUE KEYS +0 +SELECT '[{"a":[{"b":1, "b":2}]}, {"c":[{"d":1}]}]' IS JSON WITH UNIQUE KEYS; +'[{"a":[{"b":1, "b":2}]}, {"c":[{"d":1}]}]' IS JSON WITH UNIQUE KEYS +0 +SELECT '{"a":{"b":1, "c":2}, "d":{"b":1, "c":2}}' IS JSON WITH UNIQUE KEYS; +'{"a":{"b":1, "c":2}, "d":{"b":1, "c":2}}' IS JSON WITH UNIQUE KEYS +1 +SELECT '[{"a":[{"b":[{"c":1}]}]}, {"d":[{"e":[{"f":1, "f":2}]}]}]' IS JSON WITH UNIQUE KEYS; +'[{"a":[{"b":[{"c":1}]}]}, {"d":[{"e":[{"f":1, "f":2}]}]}]' IS JSON WITH UNIQUE KEYS +0 +SELECT '[{}, {"a":{}}, [{}]]' IS JSON WITH UNIQUE KEYS; +'[{}, {"a":{}}, [{}]]' IS JSON WITH UNIQUE KEYS +1 +SELECT '{"a":{"b":{"b":1}}, "d":{"e":{"f":1}}}' IS JSON WITH UNIQUE KEYS; +'{"a":{"b":{"b":1}}, "d":{"e":{"f":1}}}' IS JSON WITH UNIQUE KEYS +1 +SELECT js, +js IS JSON OBJECT WITH UNIQUE KEYS "object_with_unique", +js IS JSON OBJECT WITHOUT UNIQUE KEYS "object_without_unique", +js IS JSON ARRAY WITH UNIQUE KEYS "array_with_unique", +js IS JSON ARRAY WITHOUT UNIQUE KEYS "array_without_unique" +FROM (VALUES +('{"a":1, "b":2, "c":3}'), +('{"a":1, "a":2, "a":3}'), +('[{"a":"1"},{"c":"2","c":"3"}]'), +('[{"a":"1"},{"b":"2","c":"3"}]'), +('[1,2,3]'), ('[1,1,1]'), ('[]'), ('123'), +('"string"'), ('true'), ('null')) foo(js); +js object_with_unique object_without_unique array_with_unique array_without_unique +{"a":1, "b":2, "c":3} 1 1 0 0 +{"a":1, "a":2, "a":3} 0 1 0 0 +[{"a":"1"},{"c":"2","c":"3"}] 0 0 0 1 +[{"a":"1"},{"b":"2","c":"3"}] 0 0 1 1 +[1,2,3] 0 0 1 1 +[1,1,1] 0 0 1 1 +[] 0 0 1 1 +123 0 0 0 0 +"string" 0 0 0 0 +true 0 0 0 0 +null 0 0 0 0 +# Test with table data +CREATE TABLE test_json ( +json_col JSON, +text_col TEXT +); +INSERT INTO test_json VALUES +('{"name":"Alice", "age":25}', '{"name":"Alice", "age":25}'), +('[1,2,3]', '[1,2,3]'), +('42', '42'), +('"hello"', '"hello"'), +('true', 'true'), +('null', 'null'), +('"invalid"', 'invalid'), +('{"key1":1, "key2":2}', '{"key1":1, "key2":2}'), +('{"key1":1, "key1":2}', '{"key1":1, "key1":2}'); +SELECT +json_col, +json_col IS JSON as is_json, +json_col IS JSON VALUE as is_value, +json_col IS JSON SCALAR as is_scalar, +json_col IS JSON OBJECT as is_object, +json_col IS JSON ARRAY as is_array, +json_col IS JSON OBJECT WITH UNIQUE KEYS as object_with_unique, +json_col IS JSON OBJECT WITHOUT UNIQUE KEYS as object_without_unique +FROM test_json; +json_col is_json is_value is_scalar is_object is_array object_with_unique object_without_unique +{"name":"Alice", "age":25} 1 1 0 1 0 1 1 +[1,2,3] 1 1 0 0 1 0 0 +42 1 1 1 0 0 0 0 +"hello" 1 1 1 0 0 0 0 +true 1 1 1 0 0 0 0 +null 1 1 1 0 0 0 0 +"invalid" 1 1 1 0 0 0 0 +{"key1":1, "key2":2} 1 1 0 1 0 1 1 +{"key1":1, "key1":2} 1 1 0 1 0 0 1 +SELECT +text_col, +text_col IS JSON as is_json, +text_col IS JSON VALUE as is_value, +text_col IS JSON SCALAR as is_scalar, +text_col IS JSON OBJECT as is_object, +text_col IS JSON ARRAY as is_array +FROM test_json; +text_col is_json is_value is_scalar is_object is_array +{"name":"Alice", "age":25} 1 1 0 1 0 +[1,2,3] 1 1 0 0 1 +42 1 1 1 0 0 +"hello" 1 1 1 0 0 +true 1 1 1 0 0 +null 1 1 1 0 0 +invalid 0 0 0 0 0 +{"key1":1, "key2":2} 1 1 0 1 0 +{"key1":1, "key1":2} 1 1 0 1 0 +SELECT +COUNT(*) as total_rows, +SUM(json_col IS JSON) as valid_json_count, +SUM(json_col IS JSON OBJECT) as object_count, +SUM(json_col IS JSON ARRAY) as array_count, +SUM(json_col IS JSON SCALAR) as scalar_count +FROM test_json; +total_rows valid_json_count object_count array_count scalar_count +9 9 3 1 5 +# Edge cases +SELECT js, +js IS JSON "json?", +js IS JSON VALUE "value?", +js IS JSON SCALAR "scalar?", +js IS JSON OBJECT "object?", +js IS JSON ARRAY "array?" +FROM (VALUES +(NULL), (''), (' '), ('\n'), ('\t'), +('{"key":1,}'), ('{"key":1, "key2":}'), ('{key:1}'), +('{"emoji":"😊"}'), ('{"unicode":"\\u0041"}'), +(x'48656C6C6F'), ('2'), (CONCAT('{"a":', 1, '}')), +(JSON_OBJECT('a', 1, 'b', 2)), (JSON_ARRAY(1, 2, 3)), (JSON_QUOTE('hello'))) foo(js); +js json? value? scalar? object? array? +NULL NULL NULL NULL NULL NULL + 0 0 0 0 0 + 0 0 0 0 0 + + 0 0 0 0 0 + 0 0 0 0 0 +{"key":1,} 0 0 0 0 0 +{"key":1, "key2":} 0 0 0 0 0 +{key:1} 0 0 0 0 0 +{"emoji":"😊"} 1 1 0 1 0 +{"unicode":"\u0041"} 1 1 0 1 0 +Hello 0 0 0 0 0 +2 1 1 1 0 0 +{"a":1} 1 1 0 1 0 +{"a": 1, "b": 2} 1 1 0 1 0 +[1, 2, 3] 1 1 0 0 1 +"hello" 1 1 1 0 0 +# Large json object with unique keys +CREATE PROCEDURE build_large_json() +BEGIN +SET @json='{"key1":1'; +SET @i=2; +WHILE @i <= 1000 DO +SET @json = CONCAT(@json, ',"key', @i, '":', @i); +SET @i = @i + 1; +END WHILE; +SET @json = CONCAT(@json, '}'); +END| +CALL build_large_json()| +SELECT @json IS JSON OBJECT WITH UNIQUE KEYS AS unique_keys| +unique_keys +1 +DROP PROCEDURE build_large_json| +DROP TABLE test_json; +# Generated columns +CREATE TABLE test_generated_json ( +j TEXT, +is_json BOOL GENERATED ALWAYS AS (j IS JSON) VIRTUAL, +is_not_json BOOL GENERATED ALWAYS AS (j IS NOT JSON) VIRTUAL, +is_array BOOL GENERATED ALWAYS AS (j IS JSON ARRAY) VIRTUAL, +is_object BOOL GENERATED ALWAYS AS (j IS JSON OBJECT) VIRTUAL, +is_scalar BOOL GENERATED ALWAYS AS (j IS JSON SCALAR) VIRTUAL, +with_unique_keys BOOL GENERATED ALWAYS AS (j IS JSON OBJECT WITH UNIQUE KEYS) VIRTUAL, +without_unique_keys BOOL GENERATED ALWAYS AS (j IS JSON OBJECT WITHOUT UNIQUE KEYS) VIRTUAL +); +INSERT INTO test_generated_json (j) VALUES +('[1, 2, 3]'), +('{"key": "value"}'), +('3'), +(NULL), +('{}'), +('invalid'), +('{"key": "value", "key2": "value2"}'), +('{"key": "value", "key": "value2"}'); +SELECT +j, +is_json, +is_not_json, +is_array, +is_object, +is_scalar, +with_unique_keys, +without_unique_keys +FROM test_generated_json; +j is_json is_not_json is_array is_object is_scalar with_unique_keys without_unique_keys +[1, 2, 3] 1 0 1 0 0 0 0 +{"key": "value"} 1 0 0 1 0 1 1 +3 1 0 0 0 1 0 0 +NULL NULL NULL NULL NULL NULL NULL NULL +{} 1 0 0 1 0 1 1 +invalid 0 1 0 0 0 0 0 +{"key": "value", "key2": "value2"} 1 0 0 1 0 1 1 +{"key": "value", "key": "value2"} 1 0 0 1 0 0 1 +DROP TABLE test_generated_json; +# CHECK constraints +CREATE TABLE test_check_json ( +j TEXT CHECK (j IS JSON), +j_array JSON CHECK (j_array IS JSON ARRAY), +j_object JSON CHECK (j_object IS JSON OBJECT), +j_object_with_unique_keys JSON CHECK (j_object_with_unique_keys IS JSON OBJECT WITH UNIQUE KEYS) +); +INSERT INTO test_check_json VALUES +('[1, 2, 3]', '[1, 2]', '{"key": "value"}', '{"key": "value"}'), +('{"key": "value"}', '[1, 2]', '{"key": "value"}', '{"key": "value", "key2": "value2"}'); +INSERT INTO test_check_json VALUES ('[1, 2, 3]', '{1, 2}', '{"key": "value"}', 'invalid'); +ERROR 23000: CONSTRAINT `test_check_json.j_array` failed for `test`.`test_check_json` +INSERT INTO test_check_json VALUES ('[1, 2, 3]', '[1, 2]', '{"key": "value"}', '{"key": "value", "key": "value2"}'); +ERROR 23000: CONSTRAINT `test_check_json.j_object_with_unique_keys` failed for `test`.`test_check_json` +DROP TABLE test_check_json; +# DEFAULT clauses +CREATE TABLE test_default_json ( +j TEXT, +is_json BOOL DEFAULT (j IS JSON), +is_not_json BOOL DEFAULT (j IS NOT JSON), +is_array BOOL DEFAULT (j IS JSON ARRAY), +is_object BOOL DEFAULT (j IS JSON OBJECT), +is_scalar BOOL DEFAULT (j IS JSON SCALAR), +with_unique_keys BOOL DEFAULT (j IS JSON OBJECT WITH UNIQUE KEYS), +without_unique_keys BOOL DEFAULT (j IS JSON OBJECT WITHOUT UNIQUE KEYS) +); +INSERT INTO test_default_json (j) VALUES +('[1, 2, 3]'), +('{"key": "value"}'), +('3'), +(NULL), +('{}'), +('{"key": "value", "key2": "value2"}'), +('{"key": "value", "key": "value2"}'); +SELECT +j, +is_json, +is_not_json, +is_array, +is_object, +is_scalar, +with_unique_keys, +without_unique_keys +FROM test_default_json; +j is_json is_not_json is_array is_object is_scalar with_unique_keys without_unique_keys +[1, 2, 3] 1 0 1 0 0 0 0 +{"key": "value"} 1 0 0 1 0 1 1 +3 1 0 0 0 1 0 0 +NULL NULL NULL NULL NULL NULL NULL NULL +{} 1 0 0 1 0 1 1 +{"key": "value", "key2": "value2"} 1 0 0 1 0 1 1 +{"key": "value", "key": "value2"} 1 0 0 1 0 0 1 +DROP TABLE test_default_json; +# End of 12.3 diff --git a/mysql-test/main/func_json.test b/mysql-test/main/func_json.test index 453ede9e26b25..13be0f591e5ce 100644 --- a/mysql-test/main/func_json.test +++ b/mysql-test/main/func_json.test @@ -78,7 +78,7 @@ select json_contains_path('{"key1":1, "key2":[2,3]}', "aLl", "$.key1", "$.key2") select json_contains_path('{ "a": true }', NULL, '$.a' ) as exp; select json_contains_path('{ "a": true }', 'all', NULL ) as exp; select json_contains_path('{"a":{"b":"c"}}', 'one', '$.a.*') as exp; - + select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1") as exp; select json_extract('{"key1":"asd", "key2":[2,3]}', "$.keyX", "$.keyY") as exp; select json_extract('{"key1":"asd", "key2":[2,3]}', "$.key1", "$.key2") as exp; @@ -208,7 +208,6 @@ drop table t2; --enable_cursor_protocol drop table t1; - select json_object("a", json_object("b", "abcd")); #enable after fix MDEV-31554 --disable_cursor_protocol @@ -310,7 +309,7 @@ set @save_max_allowed_packet=@@max_allowed_packet; set @save_net_buffer_length=@@net_buffer_length; set @@global.net_buffer_length=1024; -set @@global.max_allowed_packet=2048; +set @@global.max_allowed_packet=4096; --connect (newconn, localhost, root,,) show variables like 'net_buffer_length'; @@ -323,7 +322,6 @@ set @@global.max_allowed_packet = @save_max_allowed_packet; set @@global.net_buffer_length = @save_net_buffer_length; --disconnect newconn - # # MDEV-12262 Assertion `!null_value' failed in virtual bool Item::send on JSON_REMOVE. # @@ -597,7 +595,6 @@ SELECT CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DOUBLE) AS cf, CAST(JSON_EXTRACT('{"x":false}', '$.x') AS DECIMAL) AS cd; - --echo # --echo # MDEV-24585 Assertion `je->s.cs == nice_js->charset()' failed in json_nice. --echo # @@ -689,14 +686,9 @@ SELECT JSON_VALUE('{"nulltest": null}', '$.nulltest'); SELECT 1 + NULL; SELECT 1 + JSON_VALUE('{"nulltest": null}', '$.nulltest'); - SELECT NULL; SELECT JSON_EXTRACT('{"a":null, "b":10, "c":"null"}', '$.a'); ---echo # ---echo # Start of 10.4 tests ---echo # - --echo # --echo # MDEV-16351 JSON_OBJECT() treats hybrid functions with boolean arguments as numbers --echo # @@ -739,7 +731,6 @@ SELECT * FROM t1 WHERE CASE WHEN JSON_OBJECT('x', (SELECT MAX(a=3) FROM t1))='{" SELECT * FROM t1 WHERE CASE WHEN JSON_OBJECT('x', (SELECT MAX(a=2) FROM t1))='{"x": true}' THEN a END; SELECT * FROM t1 WHERE CASE WHEN JSON_OBJECT('x', (SELECT MAX(a=2) FROM t1))='{"x": false}' THEN a END; - DROP TABLE t1; -- echo # @@ -941,7 +932,6 @@ insert into t200 values ] }'); - select JSON_DETAILED(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; select JSON_PRETTY(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; select JSON_LOOSE(JSON_EXTRACT(a, '$**.analyzing_range_alternatives')) as exp from t200; @@ -957,7 +947,6 @@ SELECT JSON_LENGTH(); --echo # MDEV-23187: Assorted assertion failures in json_find_path with certain collations - SET @old_collation_connection= @@COLLATION_CONNECTION; SET COLLATION_CONNECTION= ucs2_unicode_ci; @@ -1107,10 +1096,10 @@ DROP TABLE t1; CREATE TABLE t1(id int primary key, name varchar(50)); CREATE TABLE t2(id int, owner_id int); - + INSERT INTO t1 VALUES (1, "name1"), (2, "name2"), (3, "name3"); INSERT INTO t2 VALUES (1, 1), (2, 1), (3, 2), (4, 3); - + SELECT t1.id, JSON_ARRAYAGG(JSON_OBJECT('id',t2.id) ORDER BY t2.id) as materials from t1 LEFT JOIN t2 on t1.id = t2.owner_id GROUP BY t1.id ORDER BY id; @@ -1133,7 +1122,7 @@ CREATE TABLE arrNestTest ( id VARCHAR(80) AS (JSON_COMPACT(JSON_EXTRACT(doc, "$._id"))) UNIQUE KEY, doc JSON, CONSTRAINT id_not_null CHECK(id IS NOT NULL)); - + INSERT INTO test.arrNestTest (doc) VALUES ('{ "_id" : { "$oid" : "611c0a463b150154132f6636" }, "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : [ { "a" : 1.0 } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] } ] }'); SELECT * FROM arrNestTest; DROP TABLE arrNestTest; @@ -1156,14 +1145,12 @@ set names latin1; select json_arrayagg('ä'), json_objectagg(1, 'ä'); --enable_service_connection - --echo # --echo # MDEV-32287: JSON_EXTRACT not returning multiple values for same path --echo # select JSON_EXTRACT("[1, 2, [30, 40]]", '$[2][1]', '$[2][1]'); - --echo # --echo # MDEV-31402: SIGSEGV in json_get_path_next | Item_func_json_extract::read_json --echo # @@ -1180,7 +1167,6 @@ DROP TABLE t; SELECT JSON_TYPE(json_value(JSON_OBJECT("id", 1, "name", 'Monty', "date", Cast('2019-01-01' as Date) ), '$.date')) as x; - --echo # --echo # MDEV-22141: JSON_REMOVE returns NULL on valid arguments --echo # @@ -1188,7 +1174,6 @@ SELECT JSON_TYPE(json_value(JSON_OBJECT("id", 1, "name", 'Monty', "date", Cast(' SELECT JSON_REMOVE('{"A": { "B": 1 }}', '$.A.B.C.D'); - --echo # --echo # MDEV-34143: Server crashes when executing JSON_EXTRACT after setting non-default collation_connection --echo # @@ -1202,7 +1187,6 @@ SELECT JSON_EXTRACT('{"a": 1,"b": 2}','$.a'); SET @@collation_connection= @save_collation_connection; - --echo # End of 10.5 tests --echo # @@ -1226,19 +1210,16 @@ SELECT JSON_ARRAY_APPEND(JSON_ARRAY(l1, l2, l3, l4), '$[0]', 'k3'), JSON_ARRAY_I SELECT JSON_INSERT(JSON_OBJECT(l1, l2, l3, l4), '$.k3', 'v3'),JSON_SET(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2'),JSON_REPLACE(JSON_OBJECT(l1, l2, l3, l4), '$.k2', 'new v2') from t; DROP TABLE t; - --echo # --echo # MDEV-27412: JSON_TABLE doesn't properly unquote strings --echo # - SET @data = '[{"Data": ""}]'; SELECT data FROM JSON_TABLE (@data, '$[*]' COLUMNS (data text PATH '$.Data')) AS t; - --echo # --echo # MDEV-21530: json_extract STILL crashes in Item_func_json_extract::read_json --echo # @@ -1282,7 +1263,6 @@ DROP TABLE t1; --echo # MDEV-27677: Implement JSON_OVERLAPS() --echo # - --echo # Testing scalar json datatypes --echo # Comparing scalar json datatypes with itself @@ -1303,7 +1283,6 @@ SELECT JSON_OVERLAPS('true','["abc", 1, 2, true, false]'); SELECT JSON_OVERLAPS('true','["abc", 1, 2, [true]]'); SELECT JSON_OVERLAPS('true','{"A":true}'); - --echo # Testing non-scalar json data types --echo # Comparing object with object (non-nested) @@ -1368,7 +1347,6 @@ SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', SELECT JSON_OVERLAPS('{"A":1, "B":{"D":4, "E":[5, 6, 7]}}', '{"C":3, "F":{"E":[5, 6, 7], "D":4}}') as exp; - --echo # Comparing array with array (non-nested) SELECT JSON_OVERLAPS('[1, 2, true, false, null]', '[3, 4, 1]') as exp; @@ -1383,7 +1361,6 @@ SELECT JSON_OVERLAPS('[1, 2, [true, false], null]', '[[1], [true, false]]') as exp; SELECT JSON_OVERLAPS('[1, 2, 3, [4, 5, 6]]','[7, 8, 9, [6, 5, 4]]') as exp; - --echo # Comparing one non-scalar json datatypes with another non-scalar --echo # json datatype @@ -1675,7 +1652,6 @@ SELECT JSON_VALUE(@json,'$.x[last-0]'); SELECT JSON_VALUE(@json,'$.x[-0]'); SELECT JSON_VALUE(@json,'$.x[0]'); - --echo # --echo # MDEV-27911: Implement range notation for json path --echo # @@ -1847,7 +1823,6 @@ SET @json1= '[ ]'; SELECT JSON_VALUE(@json1, '$[2][1 to 2].key1'); - SET @json= '[ [1.1, {"key1": "value1"}, 3], [false, 5, 6], @@ -1886,7 +1861,6 @@ SELECT JSON_EXISTS(@json, '$[2][2][1 to 2]'); SELECT JSON_EXISTS(@json, '$[2][2][4 to 6]'); SELECT JSON_EXISTS(@json, '$[2][2][1 to 4]'); - --echo # --echo # MDEV-28326: Server crashes in json_path_parts_compare --echo # @@ -1907,7 +1881,7 @@ SELECT JSON_OVERLAPS(@json1, @json2); --echo # CREATE TABLE t1 ( j JSON ); - + INSERT INTO t1 (j) VALUES ('[{"key1": 1, "key2": 1}, {"key3": 1, "key4": 1}]'); INSERT INTO t1 (j) VALUES ('[{"key1": 2, "key2": 2}, {"key3": 2, "key4": 2}, {"key5": 2, "key6": 2}]'); INSERT INTO t1 (j) VALUES ('[{"key1": 3, "key2": 3}, {"key3": 3, "key4": 3}, {"key5": 3}]'); @@ -1928,7 +1902,6 @@ SELECT JSON_EXTRACT('{ "my-key": 1 }', '$.my-key'); --echo # MDEV-23187: Assorted assertion failures in json_find_path with certain collations --echo # - SET @save_collation_connection= @@collation_connection; SET @json='{ "A": [ [{"k":"v"},[1]],true],"B": {"C": 1} }'; @@ -1942,16 +1915,109 @@ SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }'; SET sql_mode=0,character_set_connection=utf32; SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1'); - SET @json='{ "A": [ [{"k":"v"},[15]],true],"B": {"C": 1} }'; SET sql_mode=0,character_set_connection=utf32; SELECT JSON_VALUE(@json,'$.A[last-1][last-1].key1'); SET @@collation_connection= @save_collation_connection; - --echo # End of 10.9 Test +--echo # +--echo # MDEV-30691 Assertion `strlen(Ptr) == str_length' failed in void Binary_string::chop() +--echo # +set @@collation_connection=utf32_czech_ci; +select json_detailed('[[123],456]'); +set @@collation_connection=@save_collation_connection; +select json_detailed('[[123],456]'); + +--echo # +--echo # MDEV-37428 JSON_VALUE returns NULL for a key with an empty string value rather than an empty string +--echo # + +SELECT JSON_VALUE(JSON_OBJECT("a", ""), '$.a') = "" AS not_null; + +--echo # +--echo # MDEV-36319: Wrong result json_table +--echo # + +SET @JSON=' +{ + "SZ": [ + { + "NAME": "S0", + "OFFERS": [ + { + "NAME": "S0A0" + } + ] + }, + { + "NAME": "S1", + "OFFERS": [ + { + "NAME": "S1A0" + }, + { + "NAME": "S1A1" + } + ] + }, + { + "NAME": "S2", + "OFFERS": [ + { + "NAME": "S2A0" + } + ] + }, + { + "NAME": "S3", + "OFFERS": [ + { + "NAME": "S3A0" + } + ] + }, + { + "NAME": "S4", + "OFFERS": [ + { + "NAME": "S4A0" + } + ] + }, + { + "NAME": "S5", + "OFFERS": [ + { + "NAME": "S5A0" + } + ] + } + ] +} + +' +; + +--echo # Should return EMPTY result +SELECT * FROM json_table(@JSON, '$.SZ[0].OFFERS[1]' +COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; + +--echo # Should return S1A1 +SELECT * FROM json_table(@JSON, '$.SZ[1].OFFERS[1]' +COLUMNS(NAME VARCHAR(30) PATH '$.NAME')) AS t_sz; + +--echo # +--echo # MDEV-25148: Unexpected success and result set upon erroneous +--echo # JSON_VALUE call +--echo # + +SELECT JSON_VALUE('{"a":[1,2]}', '$.a[*]'); + +--echo # End of 10.11 Test + --echo # --echo # MDEV-32007: JSON_VALUE and JSON_EXTRACT doesn't handle dash (-) --echo # as first character in key @@ -2222,7 +2288,6 @@ SELECT JSON_SCHEMA_VALID(@string_schema, '"abc"'); SET @schema_array= '{"type":"array"}'; SELECT JSON_SCHEMA_VALID(@schema_array, '[1, 2, {"key1":"val1"}]'); - SET @schema_array= '{"type":"array", "maxItems": 4, "minItems": 2}'; @@ -2693,7 +2758,6 @@ INSERT INTO str_table VALUES('"abcdef"'); INSERT INTO str_table VALUES('"fedcba"'); SELECT * FROM str_table; - INSERT INTO num_table values('15'); --error ER_CONSTRAINT_FAILED INSERT INTO num_table values('25'); @@ -2869,7 +2933,6 @@ SET @schema_array= '{ SELECT JSON_SCHEMA_VALID(@schema_array, '[5, "string1", "string2", "string3"]'); SELECT JSON_SCHEMA_VALID(@schema_array, '[5, "string1", 1, 2]'); - SET @schema_array= '{ "type": "array", "prefixItems": [ @@ -2901,10 +2964,8 @@ SET @schema_array= '{ }'; SELECT JSON_SCHEMA_VALID(@schema_array, '[5, "string1", "string2", "string3"]'); - --echo # Removing prefixItems - SET @schema_array= '{ "type": "array", "items": { "type": "number", "maximum": 10, "minimum":3}, @@ -2913,7 +2974,6 @@ SET @schema_array= '{ }'; SELECT JSON_SCHEMA_VALID(@schema_array, '[5, 6,"2", "string"]'); - SET @schema_array= '{ "type": "array", "items": { "type": "number", "maximum": 10, "minimum":3}, @@ -2989,7 +3049,6 @@ SET @schema_array= '{ }'; SELECT JSON_SCHEMA_VALID(@schema_array, '["str1", "str2", 1]'); - --echo # checking that unevaluatedItems alone can have effect on schema validation SET @schema_array= '{ @@ -3012,7 +3071,6 @@ SELECT JSON_SCHEMA_VALID(@schema_array, '[1, "str1"]'); SELECT JSON_SCHEMA_VALID(@schema_array, '[]'); SELECT JSON_SCHEMA_VALID(@schema_array, '[1,2,3]'); - --echo # Object validation SET @property_names= '{ @@ -3053,7 +3111,6 @@ SELECT JSON_SCHEMA_VALID(@object_schema, '{"key1":"val1", "key2": 10, "I_int":20 --echo # existence of unevaluatedProperties still does not change anything because of existence of additional --echo # properties - SET @object_schema= '{ "type":"object", "properties": { @@ -3134,7 +3191,6 @@ SET @object_schema= '{ }'; SELECT JSON_SCHEMA_VALID(@object_schema, '{"key1":"val1", "key2": 10, "I_int":20, "S_":"abc", "some_prop1":[1,2,3]}'); - --echo # Checking that in absence of additionalProperties, validation falls back on evaluatedProperties SET @object_schema= '{ @@ -3573,8 +3629,6 @@ SET @schema_reference= '{"$defs": "http://example.com/custom-email-validator.jso --error ER_JSON_SCHEMA_KEYWORD_UNSUPPORTED SELECT JSON_SCHEMA_VALID(@schema_reference, '{}'); - - --echo # --echo # MDEV-30795: JSON_SCHEMA_VALID bugs mentioned in comment --echo # @@ -3710,7 +3764,6 @@ SET @schema = '{ --error ER_JSON_INVALID_VALUE_FOR_KEYWORD SELECT JSON_SCHEMA_VALID(@schema, '2'); - --echo # --echo # MDEV-30704: JSON_SCHEMA_VALID: multipleOf must be greater than zero --echo # @@ -3749,7 +3802,6 @@ SET @schema= '{ "items" : ["str1"]}'; --error ER_JSON_INVALID_VALUE_FOR_KEYWORD SELECT JSON_SCHEMA_VALID(@schema, '[]'); - --echo # --echo # MDEV-30705: JSON_SCHEMA_VALID: schema with multipleOf for big value always return 1 --echo # @@ -3795,15 +3847,14 @@ SELECT JSON_SCHEMA_VALID(@schema, '-#'); --echo # MDEV-30689: JSON_SCHEMA_VALID for type=array return 1 for any string that starts with '[' --echo # - SET @schema_array= '{"type":"array"}'; SELECT JSON_SCHEMA_VALID(@schema_array, '['); --disable_view_protocol -SELECT JSON_SCHEMA_VALID(repeat('[', 100000), json_object()); +SELECT JSON_SCHEMA_VALID(repeat('[', 100), json_object()); --enable_view_protocol -SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 10000000)); +SELECT JSON_SCHEMA_VALID(json_object(), repeat('[', 100)); --echo # --echo # MDEV-30677: Incorrect result for "SELECT JSON_SCHEMA_VALID('{}', NULL)" @@ -3828,7 +3879,6 @@ PREPARE s FROM 'SELECT JSON_SCHEMA_VALID (?,''{}'') FROM DUAL'; SET @a= NULL; SELECT JSON_SCHEMA_VALID(@a,'{}'); - --echo # End of 11.1 test --echo # @@ -3887,7 +3937,6 @@ FROM JSON_TABLE( SELECT JSON_KEY_VALUE('[]', '[0]'); - SELECT JSON_KEY_VALUE('[1, 2, 3]', '$[0]'); SELECT jt.* FROM JSON_TABLE( @@ -3980,6 +4029,8 @@ FROM JSON_TABLE( JSON_KEY_VALUE('{"key1":{"a":1, "b": [1,2,3, {"some_key":"some_val", "c":3}]}, "key2":"val2"}', '$.key1.b[0]'), '$[*]' COLUMNS (k VARCHAR(20) PATH '$.key', v VARCHAR(20) PATH '$.value', id FOR ORDINALITY)) AS jt; +--echo # End of 11.2 test + --echo # --echo # MDEV-26182: Implement json_array_intersect() --echo # @@ -4012,7 +4063,6 @@ SET @obj1= '[null, true]'; SET @obj2= '[false, null]'; select json_array_intersect(@obj1, @obj2); - --echo # array as elements SET @json1= '[6,6,6]'; @@ -4053,7 +4103,6 @@ SET @obj1= '[1, 2, 3, 3, 3.0, "abc", true, true, {"key1":"val1"}]'; SET @obj2= '[3.0, 3, 5, "abc", "abc", true, {"key2":"val2"}, {"key1":"val1"}, {"key1":"val2"}]'; select json_array_intersect(@obj1, @obj2); - --echo # Checking Syntax error for JSON_ARRAY_INTERSECT() SET @obj1= '[1, 2, 3, 3, 3.0, "abc", true, true, {"key1":"val1" ]'; SET @obj2= '[3.0, 3, 5, "abc", "abc", true, {"key2":"val2"}, {"key1":"val1"}, {"key1":"val2"}]'; @@ -4071,7 +4120,6 @@ select json_array_intersect(@arr1, @num1); select json_array_intersect(@num1, @bool1); - --echo # JSON_OBJECT_FILTER_KEYS() SET @obj1= '{ "a": 1, "b": 2, "c": 3}'; @@ -4082,12 +4130,10 @@ SET @obj1= '{ "a": 1, "b": {"key1": {"key2":"val2"}}, "c": [1, 2, 3] }'; SET @obj2= '{"b" : 10, "c": 20, "d": 30}'; SELECT JSON_OBJECT_FILTER_KEYS (@obj1, json_array_intersect(json_keys(@obj1), json_keys(@obj2))); - SET @obj1= '{ "a": 1, "b": {"key1": {"key2":"val2"}}, "c": [1, 2, 3] }'; SET @arr2='["x", "y", "z"]'; SELECT JSON_OBJECT_FILTER_KEYS(@obj1, @arr2); - SET @obj1= '{ "a": 1, "b": {"key1": {"key2":"val2"}}, "c": [1, 2, 3] }'; SET @arr2='["key2", "key1", "b"]'; SELECT JSON_OBJECT_FILTER_KEYS(@obj1, @arr1); @@ -4112,7 +4158,6 @@ SET @arr2= '[ "key2", "key1", "b" '; SELECT JSON_OBJECT_FILTER_KEYS(@obj1, @arr1); - --echo # JSON_OBJECT_TO_ARRAY() SET @obj1= '{ "a": [1, 2, 3], "b": { "key1":"val1", "key2": {"key3":"val3"} }, "c": 3, "d" : 1, "e": "xyz", "f": true, "g" : null}'; @@ -4131,7 +4176,6 @@ SELECT JSON_OBJECT_TO_ARRAY(@obj1); SET @arr1= '[1, 2, 3]'; SELECT JSON_OBJECT_TO_ARRAY(@arr1); - --echo # --echo # MDEV-31411: JSON_ARRAY_INTERSECT/JSON_OBJECT_FILTER_KEYS should fetch --echo # data from a table similar to other JSON functions @@ -4151,7 +4195,6 @@ SELECT JSON_ARRAY_INTERSECT(c1, c2) FROM t1; DROP TABLE t1; - --echo # --echo # MDEV-31543: ASAN heap-buffer-overflow in strncpy when fetching keys using JSON_OBJECT_FILTER_KEYS function --echo # @@ -4161,5 +4204,289 @@ SET character_set_database=ucs2; SET CHARACTER SET utf8; SET @obj1='{ "a": 1,"b": 2,"c": 3}'; SELECT JSON_OBJECT_FILTER_KEYS (@obj1,@arr1); +SET character_set_database=default; +SET CHARACTER SET default; + +--echo # +--echo # MDEV-33149: JSON_ARRAY_INTERSECT function crashes the server when +--echo # called with empty json arrays, UBSAN runtime error: member access +--echo # within null pointer of type 'struct String' in +--echo # Item_func_json_array_intersect::prepare_json_and_create_hash +--echo # + +SELECT json_array_intersect(@a,@b); + +--echo # +--echo # MDEV-36809: json_array_intersect crashs when unused table ref provided +--echo # +select json_array_intersect('[["1", "7"], ["2", "6"], ["4", "5"], ["3", "8"]]', '[["2","6"],["3","8"],["4","5"],["1","7"]]') as result from (values (1),(2),(3),(4),(5)) x; +SELECT ( WITH x AS ( WITH x ( x ) AS ( SELECT ( 1.000000 ) ) SELECT x FROM x ) SELECT * FROM x WHERE ( SELECT AVG ( x ) OVER ( ORDER BY JSON_ARRAY_INTERSECT ( '[["1", "7"], ["2", "6"], ["3", "8"]]' , '[["2","6"],["3","8"],["4","5"],["1","7"]]' ) ) FROM x ) ) as result; + +--echo # +--echo # MDEV-37864: mysql-test/mtr --cursor main.func_json fails +--echo # + +select json_array_intersect('[["1", "7"], ["2", "6"], ["4", "5"], ["3", "8"]]', '[["2","6"],["3","8"],["4","5"],["1","7"]]') as result from (values (1),(2),(3),(4),(5)) x; + +--echo # +--echo # MDEV-33640: Server crashes at my_hash_free +--echo # + +--error ER_JSON_INVALID_VALUE_FOR_KEYWORD +SELECT JSON_SCHEMA_VALID('{"properties": "a_string": {"pattern": "^[5-9]$"}}}', '{"a_string": "8"}'); + +--echo # +--echo # MDEV-38356 JSON_SCHEMA_VALID() crashes with a long enum +--echo # +select json_schema_valid('{"enum":[0]}', sformat('"{:#>200}"','0')); + +--echo # End of 11.4 Test + +--echo # Beginning of 12.3 Test + +--echo # +--echo # MDEV-37072: Implement IS JSON predicate +--echo # + +set names utf8mb4; + +--disable_view_protocol +SELECT '[1, 2]' IS JSON; +SELECT '{"key1":1, "key2":[2,3]}' IS JSON; +SELECT '123' IS JSON; +SELECT 'null' IS JSON; + +SELECT 'invalid' IS JSON; +SELECT '{"key1":1, "key2":[2,3]' IS JSON; +SELECT '[1, 2' IS JSON; +SELECT 'NULL' IS JSON; + +SELECT 'invalid' IS NOT JSON; +SELECT '{"key1":1, "key2":[2,3]' IS NOT JSON; +SELECT '[1, 2]' IS NOT JSON; +SELECT '{"key1":1, "key2":[2,3]}' IS NOT JSON; + +--echo # Type constraints + +SELECT js, + js IS JSON "json?", + js IS JSON VALUE "value?", + js IS JSON SCALAR "scalar?", + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?" +FROM (VALUES + ('123'), ('"string"'), ('{"key":1}'), ('[1,2,3]'), ('[]'), ('{}'), + ('true'), ('false'), ('null')) foo(js); + +--echo # UNIQUE KEYS constraint + +SELECT '"a",1,1,2]' IS JSON WITH UNIQUE KEYS; +SELECT '{"a": 42,"b": [{"c":1, "c":2}]}' IS JSON WITH UNIQUE KEYS; +SELECT '{"a": 42,"b": [{"a": {"a": [{"a" : "a", "a" : "a" }]} }]}' IS JSON WITH UNIQUE KEYS; +SELECT '{"a": 42,"b": [{"a": {"a": [{"a" : "a"}]} }]}' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":1}, {"a":1}]' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":1, "a":2}, {"b":1}]' IS JSON WITH UNIQUE KEYS; +SELECT '{"a": {"b":1, "b":2}}' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":1}, [{"b":1, "b":2}]]' IS JSON WITH UNIQUE KEYS; +SELECT '{"a": [{"b": {"c":1, "c":2}}]}' IS JSON WITH UNIQUE KEYS; +SELECT '[{}]' IS JSON WITH UNIQUE KEYS; +SELECT '[1, {"a":1}, 2, {"b":2}]' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":1}, 1, {"a":1, "a":2}, 2]' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":1}, [{"b":1}], {"c":1}]' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":1}, [{"b":1, "b":2}], {"c":1}]' IS JSON WITH UNIQUE KEYS; +SELECT '[[[[{"a":1, "a":2}]]]]' IS JSON WITH UNIQUE KEYS; +SELECT '[[[{"a":1}]], [[{"b":1}]]]' IS JSON WITH UNIQUE KEYS; +SELECT '[[[{"a":1, "a":2}]], [[{"b":1}]]]' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":[{"b":1, "b":2}]}, {"c":[{"d":1}]}]' IS JSON WITH UNIQUE KEYS; +SELECT '{"a":{"b":1, "c":2}, "d":{"b":1, "c":2}}' IS JSON WITH UNIQUE KEYS; +SELECT '[{"a":[{"b":[{"c":1}]}]}, {"d":[{"e":[{"f":1, "f":2}]}]}]' IS JSON WITH UNIQUE KEYS; +SELECT '[{}, {"a":{}}, [{}]]' IS JSON WITH UNIQUE KEYS; +SELECT '{"a":{"b":{"b":1}}, "d":{"e":{"f":1}}}' IS JSON WITH UNIQUE KEYS; + +SELECT js, + js IS JSON OBJECT WITH UNIQUE KEYS "object_with_unique", + js IS JSON OBJECT WITHOUT UNIQUE KEYS "object_without_unique", + js IS JSON ARRAY WITH UNIQUE KEYS "array_with_unique", + js IS JSON ARRAY WITHOUT UNIQUE KEYS "array_without_unique" +FROM (VALUES + ('{"a":1, "b":2, "c":3}'), + ('{"a":1, "a":2, "a":3}'), + ('[{"a":"1"},{"c":"2","c":"3"}]'), + ('[{"a":"1"},{"b":"2","c":"3"}]'), + ('[1,2,3]'), ('[1,1,1]'), ('[]'), ('123'), + ('"string"'), ('true'), ('null')) foo(js); + +--echo # Test with table data + +CREATE TABLE test_json ( + json_col JSON, + text_col TEXT +); + +INSERT INTO test_json VALUES +('{"name":"Alice", "age":25}', '{"name":"Alice", "age":25}'), +('[1,2,3]', '[1,2,3]'), +('42', '42'), +('"hello"', '"hello"'), +('true', 'true'), +('null', 'null'), +('"invalid"', 'invalid'), +('{"key1":1, "key2":2}', '{"key1":1, "key2":2}'), +('{"key1":1, "key1":2}', '{"key1":1, "key1":2}'); + +SELECT + json_col, + json_col IS JSON as is_json, + json_col IS JSON VALUE as is_value, + json_col IS JSON SCALAR as is_scalar, + json_col IS JSON OBJECT as is_object, + json_col IS JSON ARRAY as is_array, + json_col IS JSON OBJECT WITH UNIQUE KEYS as object_with_unique, + json_col IS JSON OBJECT WITHOUT UNIQUE KEYS as object_without_unique +FROM test_json; + +SELECT + text_col, + text_col IS JSON as is_json, + text_col IS JSON VALUE as is_value, + text_col IS JSON SCALAR as is_scalar, + text_col IS JSON OBJECT as is_object, + text_col IS JSON ARRAY as is_array +FROM test_json; + +SELECT + COUNT(*) as total_rows, + SUM(json_col IS JSON) as valid_json_count, + SUM(json_col IS JSON OBJECT) as object_count, + SUM(json_col IS JSON ARRAY) as array_count, + SUM(json_col IS JSON SCALAR) as scalar_count +FROM test_json; + +--echo # Edge cases + +SELECT js, + js IS JSON "json?", + js IS JSON VALUE "value?", + js IS JSON SCALAR "scalar?", + js IS JSON OBJECT "object?", + js IS JSON ARRAY "array?" +FROM (VALUES + (NULL), (''), (' '), ('\n'), ('\t'), + ('{"key":1,}'), ('{"key":1, "key2":}'), ('{key:1}'), + ('{"emoji":"😊"}'), ('{"unicode":"\\u0041"}'), + (x'48656C6C6F'), ('2'), (CONCAT('{"a":', 1, '}')), + (JSON_OBJECT('a', 1, 'b', 2)), (JSON_ARRAY(1, 2, 3)), (JSON_QUOTE('hello'))) foo(js); +--enable_view_protocol + +--echo # Large json object with unique keys + +DELIMITER |; +CREATE PROCEDURE build_large_json() +BEGIN + SET @json='{"key1":1'; + SET @i=2; + WHILE @i <= 1000 DO + SET @json = CONCAT(@json, ',"key', @i, '":', @i); + SET @i = @i + 1; + END WHILE; + SET @json = CONCAT(@json, '}'); +END| +CALL build_large_json()| +SELECT @json IS JSON OBJECT WITH UNIQUE KEYS AS unique_keys| +DROP PROCEDURE build_large_json| +DELIMITER ;| + +DROP TABLE test_json; + +--echo # Generated columns + +CREATE TABLE test_generated_json ( + j TEXT, + is_json BOOL GENERATED ALWAYS AS (j IS JSON) VIRTUAL, + is_not_json BOOL GENERATED ALWAYS AS (j IS NOT JSON) VIRTUAL, + is_array BOOL GENERATED ALWAYS AS (j IS JSON ARRAY) VIRTUAL, + is_object BOOL GENERATED ALWAYS AS (j IS JSON OBJECT) VIRTUAL, + is_scalar BOOL GENERATED ALWAYS AS (j IS JSON SCALAR) VIRTUAL, + with_unique_keys BOOL GENERATED ALWAYS AS (j IS JSON OBJECT WITH UNIQUE KEYS) VIRTUAL, + without_unique_keys BOOL GENERATED ALWAYS AS (j IS JSON OBJECT WITHOUT UNIQUE KEYS) VIRTUAL +); + +INSERT INTO test_generated_json (j) VALUES + ('[1, 2, 3]'), + ('{"key": "value"}'), + ('3'), + (NULL), + ('{}'), + ('invalid'), + ('{"key": "value", "key2": "value2"}'), + ('{"key": "value", "key": "value2"}'); + +SELECT + j, + is_json, + is_not_json, + is_array, + is_object, + is_scalar, + with_unique_keys, + without_unique_keys +FROM test_generated_json; + +DROP TABLE test_generated_json; + +--echo # CHECK constraints + +CREATE TABLE test_check_json ( + j TEXT CHECK (j IS JSON), + j_array JSON CHECK (j_array IS JSON ARRAY), + j_object JSON CHECK (j_object IS JSON OBJECT), + j_object_with_unique_keys JSON CHECK (j_object_with_unique_keys IS JSON OBJECT WITH UNIQUE KEYS) +); + +INSERT INTO test_check_json VALUES + ('[1, 2, 3]', '[1, 2]', '{"key": "value"}', '{"key": "value"}'), + ('{"key": "value"}', '[1, 2]', '{"key": "value"}', '{"key": "value", "key2": "value2"}'); + +--error ER_CONSTRAINT_FAILED +INSERT INTO test_check_json VALUES ('[1, 2, 3]', '{1, 2}', '{"key": "value"}', 'invalid'); +--error ER_CONSTRAINT_FAILED +INSERT INTO test_check_json VALUES ('[1, 2, 3]', '[1, 2]', '{"key": "value"}', '{"key": "value", "key": "value2"}'); + +DROP TABLE test_check_json; + +--echo # DEFAULT clauses + +CREATE TABLE test_default_json ( + j TEXT, + is_json BOOL DEFAULT (j IS JSON), + is_not_json BOOL DEFAULT (j IS NOT JSON), + is_array BOOL DEFAULT (j IS JSON ARRAY), + is_object BOOL DEFAULT (j IS JSON OBJECT), + is_scalar BOOL DEFAULT (j IS JSON SCALAR), + with_unique_keys BOOL DEFAULT (j IS JSON OBJECT WITH UNIQUE KEYS), + without_unique_keys BOOL DEFAULT (j IS JSON OBJECT WITHOUT UNIQUE KEYS) +); ---echo # End of 11.2 Test +INSERT INTO test_default_json (j) VALUES + ('[1, 2, 3]'), + ('{"key": "value"}'), + ('3'), + (NULL), + ('{}'), + ('{"key": "value", "key2": "value2"}'), + ('{"key": "value", "key": "value2"}'); + +SELECT + j, + is_json, + is_not_json, + is_array, + is_object, + is_scalar, + with_unique_keys, + without_unique_keys +FROM test_default_json; + +DROP TABLE test_default_json; + +--echo # End of 12.3 diff --git a/mysql-test/main/func_json_notembedded.result b/mysql-test/main/func_json_notembedded.result index ba4d38dd623f3..569f41de70e55 100644 --- a/mysql-test/main/func_json_notembedded.result +++ b/mysql-test/main/func_json_notembedded.result @@ -13,29 +13,29 @@ set max_statement_time=0.0001; SET @old_debug= @@debug_dbug; SET debug_dbug='+d,debug_max_statement_time exceeded'; select json_array_append(@arr, '$[0]', 1); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_array_insert(@arr, '$[0]', 1); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_insert(@obj, '$.meta', 1); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_compact(@arr); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_detailed(@arr); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_loose(@arr); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_merge(@obj, @arr); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_merge_patch(@obj, @obj); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_merge_preserve(@obj, @arr); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_remove(@obj,'$.foo'); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_replace(@obj,'$.foo',1); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded select json_set(@arr,'$[1000]',1); -ERROR 70100: Query execution was interrupted (max_statement_time exceeded) +ERROR 70100: Query was interrupted: execution time limit 0.0001 sec exceeded SET debug_dbug= @old_debug; disconnect u; connection default; diff --git a/mysql-test/main/func_numconv.result b/mysql-test/main/func_numconv.result new file mode 100644 index 0000000000000..d00a939088c01 --- /dev/null +++ b/mysql-test/main/func_numconv.result @@ -0,0 +1,1525 @@ +# +# MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +# +# +# to_number() with one argument +# +SELECT to_number(ROW(1,1)); +ERROR 21000: Operand should contain 1 column(s) +SELECT to_number(point(1,1)); +ERROR HY000: Illegal parameter data type point for operation 'to_number' +# With one arg, to_number() works similarly CAST(expr AS DOUBLE) +CREATE TABLE t1 AS SELECT +to_number('123') AS c1, +to_number(123) AS c2, +to_number(123e0) AS c3, +to_number(123.0) AS c4; +SHOW COLUMNS IN t1; +Field Type Null Key Default Extra +c1 double YES NULL +c2 double YES NULL +c3 double YES NULL +c4 double YES NULL +SELECT * FROM t1; +c1 c2 c3 c4 +123 123 123 123 +DROP TABLE t1; +SELECT to_number('') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='' value: '' for function to_number +SELECT to_number('1E+400') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='' value: '1E+400' for function to_number +SELECT to_number('123x') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='' value: '123x' for function to_number +# +# With two args only string+string are allowed +# +SELECT to_number(point(1,1), ''); +ERROR HY000: Illegal parameter data types point and varchar for operation 'to_number' +SELECT to_number('',point(1,1)); +ERROR HY000: Illegal parameter data types varchar and point for operation 'to_number' +SELECT to_number(1,''); +ERROR HY000: Illegal parameter data types int and varchar for operation 'to_number' +SELECT to_number('',1); +ERROR HY000: Illegal parameter data types varchar and int for operation 'to_number' +SELECT to_number(1e0,''); +ERROR HY000: Illegal parameter data types double and varchar for operation 'to_number' +SELECT to_number('',1e0); +ERROR HY000: Illegal parameter data types varchar and double for operation 'to_number' +# +# Multiple dollar or B signs are not allowed +# +SELECT to_number('0', '99$99$'); +ERROR HY000: Incorrect value: '' for function to_number +SELECT to_number('0', '$9999$'); +ERROR HY000: Incorrect value: '$9999 + $' for function to_number +SELECT to_number('0', '$9.99$'); +ERROR HY000: Incorrect value: '$9.99 + $' for function to_number +SELECT to_number('0', '9$9.9$99EEEE'); +ERROR HY000: Incorrect value: '9$9.9 + $99EEEE' for function to_number +SELECT to_number('0', '99B99B'); +ERROR HY000: Incorrect value: '' for function to_number +SELECT to_number('0', 'B99B99B'); +ERROR HY000: Incorrect value: '' for function to_number +SELECT to_number('0', 'B999B'); +ERROR HY000: Incorrect value: 'B999 + B' for function to_number +SELECT to_number('0', 'B9.99B'); +ERROR HY000: Incorrect value: 'B9.99 + B' for function to_number +SELECT to_number('0', '9B9.9B99EEEE'); +ERROR HY000: Incorrect value: '9B9.9 + B99EEEE' for function to_number +SELECT to_number('0', '.9$9BB$0B'); +ERROR HY000: Incorrect value: '$0B' for function to_number +SELECT to_number('0', '.0$0BB$9B'); +ERROR HY000: Incorrect value: '$9B' for function to_number +# Comma and G cannot co-exist +SELECT to_number('1', '9G9,9G9'); +ERROR HY000: Incorrect value: '9G9' for function to_number +SELECT to_number('1', '9,9G9,9'); +ERROR HY000: Incorrect value: '9,9' for function to_number +SELECT to_number('1', '0G0,0G0'); +ERROR HY000: Incorrect value: '0G0' for function to_number +SELECT to_number('1', '0,0G0,0'); +ERROR HY000: Incorrect value: '0,0' for function to_number +# +# Dollar and C,L,U cannot co-exist +# +SELECT to_number('1', '$C'); +ERROR HY000: Incorrect value: '$ + C' for function to_number +SELECT to_number('1', '$L'); +ERROR HY000: Incorrect value: '$ + L' for function to_number +SELECT to_number('1', '$U'); +ERROR HY000: Incorrect value: '$ + U' for function to_number +SELECT to_number('1', '$C99'); +ERROR HY000: Incorrect value: '$ + C99' for function to_number +SELECT to_number('1', '$L99'); +ERROR HY000: Incorrect value: '$ + L99' for function to_number +SELECT to_number('1', '$U99'); +ERROR HY000: Incorrect value: '$ + U99' for function to_number +SELECT to_number('1', '0$C'); +ERROR HY000: Incorrect value: '0$ + C' for function to_number +SELECT to_number('1', '0$L'); +ERROR HY000: Incorrect value: '0$ + L' for function to_number +SELECT to_number('1', '0$U'); +ERROR HY000: Incorrect value: '0$ + U' for function to_number +SELECT to_number('1', '9$C'); +ERROR HY000: Incorrect value: '9$ + C' for function to_number +SELECT to_number('1', '9$L'); +ERROR HY000: Incorrect value: '9$ + L' for function to_number +SELECT to_number('1', '9$U'); +ERROR HY000: Incorrect value: '9$ + U' for function to_number +SELECT to_number('1', 'C0$'); +ERROR HY000: Incorrect value: 'C0 + $' for function to_number +SELECT to_number('1', 'L0$'); +ERROR HY000: Incorrect value: 'L0 + $' for function to_number +SELECT to_number('1', 'U0$'); +ERROR HY000: Incorrect value: 'U0 + $' for function to_number +SELECT to_number('1', '.$C'); +ERROR HY000: Incorrect value: '.$ + C' for function to_number +SELECT to_number('1', '.$L'); +ERROR HY000: Incorrect value: '.$ + L' for function to_number +SELECT to_number('1', '.$U'); +ERROR HY000: Incorrect value: '.$ + U' for function to_number +SELECT to_number('1', 'D$C'); +ERROR HY000: Incorrect value: 'D$ + C' for function to_number +SELECT to_number('1', 'D$L'); +ERROR HY000: Incorrect value: 'D$ + L' for function to_number +SELECT to_number('1', 'D$U'); +ERROR HY000: Incorrect value: 'D$ + U' for function to_number +SELECT to_number('1', 'V$C'); +ERROR HY000: Incorrect value: 'V$ + C' for function to_number +SELECT to_number('1', 'V$L'); +ERROR HY000: Incorrect value: 'V$ + L' for function to_number +SELECT to_number('1', 'V$U'); +ERROR HY000: Incorrect value: 'V$ + U' for function to_number +SELECT to_number('1', '$.C'); +ERROR HY000: Incorrect value: '$. + C' for function to_number +SELECT to_number('1', '$.L'); +ERROR HY000: Incorrect value: '$. + L' for function to_number +SELECT to_number('1', '$.U'); +ERROR HY000: Incorrect value: '$. + U' for function to_number +SELECT to_number('1', '$DC'); +ERROR HY000: Incorrect value: '$D + C' for function to_number +SELECT to_number('1', '$DL'); +ERROR HY000: Incorrect value: '$D + L' for function to_number +SELECT to_number('1', '$DU'); +ERROR HY000: Incorrect value: '$D + U' for function to_number +# +# Test that non-constant wrong formats raise a warning (not an error) +# +CREATE TABLE t1 (fmt VARCHAR(32)); +INSERT INTO t1 VALUES ('$999$'),('C999'); +SELECT to_number('9999', fmt) FROM t1; +to_number('9999', fmt) +NULL +NULL +Warnings: +Warning 1411 Incorrect value: '$999 + $' for function to_number +Warning 1235 This version of MariaDB doesn't yet support '='C999'' +DROP TABLE t1; +# +# An empty format is allowed and returns NULL +# +SELECT to_number('', ''); +to_number('', '') +NULL +Warnings: +Warning 1411 Incorrect ='' value: '' for function to_number +SELECT to_number('1', ''); +to_number('1', '') +NULL +Warnings: +Warning 1411 Incorrect ='' value: '1' for function to_number +# +# B/dollar can go alone, in combination, with FM, and return NULL +# +SELECT to_number('1', 'B'); +to_number('1', 'B') +NULL +Warnings: +Warning 1411 Incorrect ='B' value: '1' for function to_number +SELECT to_number('1', '$'); +to_number('1', '$') +NULL +Warnings: +Warning 1411 Incorrect ='$' value: '1' for function to_number +SELECT to_number('1', 'B$'); +to_number('1', 'B$') +NULL +Warnings: +Warning 1411 Incorrect ='B$' value: '1' for function to_number +SELECT to_number('1', '$B'); +to_number('1', '$B') +NULL +Warnings: +Warning 1411 Incorrect ='$B' value: '1' for function to_number +SELECT to_number('$', '$'); +to_number('$', '$') +NULL +Warnings: +Warning 1411 Incorrect ='$' value: '$' for function to_number +SELECT to_number('$', 'B$'); +to_number('$', 'B$') +NULL +Warnings: +Warning 1411 Incorrect ='B$' value: '$' for function to_number +SELECT to_number('$', '$B'); +to_number('$', '$B') +NULL +Warnings: +Warning 1411 Incorrect ='$B' value: '$' for function to_number +SELECT to_number('1', 'FMB'); +to_number('1', 'FMB') +NULL +Warnings: +Warning 1411 Incorrect ='FMB' value: '1' for function to_number +SELECT to_number('1', 'FM$'); +to_number('1', 'FM$') +NULL +Warnings: +Warning 1411 Incorrect ='FM$' value: '1' for function to_number +SELECT to_number('1', 'FMB$'); +to_number('1', 'FMB$') +NULL +Warnings: +Warning 1411 Incorrect ='FMB$' value: '1' for function to_number +SELECT to_number('1', 'FM$B'); +to_number('1', 'FM$B') +NULL +Warnings: +Warning 1411 Incorrect ='FM$B' value: '1' for function to_number +SELECT to_number('$', 'FM$'); +to_number('$', 'FM$') +NULL +Warnings: +Warning 1411 Incorrect ='FM$' value: '$' for function to_number +SELECT to_number('$', 'FMB$'); +to_number('$', 'FMB$') +NULL +Warnings: +Warning 1411 Incorrect ='FMB$' value: '$' for function to_number +SELECT to_number('$', 'FM$B'); +to_number('$', 'FM$B') +NULL +Warnings: +Warning 1411 Incorrect ='FM$B' value: '$' for function to_number +# +# . can go alone +# +SELECT to_number('.', '.'); +to_number('.', '.') +0 +SELECT to_number('1', '.'); +to_number('1', '.') +NULL +Warnings: +Warning 1411 Incorrect ='.' value: '1' for function to_number +# +# 'S', 'MI', 'PR' alone are allowed (optionally with FM), NULL returned +# +SELECT to_number('-', 'S'); +to_number('-', 'S') +NULL +Warnings: +Warning 1411 Incorrect ='S' value: '-' for function to_number +SELECT to_number('-', 'MI'); +to_number('-', 'MI') +NULL +Warnings: +Warning 1411 Incorrect ='MI' value: '-' for function to_number +SELECT to_number('<>', 'PR'); +to_number('<>', 'PR') +NULL +Warnings: +Warning 1411 Incorrect ='PR' value: '<>' for function to_number +SELECT to_number('-', 'FMS'); +to_number('-', 'FMS') +NULL +Warnings: +Warning 1411 Incorrect ='FMS' value: '-' for function to_number +SELECT to_number('-', 'SFM'); +to_number('-', 'SFM') +NULL +Warnings: +Warning 1411 Incorrect ='SFM' value: '-' for function to_number +SELECT to_number('-', 'FMMI'); +to_number('-', 'FMMI') +NULL +Warnings: +Warning 1411 Incorrect ='FMMI' value: '-' for function to_number +SELECT to_number('<>', 'FMPR'); +to_number('<>', 'FMPR') +NULL +Warnings: +Warning 1411 Incorrect ='FMPR' value: '<>' for function to_number +SELECT to_number('1', 'S'); +to_number('1', 'S') +NULL +Warnings: +Warning 1411 Incorrect ='S' value: '1' for function to_number +SELECT to_number('1', 'MI'); +to_number('1', 'MI') +NULL +Warnings: +Warning 1411 Incorrect ='MI' value: '1' for function to_number +SELECT to_number('1', 'PR'); +to_number('1', 'PR') +NULL +Warnings: +Warning 1411 Incorrect ='PR' value: '1' for function to_number +SELECT to_number('1', 'FMMI'); +to_number('1', 'FMMI') +NULL +Warnings: +Warning 1411 Incorrect ='FMMI' value: '1' for function to_number +SELECT to_number('1', 'FMPR'); +to_number('1', 'FMPR') +NULL +Warnings: +Warning 1411 Incorrect ='FMPR' value: '1' for function to_number +# +# Integer +# +SELECT to_number('1', 'x999'); +ERROR HY000: Incorrect value: '999' for function to_number +SELECT to_number('1', '999x'); +ERROR HY000: Incorrect value: 'x' for function to_number +# Correct formats +SELECT to_number('1', '999'); +to_number('1', '999') +1 +SELECT to_number('$12', '$99'); +to_number('$12', '$99') +12 +SELECT to_number('$12', '9$9'); +to_number('$12', '9$9') +12 +SELECT to_number('$12', '99$'); +to_number('$12', '99$') +12 +SELECT to_number('1', 'B99'); +to_number('1', 'B99') +1 +SELECT to_number('1', '9B9'); +to_number('1', '9B9') +1 +SELECT to_number('1', '99B'); +to_number('1', '99B') +1 +SELECT to_number('$1', 'B$9'); +to_number('$1', 'B$9') +1 +SELECT to_number('$1', '9B$'); +to_number('$1', '9B$') +1 +SELECT to_number('$1', '$B9'); +to_number('$1', '$B9') +1 +SELECT to_number('$1', '9$B'); +to_number('$1', '9$B') +1 +SELECT to_number('1', '9,9,9,9'); +to_number('1', '9,9,9,9') +1 +SELECT to_number('1', '9G9G9G9'); +ERROR 42000: This version of MariaDB doesn't yet support '='9G9G9G9'' +SELECT to_number('1', '0000'); +to_number('1', '0000') +NULL +Warnings: +Warning 1411 Incorrect ='0000' value: '1' for function to_number +SELECT to_number('1', '0,0,0,0'); +to_number('1', '0,0,0,0') +NULL +Warnings: +Warning 1411 Incorrect ='0,0,0,0' value: '1' for function to_number +SELECT to_number('1', '9999'); +to_number('1', '9999') +1 +SELECT to_number('1', '9,9,9,9'); +to_number('1', '9,9,9,9') +1 +SELECT to_number('1', '0G0G0G0'); +ERROR 42000: This version of MariaDB doesn't yet support '='0G0G0G0'' +SELECT to_number('1', '00009999'); +to_number('1', '00009999') +NULL +Warnings: +Warning 1411 Incorrect ='00009999' value: '1' for function to_number +SELECT to_number('1', '99999999'); +to_number('1', '99999999') +1 +SELECT to_number('1', '0,0,0,0,9,9,9,9'); +to_number('1', '0,0,0,0,9,9,9,9') +NULL +Warnings: +Warning 1411 Incorrect ='0,0,0,0,9,9,9,9 value: '1' for function to_number +SELECT to_number('1', '9,9,9,9,9,9,9,9'); +to_number('1', '9,9,9,9,9,9,9,9') +1 +SELECT to_number('1', '0G0G0G0G9G9G9G9'); +ERROR 42000: This version of MariaDB doesn't yet support '='0G0G0G0G9G9G9G9'' +SELECT to_number('1', '99990000'); +to_number('1', '99990000') +NULL +Warnings: +Warning 1411 Incorrect ='99990000' value: '1' for function to_number +SELECT to_number('1', '99999999'); +to_number('1', '99999999') +1 +SELECT to_number('1', '9,9,9,9,0,0,0,0'); +to_number('1', '9,9,9,9,0,0,0,0') +NULL +Warnings: +Warning 1411 Incorrect ='9,9,9,9,0,0,0,0 value: '1' for function to_number +SELECT to_number('1', '9,9,9,9,9,9,9,9'); +to_number('1', '9,9,9,9,9,9,9,9') +1 +SELECT to_number('1', '9G9G9G9G0G0G0G0'); +ERROR 42000: This version of MariaDB doesn't yet support '='9G9G9G9G0G0G0G0'' +SELECT to_number('123456.123456', '999999.999999') AS c1; +c1 +123456.123456 +SELECT to_number('123,456.123456', '999,999.999999') AS c1; +c1 +123456.123456 +SELECT to_number('1,2,3,4,5,6.123456', '9,9,9,9,9,9.999999') AS c1; +c1 +123456.123456 +# +# Integer: 0 vs 9 +# +CREATE TABLE t1 (fmt VARCHAR(32)); +INSERT INTO t1 VALUES +('0'),('9'), +('00'),('09'),('90'),('99'), +('000'),('009'),('090'),('099'), ('900'),('909'),('990'),('999'); +CREATE TABLE t2 (sbj VARCHAR(32)); +INSERT INTO t2 VALUES ('0'),('00'),('000'),('0000'); +# Expect NULL if +# - the subject is shorter than the format, or +# - if there's a format 0 outside of the subject length +SELECT +fmt, sbj, to_number(sbj,fmt), +IF(length(fmt)=length(sbj) +ORDER BY length(fmt),fmt,sbj; +fmt sbj to_number(sbj,fmt) comment +0 0 0 +9 0 0 +00 0 NULL Expect NULL +00 00 0 +09 0 NULL Expect NULL +09 00 0 +90 0 0 +90 00 0 +99 0 0 +99 00 0 +000 0 NULL Expect NULL +000 00 NULL Expect NULL +000 000 0 +009 0 NULL Expect NULL +009 00 NULL Expect NULL +009 000 0 +090 0 NULL Expect NULL +090 00 NULL Expect NULL +090 000 0 +099 0 NULL Expect NULL +099 00 NULL Expect NULL +099 000 0 +900 0 NULL Expect NULL +900 00 0 +900 000 0 +909 0 NULL Expect NULL +909 00 0 +909 000 0 +990 0 0 +990 00 0 +990 000 0 +999 0 0 +999 00 0 +999 000 0 +Warnings: +Warning 1411 Incorrect ='00' value: '0' for function to_number +Warning 1411 Incorrect ='09' value: '0' for function to_number +Warning 1411 Incorrect ='000' value: '0' for function to_number +Warning 1411 Incorrect ='000' value: '00' for function to_number +Warning 1411 Incorrect ='009' value: '0' for function to_number +Warning 1411 Incorrect ='009' value: '00' for function to_number +Warning 1411 Incorrect ='090' value: '0' for function to_number +Warning 1411 Incorrect ='090' value: '00' for function to_number +Warning 1411 Incorrect ='099' value: '0' for function to_number +Warning 1411 Incorrect ='099' value: '00' for function to_number +Warning 1411 Incorrect ='900' value: '0' for function to_number +Warning 1411 Incorrect ='909' value: '0' for function to_number +DROP TABLE t1, t2; +# +# Fraction +# +SELECT to_number('.', '.'); +to_number('.', '.') +0 +SELECT to_number('.', 'B.'); +to_number('.', 'B.') +0 +SELECT to_number('.', 'B.9'); +to_number('.', 'B.9') +0 +SELECT to_number('.1', 'B.9'); +to_number('.1', 'B.9') +0.1 +SELECT to_number('1', 'B.'); +to_number('1', 'B.') +NULL +Warnings: +Warning 1411 Incorrect ='B.' value: '1' for function to_number +SELECT to_number('1', 'B.9'); +to_number('1', 'B.9') +NULL +Warnings: +Warning 1411 Incorrect ='B.9' value: '1' for function to_number +# +# Fraction + dollar +# +SELECT to_number('$.', '$.'); +to_number('$.', '$.') +0 +SELECT to_number('1', '$.'); +to_number('1', '$.') +NULL +Warnings: +Warning 1411 Incorrect ='$.' value: '1' for function to_number +SELECT to_number('.1', '.9999'); +to_number('.1', '.9999') +0.1 +SELECT to_number('.1', '.99990000'); +to_number('.1', '.99990000') +0.1 +SELECT to_number('$.1', '.9$9B'); +to_number('$.1', '.9$9B') +0.1 +SELECT to_number('.1', '.0000'); +to_number('.1', '.0000') +0.1 +SELECT to_number('.1', '.00009999'); +to_number('.1', '.00009999') +0.1 +SELECT to_number('$.1', '.0$0B'); +to_number('$.1', '.0$0B') +0.1 +SELECT to_number('1', '$.9'); +to_number('1', '$.9') +NULL +Warnings: +Warning 1411 Incorrect ='$.9' value: '1' for function to_number +SELECT to_number('1', '$.9'); +to_number('1', '$.9') +NULL +Warnings: +Warning 1411 Incorrect ='$.9' value: '1' for function to_number +# +# Decimal +# +SELECT to_number('1', '9999.'); +to_number('1', '9999.') +1 +SELECT to_number('1', '9999.9999'); +to_number('1', '9999.9999') +1 +SELECT to_number('1', '9999.99990000'); +to_number('1', '9999.99990000') +1 +SELECT to_number('1', '9999.00009999'); +to_number('1', '9999.00009999') +1 +SELECT to_number('1', '9999.'); +to_number('1', '9999.') +1 +SELECT to_number('1', '9999.9999'); +to_number('1', '9999.9999') +1 +SELECT to_number('1', '9999.99990000'); +to_number('1', '9999.99990000') +1 +SELECT to_number('1', '9999.00009999'); +to_number('1', '9999.00009999') +1 +# The subject has more integer digits than the format +SELECT to_number('111.1','9.9'); +to_number('111.1','9.9') +NULL +Warnings: +Warning 1411 Incorrect ='9.9' value: '111.1' for function to_number +# The subject has more fractional digits than the format +SELECT to_number('1.111','9.9'); +to_number('1.111','9.9') +NULL +Warnings: +Warning 1411 Incorrect ='9.9' value: '1.111' for function to_number +# Multiple dollar and B prefix flags are not allowed +select to_number('$1','$$9.9'); +ERROR HY000: Incorrect value: '$ + $9.9' for function to_number +select to_number('11','BB9.9'); +ERROR HY000: Incorrect value: 'B + B9.9' for function to_number +# +# Decimal starting with zeros +# +CREATE TABLE t1 (num VARCHAR(32), fmt VARCHAR(64)); +INSERT INTO t1 VALUES +('1', '0.999'), +('111', '000.999'), +('111111','000999.999'), +('11111111','00090909.999'); +SELECT to_number(num, fmt), fmt FROM t1; +to_number(num, fmt) fmt +1 0.999 +111 000.999 +111111 000999.999 +11111111 00090909.999 +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','D')), @fmt FROM t1; +to_number(num, @fmt:=REPLACE(fmt,'.','D')) @fmt +NULL 0D999 +NULL 000D999 +NULL 000999D999 +NULL 00090909D999 +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0D999'' +Warning 1235 This version of MariaDB doesn't yet support '='000D999'' +Warning 1235 This version of MariaDB doesn't yet support '='000999D999'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909D999'' +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','V')), @fmt FROM t1; +to_number(num, @fmt:=REPLACE(fmt,'.','V')) @fmt +NULL 0V999 +NULL 000V999 +NULL 000999V999 +NULL 00090909V999 +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0V999'' +Warning 1235 This version of MariaDB doesn't yet support '='000V999'' +Warning 1235 This version of MariaDB doesn't yet support '='000999V999'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909V999'' +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','C')), @fmt FROM t1; +to_number(num, @fmt:=REPLACE(fmt,'.','C')) @fmt +NULL 0C999 +NULL 000C999 +NULL 000999C999 +NULL 00090909C999 +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0C999'' +Warning 1235 This version of MariaDB doesn't yet support '='000C999'' +Warning 1235 This version of MariaDB doesn't yet support '='000999C999'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909C999'' +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','L')), @fmt FROM t1; +to_number(num, @fmt:=REPLACE(fmt,'.','L')) @fmt +NULL 0L999 +NULL 000L999 +NULL 000999L999 +NULL 00090909L999 +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0L999'' +Warning 1235 This version of MariaDB doesn't yet support '='000L999'' +Warning 1235 This version of MariaDB doesn't yet support '='000999L999'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909L999'' +DROP TABLE t1; +# +# Decimal + flags B/dollar + signs +# +SELECT to_number('-1', 'SB'); +to_number('-1', 'SB') +NULL +Warnings: +Warning 1411 Incorrect ='SB' value: '-1' for function to_number +SELECT to_number('-$1', 'S$'); +to_number('-$1', 'S$') +NULL +Warnings: +Warning 1411 Incorrect ='S$' value: '-$1' for function to_number +SELECT to_number('-$1', 'SB$'); +to_number('-$1', 'SB$') +NULL +Warnings: +Warning 1411 Incorrect ='SB$' value: '-$1' for function to_number +SELECT to_number('-$1', 'S$B'); +to_number('-$1', 'S$B') +NULL +Warnings: +Warning 1411 Incorrect ='S$B' value: '-$1' for function to_number +SELECT to_number('1', 'BS'); +to_number('1', 'BS') +NULL +Warnings: +Warning 1411 Incorrect ='BS' value: '1' for function to_number +SELECT to_number('1', 'BMI'); +to_number('1', 'BMI') +NULL +Warnings: +Warning 1411 Incorrect ='BMI' value: '1' for function to_number +SELECT to_number('1', 'BPR'); +to_number('1', 'BPR') +NULL +Warnings: +Warning 1411 Incorrect ='BPR' value: '1' for function to_number +SELECT to_number('1', '$S'); +to_number('1', '$S') +NULL +Warnings: +Warning 1411 Incorrect ='$S' value: '1' for function to_number +SELECT to_number('1', '$MI'); +to_number('1', '$MI') +NULL +Warnings: +Warning 1411 Incorrect ='$MI' value: '1' for function to_number +SELECT to_number('1', '$PR'); +to_number('1', '$PR') +NULL +Warnings: +Warning 1411 Incorrect ='$PR' value: '1' for function to_number +SELECT to_number('1', 'BC'); +ERROR 42000: This version of MariaDB doesn't yet support '='BC'' +SELECT to_number('1', 'BL'); +ERROR 42000: This version of MariaDB doesn't yet support '='BL'' +SELECT to_number('1', 'BU'); +ERROR 42000: This version of MariaDB doesn't yet support '='BU'' +SELECT to_number('1', 'BC99'); +ERROR 42000: This version of MariaDB doesn't yet support '='BC99'' +SELECT to_number('1', 'BL99'); +ERROR 42000: This version of MariaDB doesn't yet support '='BL99'' +SELECT to_number('1', 'BU99'); +ERROR 42000: This version of MariaDB doesn't yet support '='BU99'' +SELECT to_number('1', 'BV'); +ERROR 42000: This version of MariaDB doesn't yet support '='BV'' +SELECT to_number('1', 'BV99'); +ERROR 42000: This version of MariaDB doesn't yet support '='BV99'' +SELECT to_number('1', '$V'); +ERROR 42000: This version of MariaDB doesn't yet support '='$V'' +SELECT to_number('1', '$V99'); +ERROR 42000: This version of MariaDB doesn't yet support '='$V99'' +SELECT to_number('1', 'B.'); +to_number('1', 'B.') +NULL +Warnings: +Warning 1411 Incorrect ='B.' value: '1' for function to_number +SELECT to_number('1', 'BD'); +ERROR 42000: This version of MariaDB doesn't yet support '='BD'' +SELECT to_number('1', 'B.99'); +to_number('1', 'B.99') +NULL +Warnings: +Warning 1411 Incorrect ='B.99' value: '1' for function to_number +SELECT to_number('1', 'BD99'); +ERROR 42000: This version of MariaDB doesn't yet support '='BD99'' +SELECT to_number('1', '$.'); +to_number('1', '$.') +NULL +Warnings: +Warning 1411 Incorrect ='$.' value: '1' for function to_number +SELECT to_number('1', '$D'); +ERROR 42000: This version of MariaDB doesn't yet support '='$D'' +SELECT to_number('1', '$.99'); +to_number('1', '$.99') +NULL +Warnings: +Warning 1411 Incorrect ='$.99' value: '1' for function to_number +SELECT to_number('1', '$D99'); +ERROR 42000: This version of MariaDB doesn't yet support '='$D99'' +# +# Number1 (i.e. not starting with zeros) +# +SELECT to_number('1', 'CB,999'); +ERROR HY000: Incorrect value: ',999' for function to_number +SELECT to_number('1', 'CBG999'); +ERROR HY000: Incorrect value: 'G999' for function to_number +SELECT to_number('1', 'C999'); +ERROR 42000: This version of MariaDB doesn't yet support '='C999'' +SELECT to_number('1', 'C000'); +ERROR 42000: This version of MariaDB doesn't yet support '='C000'' +SELECT to_number('1', 'CB999'); +ERROR 42000: This version of MariaDB doesn't yet support '='CB999'' +SELECT to_number('1', 'CB000'); +ERROR 42000: This version of MariaDB doesn't yet support '='CB000'' +SELECT to_number('1', 'C'); +ERROR 42000: This version of MariaDB doesn't yet support '='C'' +SELECT to_number('1', 'C.'); +ERROR 42000: This version of MariaDB doesn't yet support '='C.'' +SELECT to_number('1', 'CD'); +ERROR 42000: This version of MariaDB doesn't yet support '='CD'' +SELECT to_number('1', 'CV'); +ERROR 42000: This version of MariaDB doesn't yet support '='CV'' +SELECT to_number('1', 'C.99'); +ERROR 42000: This version of MariaDB doesn't yet support '='C.99'' +SELECT to_number('1', 'CD99'); +ERROR 42000: This version of MariaDB doesn't yet support '='CD99'' +SELECT to_number('1', 'CV99'); +ERROR 42000: This version of MariaDB doesn't yet support '='CV99'' +SELECT to_number('1', 'CB.999'); +ERROR 42000: This version of MariaDB doesn't yet support '='CB.999'' +SELECT to_number('1', 'CBD999'); +ERROR 42000: This version of MariaDB doesn't yet support '='CBD999'' +SELECT to_number('1', 'CB'); +ERROR 42000: This version of MariaDB doesn't yet support '='CB'' +SELECT to_number('1', 'L999'); +ERROR 42000: This version of MariaDB doesn't yet support '='L999'' +SELECT to_number('1', 'L000'); +ERROR 42000: This version of MariaDB doesn't yet support '='L000'' +SELECT to_number('1', 'LB999'); +ERROR 42000: This version of MariaDB doesn't yet support '='LB999'' +SELECT to_number('1', 'LB000'); +ERROR 42000: This version of MariaDB doesn't yet support '='LB000'' +SELECT to_number('1', 'L'); +ERROR 42000: This version of MariaDB doesn't yet support '='L'' +SELECT to_number('1', 'L.'); +ERROR 42000: This version of MariaDB doesn't yet support '='L.'' +SELECT to_number('1', 'LD'); +ERROR 42000: This version of MariaDB doesn't yet support '='LD'' +SELECT to_number('1', 'LV'); +ERROR 42000: This version of MariaDB doesn't yet support '='LV'' +SELECT to_number('1', 'L.99'); +ERROR 42000: This version of MariaDB doesn't yet support '='L.99'' +SELECT to_number('1', 'LD99'); +ERROR 42000: This version of MariaDB doesn't yet support '='LD99'' +SELECT to_number('1', 'LV99'); +ERROR 42000: This version of MariaDB doesn't yet support '='LV99'' +SELECT to_number('1', 'LB.999'); +ERROR 42000: This version of MariaDB doesn't yet support '='LB.999'' +SELECT to_number('1', 'LBD999'); +ERROR 42000: This version of MariaDB doesn't yet support '='LBD999'' +SELECT to_number('1', 'LB'); +ERROR 42000: This version of MariaDB doesn't yet support '='LB'' +SELECT to_number('1', 'U999'); +ERROR 42000: This version of MariaDB doesn't yet support '='U999'' +SELECT to_number('1', 'U000'); +ERROR 42000: This version of MariaDB doesn't yet support '='U000'' +SELECT to_number('1', 'UB999'); +ERROR 42000: This version of MariaDB doesn't yet support '='UB999'' +SELECT to_number('1', 'UB000'); +ERROR 42000: This version of MariaDB doesn't yet support '='UB000'' +SELECT to_number('1', 'U'); +ERROR 42000: This version of MariaDB doesn't yet support '='U'' +SELECT to_number('1', 'U.'); +ERROR 42000: This version of MariaDB doesn't yet support '='U.'' +SELECT to_number('1', 'UD'); +ERROR 42000: This version of MariaDB doesn't yet support '='UD'' +SELECT to_number('1', 'UV'); +ERROR 42000: This version of MariaDB doesn't yet support '='UV'' +SELECT to_number('1', 'U.99'); +ERROR 42000: This version of MariaDB doesn't yet support '='U.99'' +SELECT to_number('1', 'UD99'); +ERROR 42000: This version of MariaDB doesn't yet support '='UD99'' +SELECT to_number('1', 'UV99'); +ERROR 42000: This version of MariaDB doesn't yet support '='UV99'' +SELECT to_number('1', 'UB.999'); +ERROR 42000: This version of MariaDB doesn't yet support '='UB.999'' +SELECT to_number('1', 'UBD999'); +ERROR 42000: This version of MariaDB doesn't yet support '='UBD999'' +SELECT to_number('1', 'UB'); +ERROR 42000: This version of MariaDB doesn't yet support '='UB'' +# +# Number0: zeros + postfix sign +# +SELECT to_number('12-', '00S'); +to_number('12-', '00S') +-12 +SELECT to_number('12+', '00S'); +to_number('12+', '00S') +12 +SELECT to_number('12-', '00MI'); +to_number('12-', '00MI') +-12 +SELECT to_number('12 ', '00MI'); +to_number('12 ', '00MI') +12 +SELECT to_number('<12>', '00PR'); +to_number('<12>', '00PR') +-12 +SELECT to_number(' 12 ', '00PR'); +to_number(' 12 ', '00PR') +12 +SELECT to_number('[12]', '00PR'); +to_number('[12]', '00PR') +NULL +Warnings: +Warning 1411 Incorrect ='00PR' value: '[12]' for function to_number +SELECT to_number('<1234>', '999999PR') AS c1; +c1 +-1234 +SELECT to_number(' 1234 ', '999999PR') AS c1; +c1 +1234 +# +# Postfix sign +# +SELECT to_number('12-', '99S'); +to_number('12-', '99S') +-12 +SELECT to_number('12+', '99S'); +to_number('12+', '99S') +12 +SELECT to_number('12-', '99MI'); +to_number('12-', '99MI') +-12 +SELECT to_number('12 ', '99MI'); +to_number('12 ', '99MI') +12 +SELECT to_number('<12>', '99PR'); +to_number('<12>', '99PR') +-12 +SELECT to_number(' 12 ', '99PR'); +to_number(' 12 ', '99PR') +12 +# +# Prefix sign +# +SELECT to_number('-1', 'S'); +to_number('-1', 'S') +NULL +Warnings: +Warning 1411 Incorrect ='S' value: '-1' for function to_number +SELECT to_number('-1', 'S00'); +to_number('-1', 'S00') +NULL +Warnings: +Warning 1411 Incorrect ='S00' value: '-1' for function to_number +SELECT to_number('-12', 'S00'); +to_number('-12', 'S00') +-12 +SELECT to_number('-1', 'S99'); +to_number('-1', 'S99') +-1 +SELECT to_number('1', 'FMS'); +to_number('1', 'FMS') +NULL +Warnings: +Warning 1411 Incorrect ='FMS' value: '1' for function to_number +SELECT to_number('-12', 'FMS00'); +to_number('-12', 'FMS00') +-12 +SELECT to_number('-12', 'FMS99'); +to_number('-12', 'FMS99') +-12 +SELECT to_number('1', 'SFM'); +to_number('1', 'SFM') +NULL +Warnings: +Warning 1411 Incorrect ='SFM' value: '1' for function to_number +SELECT to_number('-12', 'SFM00'); +to_number('-12', 'SFM00') +-12 +SELECT to_number('-12', 'SFM99'); +to_number('-12', 'SFM99') +-12 +# +# Prefix-signed currency +# +# CLU are not supported yet +SELECT to_number('1', 'S00.99C'); +ERROR 42000: This version of MariaDB doesn't yet support '='S00.99C'' +SELECT to_number('1', 'S99.99L'); +ERROR 42000: This version of MariaDB doesn't yet support '='S99.99L'' +SELECT to_number('1', 'S99.99U'); +ERROR 42000: This version of MariaDB doesn't yet support '='S99.99U'' +SELECT to_number('1', 'S00D99C'); +ERROR 42000: This version of MariaDB doesn't yet support '='S00D99C'' +SELECT to_number('1', 'S99D99L'); +ERROR 42000: This version of MariaDB doesn't yet support '='S99D99L'' +SELECT to_number('1', 'S99D99U'); +ERROR 42000: This version of MariaDB doesn't yet support '='S99D99U'' +SELECT to_number('-$12,345.67', 'S$999,099.99') AS c1; +c1 +-12345.67 +SELECT to_number('+$12,345.67', 'S$999,099.99') AS c1; +c1 +12345.67 +SELECT to_number('-$12,345.67', 'S$999,999.99') AS c1; +c1 +-12345.67 +SELECT to_number('+$12,345.67', 'S$999,999.99') AS c1; +c1 +12345.67 +SELECT to_number('$12,345.67', 'S$999,099.99') AS c1, 'Missing sign' AS comment; +c1 comment +NULL Missing sign +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '$12,345.67' for function to_number +SELECT to_number('-$45', 'S$999,099.99') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '-$45' for function to_number +SELECT to_number('+$45', 'S$999,099.99') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '+$45' for function to_number +SELECT to_number('$45', 'S$999,099.99') AS c1, 'Missing sign' AS comment; +c1 comment +NULL Missing sign +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '$45' for function to_number +SELECT to_number('-$45', 'S$999,999.99') AS c1; +c1 +-45 +SELECT to_number('+$45', 'S$999,999.99') AS c1; +c1 +45 +SELECT to_number('$45', 'S$999,999.99') AS c1, 'Missing sign' AS comment; +c1 comment +NULL Missing sign +Warnings: +Warning 1411 Incorrect ='S$999,999.99' value: '$45' for function to_number +SELECT to_number('+$5', 'S$999,099.99') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '+$5' for function to_number +SELECT to_number('+$45', 'S$999,099.99') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '+$45' for function to_number +SELECT to_number('+$045', 'S$999,099.99') AS c1; +c1 +45 +SELECT to_number('+$0,045', 'S$999,099.99') AS c1; +c1 +45 +SELECT to_number('+$00,045', 'S$999,099.99') AS c1; +c1 +45 +SELECT to_number('+$000,045', 'S$999,099.99') AS c1; +c1 +45 +SELECT to_number('+$0000,045', 'S$999,099.99') AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='S$999,099.99' value: '+$0000,045' for function to_number +# +# FM +# +SELECT to_number('1', 'FM'); +to_number('1', 'FM') +NULL +Warnings: +Warning 1411 Incorrect ='FM' value: '1' for function to_number +SELECT to_number('1', 'FM9'); +to_number('1', 'FM9') +1 +SELECT to_number('1,2', 'FM9,9'); +to_number('1,2', 'FM9,9') +12 +SELECT to_number('1.2', 'FM9.9'); +to_number('1.2', 'FM9.9') +1.2 +SELECT to_number('1-', 'FM9S'); +to_number('1-', 'FM9S') +-1 +SELECT to_number('-1', 'FMS9'); +to_number('-1', 'FMS9') +-1 +SELECT to_number('12-', 'FM00S'); +to_number('12-', 'FM00S') +-12 +SELECT to_number('12-', 'FM99S'); +to_number('12-', 'FM99S') +-12 +SELECT to_number('12-', 'FM99S'); +to_number('12-', 'FM99S') +-12 +SELECT to_number('12-', 'FM00.99S'); +to_number('12-', 'FM00.99S') +-12 +SELECT to_number('12-', 'FM99.99S'); +to_number('12-', 'FM99.99S') +-12 +SELECT to_number('12-', 'FM99.99S'); +to_number('12-', 'FM99.99S') +-12 +SELECT to_number('12.34-', 'FM00.99S'); +to_number('12.34-', 'FM00.99S') +-12.34 +SELECT to_number('12.34-', 'FM99.99S'); +to_number('12.34-', 'FM99.99S') +-12.34 +SELECT to_number('12.34-', 'FM99.99S'); +to_number('12.34-', 'FM99.99S') +-12.34 +# +# Long examples +# +SELECT to_number('123,456,789','999,999,999') AS c1; +c1 +123456789 +SELECT to_number('111,222,333,444,555','999,999,999,999,999') AS c1; +c1 +111222333444555 +SELECT to_number('111,222,333,444,555,666,777,888,999', +'999,999,999,999,999,999,999,999,999') AS c1; +c1 +1.1122233344455566e26 +# +# EEEE specific tests +# +# EEEE cannot go without any integer digits +SELECT to_number('', 'EEEE'); +ERROR HY000: Incorrect value: 'EEEE' for function to_number +SELECT to_number('', '.EEEE'); +ERROR HY000: Incorrect value: '. + EEEE' for function to_number +SELECT to_number('', '.9EEEE'); +ERROR HY000: Incorrect value: '.9 + EEEE' for function to_number +SELECT to_number('1', '.999EEEE'); +ERROR HY000: Incorrect value: '.999 + EEEE' for function to_number +SELECT to_number('1', '.9$9EEEE'); +ERROR HY000: Incorrect value: '.9$9 + EEEE' for function to_number +SELECT to_number('1', '.9B9EEEE'); +ERROR HY000: Incorrect value: '.9B9 + EEEE' for function to_number +SELECT to_number('1', '$EEEE'); +ERROR HY000: Incorrect value: 'EEEE' for function to_number +SELECT to_number('1', 'BEEEE'); +ERROR HY000: Incorrect value: 'EEEE' for function to_number +SELECT to_number('', 'S.9EEEE'); +ERROR HY000: Incorrect value: 'S.9 + EEEE' for function to_number +SELECT to_number('', 'S.9EEEES'); +ERROR HY000: Incorrect value: 'S' for function to_number +SELECT to_number('', 'FM.EEEE'); +ERROR HY000: Incorrect value: 'FM. + EEEE' for function to_number +# +# EEEE correct formats +# +# Currency CLU is not supported yet +SELECT to_number('1', 'C0EEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='C0EEEE'' +SELECT to_number('1', 'L0EEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='L0EEEE'' +SELECT to_number('1', 'U0EEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='U0EEEE'' +SELECT to_number('1', 'C9EEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='C9EEEE'' +SELECT to_number('1', 'L9EEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='L9EEEE'' +SELECT to_number('1', 'U9EEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='U9EEEE'' +# +# The following formats are not supported in Oracle. +# However, it works if change C/L/U to dollar sign. +# Looks like a bug in Oracle. +# Anyway, CLU is not supported yet. +# +SELECT to_number('1', 'S00.99CEEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='S00.99CEEEE'' +SELECT to_number('1', 'S99.99LEEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='S99.99LEEEE'' +SELECT to_number('1', 'S99.99UEEEE'); +ERROR 42000: This version of MariaDB doesn't yet support '='S99.99UEEEE'' +# Trailing gargabe: +SELECT to_number('1E+3x', '99EEEE'); +to_number('1E+3x', '99EEEE') +NULL +Warnings: +Warning 1411 Incorrect ='99EEEE' value: '1E+3x' for function to_number +SELECT to_number('$1E+3x', '$99EEEE'); +to_number('$1E+3x', '$99EEEE') +NULL +Warnings: +Warning 1411 Incorrect ='$99EEEE' value: '$1E+3x' for function to_number +# +# Simple examples with EEEE +# +SELECT to_number('1', '9EEEE'); +to_number('1', '9EEEE') +1 +SELECT to_number('1', '9.9EEEE'); +to_number('1', '9.9EEEE') +1 +SELECT to_number('1.2', '9.9EEEE'); +to_number('1.2', '9.9EEEE') +1.2 +# +# EEEE formats starting with zeros +# +SELECT to_number('1', '00EEEE'); +to_number('1', '00EEEE') +1 +CREATE TABLE t1 (num VARCHAR(32), fmt VARCHAR(64)); +INSERT INTO t1 VALUES +('1', '0.999'), +('111', '000.999'), +('111111','000999.999'), +('11111111','00090909.999'); +SELECT to_number(num, @fmt:=CONCAT(fmt,'EEEE')), @fmt FROM t1; +to_number(num, @fmt:=CONCAT(fmt,'EEEE')) @fmt +1 0.999EEEE +111 000.999EEEE +111111 000999.999EEEE +11111111 00090909.999EEEE +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','D'),'EEEE')), @fmt FROM t1; +to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','D'),'EEEE')) @fmt +NULL 0D999EEEE +NULL 000D999EEEE +NULL 000999D999EEEE +NULL 00090909D999EEEE +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0D999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000D999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000999D999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909D999EEEE'' +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','V'),'EEEE')), @fmt FROM t1; +to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','V'),'EEEE')) @fmt +NULL 0V999EEEE +NULL 000V999EEEE +NULL 000999V999EEEE +NULL 00090909V999EEEE +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0V999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000V999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000999V999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909V999EEEE'' +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','C'),'EEEE')), @fmt FROM t1; +to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','C'),'EEEE')) @fmt +NULL 0C999EEEE +NULL 000C999EEEE +NULL 000999C999EEEE +NULL 00090909C999EEEE +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0C999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000C999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000999C999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909C999EEEE'' +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','L'),'EEEE')), @fmt FROM t1; +to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','L'),'EEEE')) @fmt +NULL 0L999EEEE +NULL 000L999EEEE +NULL 000999L999EEEE +NULL 00090909L999EEEE +Warnings: +Warning 1235 This version of MariaDB doesn't yet support '='0L999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000L999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='000999L999EEEE'' +Warning 1235 This version of MariaDB doesn't yet support '='00090909L999EEEE'' +DROP TABLE t1; +# +# B and dollar inside a EEEE format +# +SELECT to_number('1', 'B0EEEE'); +to_number('1', 'B0EEEE') +1 +SELECT to_number('1', 'B9EEEE'); +to_number('1', 'B9EEEE') +1 +SELECT to_number('1', 'B0.EEEE'); +to_number('1', 'B0.EEEE') +1 +SELECT to_number('1', 'B9.EEEE'); +to_number('1', 'B9.EEEE') +1 +SELECT to_number('1', 'B0.9EEEE'); +to_number('1', 'B0.9EEEE') +1 +SELECT to_number('1', 'B9.9EEEE'); +to_number('1', 'B9.9EEEE') +1 +SELECT to_number('$1E+1', '$0EEEE'); +to_number('$1E+1', '$0EEEE') +10 +SELECT to_number('$1E+1', '$9EEEE'); +to_number('$1E+1', '$9EEEE') +10 +SELECT to_number('$1E+1', '$0.EEEE'); +to_number('$1E+1', '$0.EEEE') +10 +SELECT to_number('$1E+1', '$9.EEEE'); +to_number('$1E+1', '$9.EEEE') +10 +SELECT to_number('$1.E+1', '$0.EEEE'); +to_number('$1.E+1', '$0.EEEE') +10 +SELECT to_number('$1.E+1', '$9.EEEE'); +to_number('$1.E+1', '$9.EEEE') +10 +SELECT to_number('$1.2E+1', '$0.EEEE'); +to_number('$1.2E+1', '$0.EEEE') +12 +SELECT to_number('$1.2E+1', '$9.EEEE'); +to_number('$1.2E+1', '$9.EEEE') +12 +SELECT to_number('$1.2E+1', '$0.9EEEE'); +to_number('$1.2E+1', '$0.9EEEE') +12 +SELECT to_number('$1.2E+1', '$9.9EEEE'); +to_number('$1.2E+1', '$9.9EEEE') +12 +SELECT to_number('1', '999EEEE'); +to_number('1', '999EEEE') +1 +SELECT to_number('1', '999.EEEE'); +to_number('1', '999.EEEE') +1 +SELECT to_number('1', '999.9999EEEE'); +to_number('1', '999.9999EEEE') +1 +SELECT to_number ('$1', '9$9EEEE'); +to_number ('$1', '9$9EEEE') +1 +SELECT to_number ('$1', '9$9.EEEE'); +to_number ('$1', '9$9.EEEE') +1 +SELECT to_number('1', '9B9EEEE'); +to_number('1', '9B9EEEE') +1 +SELECT to_number('1', '9B9.EEEE'); +to_number('1', '9B9.EEEE') +1 +# +# EEEE formats with prefix and postfix signs and FM +# +SELECT to_number('1.2E+1-', '99EEEES'); +to_number('1.2E+1-', '99EEEES') +-12 +SELECT to_number('1.2E+1+', '99EEEES'); +to_number('1.2E+1+', '99EEEES') +12 +SELECT to_number('1.2E+1-', '99EEEEMI'); +to_number('1.2E+1-', '99EEEEMI') +-12 +SELECT to_number('1.2E+1 ', '99EEEEMI'); +to_number('1.2E+1 ', '99EEEEMI') +12 +SELECT to_number('<1.2E+1>', '99EEEEPR'); +to_number('<1.2E+1>', '99EEEEPR') +-12 +SELECT to_number(' 1.2E+1 ', '99EEEEPR'); +to_number(' 1.2E+1 ', '99EEEEPR') +12 +SELECT to_number('-12.34E+2', 'S00.99EEEE'); +to_number('-12.34E+2', 'S00.99EEEE') +-1234 +SELECT to_number('-12.34E+2', 'S99.99EEEE'); +to_number('-12.34E+2', 'S99.99EEEE') +-1234 +SELECT to_number('$1.2E+1-', '$9.9EEEES'); +to_number('$1.2E+1-', '$9.9EEEES') +-12 +SELECT to_number('$1.2E+1+', '$9.9EEEES'); +to_number('$1.2E+1+', '$9.9EEEES') +12 +SELECT to_number('$1.2E+1-', '$9.9EEEEMI'); +to_number('$1.2E+1-', '$9.9EEEEMI') +-12 +SELECT to_number('$1.2E+1 ', '$9.9EEEEMI'); +to_number('$1.2E+1 ', '$9.9EEEEMI') +12 +SELECT to_number('<$1.2E+1>', '$9.9EEEEPR'); +to_number('<$1.2E+1>', '$9.9EEEEPR') +-12 +SELECT to_number(' $1.2E+1 ', '$9.9EEEEPR'); +to_number(' $1.2E+1 ', '$9.9EEEEPR') +12 +SELECT to_number('12.34E+2-', 'FM00.99EEEES'); +to_number('12.34E+2-', 'FM00.99EEEES') +-1234 +SELECT to_number('12.34E+2-', 'FM99.99EEEES'); +to_number('12.34E+2-', 'FM99.99EEEES') +-1234 +# +# X formats (hexadecimal) +# +# X cannot co-exist with dollar, B, dec, group, signs, currency +SELECT to_number('0', '$X'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', 'BX'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', 'X,X'); +ERROR HY000: Incorrect value: ',X' for function to_number +SELECT to_number('0', 'XGX'); +ERROR HY000: Incorrect value: 'GX' for function to_number +SELECT to_number('0', 'X.X'); +ERROR HY000: Incorrect value: '.X' for function to_number +SELECT to_number('0', 'XCX'); +ERROR HY000: Incorrect value: 'CX' for function to_number +SELECT to_number('0', 'XLX'); +ERROR HY000: Incorrect value: 'LX' for function to_number +SELECT to_number('0', 'XUX'); +ERROR HY000: Incorrect value: 'UX' for function to_number +SELECT to_number('0', 'SX'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', '$X'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', 'CX'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', 'LX'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', 'UX'); +ERROR HY000: Incorrect value: 'X' for function to_number +SELECT to_number('0', 'X$'); +ERROR HY000: Incorrect value: '$' for function to_number +SELECT to_number('0', 'XC'); +ERROR HY000: Incorrect value: 'C' for function to_number +SELECT to_number('0', 'XL'); +ERROR HY000: Incorrect value: 'L' for function to_number +SELECT to_number('0', 'XU'); +ERROR HY000: Incorrect value: 'U' for function to_number +SELECT to_number('0', 'XMI'); +ERROR HY000: Incorrect value: 'MI' for function to_number +SELECT to_number('0', 'XPR'); +ERROR HY000: Incorrect value: 'PR' for function to_number +SELECT to_number('0', 'XS'); +ERROR HY000: Incorrect value: 'S' for function to_number +# +# FM and X can co-exist +# +SELECT to_number('F', 'FMXXXX'); +to_number('F', 'FMXXXX') +15 +SELECT to_number('FF', 'FMXXXX'); +to_number('FF', 'FMXXXX') +255 +SELECT to_number('FFF', 'FMXXXX'); +to_number('FFF', 'FMXXXX') +4095 +SELECT to_number('FFFF', 'FMXXXX'); +to_number('FFFF', 'FMXXXX') +65535 +# +# X simple exaples +# +SELECT to_number('0', 'X'); +to_number('0', 'X') +0 +SELECT to_number('20', 'XX'); +to_number('20', 'XX') +32 +SELECT to_number('020', 'XXX'); +to_number('020', 'XXX') +32 +SELECT to_number('2020', 'XXXX'); +to_number('2020', 'XXXX') +8224 +SELECT to_number('02020', 'XXXXX'); +to_number('02020', 'XXXXX') +8224 +SELECT to_number('202020', 'XXXXXX'); +to_number('202020', 'XXXXXX') +2105376 +SELECT to_number('202020', 'XXXXX'); +to_number('202020', 'XXXXX') +NULL +Warnings: +Warning 1411 Incorrect ='XXXXX' value: '202020' for function to_number +# +# Zeros + xchain +# +SELECT to_number('061', '00X'); +to_number('061', '00X') +97 +SELECT to_number('0061', '00XX'); +to_number('0061', '00XX') +97 +SELECT to_number('00061', '00XXX'); +to_number('00061', '00XXX') +97 +SELECT to_number('000061', '00XXXX'); +to_number('000061', '00XXXX') +97 +SELECT to_number('0000061', '00XXXXX'); +to_number('0000061', '00XXXXX') +97 +SELECT to_number('00000061', '00XXXXXX'); +to_number('00000061', '00XXXXXX') +97 +# +# 0 vs X +# +CREATE TABLE t1 (fmt VARCHAR(32)); +CREATE TABLE t2 (sbj VARCHAR(32)); +FOR i IN 0..3 DO +INSERT INTO t1 VALUES (CONCAT(REPEAT('0',i), REPEAT('X',4-i))); +END FOR; +$$ +FOR i IN 0..4 DO +INSERT INTO t2 VALUES (REPEAT('1',i)); +END FOR; +$$ +SELECT fmt, sbj, to_number(sbj, fmt) AS c1 FROM t1, t2 ORDER BY fmt, sbj; +fmt sbj c1 +000X NULL +000X 1 NULL +000X 11 NULL +000X 111 NULL +000X 1111 4369 +00XX NULL +00XX 1 NULL +00XX 11 NULL +00XX 111 NULL +00XX 1111 4369 +0XXX NULL +0XXX 1 NULL +0XXX 11 NULL +0XXX 111 NULL +0XXX 1111 4369 +XXXX NULL +XXXX 1 1 +XXXX 11 17 +XXXX 111 273 +XXXX 1111 4369 +DROP TABLE t1, t2; +# +# Format TM is not supported by to_number(), only supported by to_char() +# +SELECT to_number('1', 'TM'); +ERROR 42000: This version of MariaDB doesn't yet support '='TM'' +SELECT to_number('1', 'TM9'); +ERROR 42000: This version of MariaDB doesn't yet support '='TM9'' +SELECT to_number('1', 'TME'); +ERROR 42000: This version of MariaDB doesn't yet support '='TME'' diff --git a/mysql-test/main/func_numconv.test b/mysql-test/main/func_numconv.test new file mode 100644 index 0000000000000..afc7f02edad5a --- /dev/null +++ b/mysql-test/main/func_numconv.test @@ -0,0 +1,953 @@ +--echo # +--echo # MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +--echo # + +--echo # +--echo # to_number() with one argument +--echo # + +--error ER_OPERAND_COLUMNS +SELECT to_number(ROW(1,1)); + +--error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION +SELECT to_number(point(1,1)); + +--echo # With one arg, to_number() works similarly CAST(expr AS DOUBLE) +CREATE TABLE t1 AS SELECT + to_number('123') AS c1, + to_number(123) AS c2, + to_number(123e0) AS c3, + to_number(123.0) AS c4; +SHOW COLUMNS IN t1; +SELECT * FROM t1; +DROP TABLE t1; + +# However, it returns NULL in case of +# empty input, out of range values, trailing garbage + +SELECT to_number('') AS c1; +SELECT to_number('1E+400') AS c1; +SELECT to_number('123x') AS c1; + + +--echo # +--echo # With two args only string+string are allowed +--echo # + +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT to_number(point(1,1), ''); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT to_number('',point(1,1)); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT to_number(1,''); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT to_number('',1); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT to_number(1e0,''); +--error ER_ILLEGAL_PARAMETER_DATA_TYPES2_FOR_OPERATION +SELECT to_number('',1e0); + + +--echo # +--echo # Multiple dollar or B signs are not allowed +--echo # + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '99$99$'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '$9999$'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '$9.99$'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '9$9.9$99EEEE'); + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '99B99B'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'B99B99B'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'B999B'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'B9.99B'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '9B9.9B99EEEE'); + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '.9$9BB$0B'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '.0$0BB$9B'); + +--echo # Comma and G cannot co-exist + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '9G9,9G9'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '9,9G9,9'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '0G0,0G0'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '0,0G0,0'); + + +--echo # +--echo # Dollar and C,L,U cannot co-exist +--echo # + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$U'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$C99'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$L99'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$U99'); + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '0$C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '0$L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '0$U'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '9$C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '9$L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '9$U'); + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'C0$'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'L0$'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'U0$'); +--error ER_WRONG_VALUE_FOR_TYPE + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '.$C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '.$L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '.$U'); +--error ER_WRONG_VALUE_FOR_TYPE + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'D$C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'D$L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'D$U'); +--error ER_WRONG_VALUE_FOR_TYPE + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'V$C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'V$L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'V$U'); +--error ER_WRONG_VALUE_FOR_TYPE + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$.C'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$.L'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$.U'); +--error ER_WRONG_VALUE_FOR_TYPE + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$DC'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$DL'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$DU'); +--error ER_WRONG_VALUE_FOR_TYPE + + +--echo # +--echo # Test that non-constant wrong formats raise a warning (not an error) +--echo # + +CREATE TABLE t1 (fmt VARCHAR(32)); +INSERT INTO t1 VALUES ('$999$'),('C999'); +SELECT to_number('9999', fmt) FROM t1; +DROP TABLE t1; + + +--echo # +--echo # An empty format is allowed and returns NULL +--echo # + +SELECT to_number('', ''); +SELECT to_number('1', ''); + + +--echo # +--echo # B/dollar can go alone, in combination, with FM, and return NULL +--echo # + +SELECT to_number('1', 'B'); +SELECT to_number('1', '$'); +SELECT to_number('1', 'B$'); +SELECT to_number('1', '$B'); + +SELECT to_number('$', '$'); +SELECT to_number('$', 'B$'); +SELECT to_number('$', '$B'); + +SELECT to_number('1', 'FMB'); +SELECT to_number('1', 'FM$'); +SELECT to_number('1', 'FMB$'); +SELECT to_number('1', 'FM$B'); + +SELECT to_number('$', 'FM$'); +SELECT to_number('$', 'FMB$'); +SELECT to_number('$', 'FM$B'); + + +--echo # +--echo # . can go alone +--echo # + +SELECT to_number('.', '.'); +SELECT to_number('1', '.'); + + +--echo # +--echo # 'S', 'MI', 'PR' alone are allowed (optionally with FM), NULL returned +--echo # + +SELECT to_number('-', 'S'); +SELECT to_number('-', 'MI'); +SELECT to_number('<>', 'PR'); +SELECT to_number('-', 'FMS'); +SELECT to_number('-', 'SFM'); +SELECT to_number('-', 'FMMI'); +SELECT to_number('<>', 'FMPR'); + +SELECT to_number('1', 'S'); +SELECT to_number('1', 'MI'); +SELECT to_number('1', 'PR'); +SELECT to_number('1', 'FMMI'); +SELECT to_number('1', 'FMPR'); + + +--echo # +--echo # Integer +--echo # + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'x999'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '999x'); + +--echo # Correct formats + +SELECT to_number('1', '999'); + +SELECT to_number('$12', '$99'); +SELECT to_number('$12', '9$9'); +SELECT to_number('$12', '99$'); + +SELECT to_number('1', 'B99'); +SELECT to_number('1', '9B9'); +SELECT to_number('1', '99B'); + +SELECT to_number('$1', 'B$9'); +SELECT to_number('$1', '9B$'); + +SELECT to_number('$1', '$B9'); +SELECT to_number('$1', '9$B'); + +SELECT to_number('1', '9,9,9,9'); + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '9G9G9G9'); +SELECT to_number('1', '0000'); +SELECT to_number('1', '0,0,0,0'); +SELECT to_number('1', '9999'); +SELECT to_number('1', '9,9,9,9'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '0G0G0G0'); + +SELECT to_number('1', '00009999'); +SELECT to_number('1', '99999999'); +SELECT to_number('1', '0,0,0,0,9,9,9,9'); +SELECT to_number('1', '9,9,9,9,9,9,9,9'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '0G0G0G0G9G9G9G9'); + +SELECT to_number('1', '99990000'); +SELECT to_number('1', '99999999'); +SELECT to_number('1', '9,9,9,9,0,0,0,0'); +SELECT to_number('1', '9,9,9,9,9,9,9,9'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '9G9G9G9G0G0G0G0'); + +SELECT to_number('123456.123456', '999999.999999') AS c1; +SELECT to_number('123,456.123456', '999,999.999999') AS c1; +SELECT to_number('1,2,3,4,5,6.123456', '9,9,9,9,9,9.999999') AS c1; + +--echo # +--echo # Integer: 0 vs 9 +--echo # + +CREATE TABLE t1 (fmt VARCHAR(32)); +INSERT INTO t1 VALUES +('0'),('9'), +('00'),('09'),('90'),('99'), +('000'),('009'),('090'),('099'), ('900'),('909'),('990'),('999'); +CREATE TABLE t2 (sbj VARCHAR(32)); +INSERT INTO t2 VALUES ('0'),('00'),('000'),('0000'); + +--echo # Expect NULL if +--echo # - the subject is shorter than the format, or +--echo # - if there's a format 0 outside of the subject length + +SELECT + fmt, sbj, to_number(sbj,fmt), + IF(length(fmt)=length(sbj) +ORDER BY length(fmt),fmt,sbj; + +DROP TABLE t1, t2; + + +--echo # +--echo # Fraction +--echo # + +SELECT to_number('.', '.'); +SELECT to_number('.', 'B.'); +SELECT to_number('.', 'B.9'); +SELECT to_number('.1', 'B.9'); + +SELECT to_number('1', 'B.'); +SELECT to_number('1', 'B.9'); + + +--echo # +--echo # Fraction + dollar +--echo # + +SELECT to_number('$.', '$.'); +SELECT to_number('1', '$.'); + +SELECT to_number('.1', '.9999'); +SELECT to_number('.1', '.99990000'); +SELECT to_number('$.1', '.9$9B'); + +SELECT to_number('.1', '.0000'); +SELECT to_number('.1', '.00009999'); +SELECT to_number('$.1', '.0$0B'); + +SELECT to_number('1', '$.9'); +SELECT to_number('1', '$.9'); + + +--echo # +--echo # Decimal +--echo # + +SELECT to_number('1', '9999.'); +SELECT to_number('1', '9999.9999'); +SELECT to_number('1', '9999.99990000'); +SELECT to_number('1', '9999.00009999'); + +SELECT to_number('1', '9999.'); +SELECT to_number('1', '9999.9999'); +SELECT to_number('1', '9999.99990000'); +SELECT to_number('1', '9999.00009999'); + +--echo # The subject has more integer digits than the format +SELECT to_number('111.1','9.9'); + +--echo # The subject has more fractional digits than the format +SELECT to_number('1.111','9.9'); + +--echo # Multiple dollar and B prefix flags are not allowed +--error ER_WRONG_VALUE_FOR_TYPE +select to_number('$1','$$9.9'); +--error ER_WRONG_VALUE_FOR_TYPE +select to_number('11','BB9.9'); + +--echo # +--echo # Decimal starting with zeros +--echo # + +CREATE TABLE t1 (num VARCHAR(32), fmt VARCHAR(64)); +INSERT INTO t1 VALUES +('1', '0.999'), +('111', '000.999'), +('111111','000999.999'), +('11111111','00090909.999'); + +SELECT to_number(num, fmt), fmt FROM t1; +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','D')), @fmt FROM t1; +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','V')), @fmt FROM t1; +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','C')), @fmt FROM t1; +SELECT to_number(num, @fmt:=REPLACE(fmt,'.','L')), @fmt FROM t1; + +DROP TABLE t1; + + +--echo # +--echo # Decimal + flags B/dollar + signs +--echo # + +# B/$ can follow a leading sign +SELECT to_number('-1', 'SB'); +SELECT to_number('-$1', 'S$'); +SELECT to_number('-$1', 'SB$'); +SELECT to_number('-$1', 'S$B'); + +# B/$ can be followed by a trailing sign +SELECT to_number('1', 'BS'); +SELECT to_number('1', 'BMI'); +SELECT to_number('1', 'BPR'); +SELECT to_number('1', '$S'); +SELECT to_number('1', '$MI'); +SELECT to_number('1', '$PR'); + +# B/$ can be followed a currency +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BC'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BL'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BU'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BC99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BL99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BU99'); + +# B/$ can be followed a V +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BV'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BV99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '$V'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '$V99'); + +# B/$ can be followed a decimal point +SELECT to_number('1', 'B.'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BD'); +SELECT to_number('1', 'B.99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'BD99'); + +SELECT to_number('1', '$.'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '$D'); +SELECT to_number('1', '$.99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', '$D99'); + + +--echo # +--echo # Number1 (i.e. not starting with zeros) +--echo # + +# Positional_currency+B cannot be followed by ,G +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'CB,999'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'CBG999'); + + +# Correct formats +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C000'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CB999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CB000'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C.'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CD'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CV'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C.99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CD99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CV99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CB.999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CBD999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'CB'); + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L000'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LB999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LB000'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L.'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LD'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LV'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L.99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LD99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LV99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LB.999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LBD999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'LB'); + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U000'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UB999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UB000'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U.'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UD'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UV'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U.99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UD99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UV99'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UB.999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UBD999'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'UB'); + + +--echo # +--echo # Number0: zeros + postfix sign +--echo # + +SELECT to_number('12-', '00S'); +SELECT to_number('12+', '00S'); +SELECT to_number('12-', '00MI'); +SELECT to_number('12 ', '00MI'); +SELECT to_number('<12>', '00PR'); +SELECT to_number(' 12 ', '00PR'); +SELECT to_number('[12]', '00PR'); + +SELECT to_number('<1234>', '999999PR') AS c1; +SELECT to_number(' 1234 ', '999999PR') AS c1; + + +--echo # +--echo # Postfix sign +--echo # + +SELECT to_number('12-', '99S'); +SELECT to_number('12+', '99S'); +SELECT to_number('12-', '99MI'); +SELECT to_number('12 ', '99MI'); +SELECT to_number('<12>', '99PR'); +SELECT to_number(' 12 ', '99PR'); + +--echo # +--echo # Prefix sign +--echo # + +SELECT to_number('-1', 'S'); +SELECT to_number('-1', 'S00'); +SELECT to_number('-12', 'S00'); +SELECT to_number('-1', 'S99'); + +SELECT to_number('1', 'FMS'); +SELECT to_number('-12', 'FMS00'); +SELECT to_number('-12', 'FMS99'); + +SELECT to_number('1', 'SFM'); +SELECT to_number('-12', 'SFM00'); +SELECT to_number('-12', 'SFM99'); + + +--echo # +--echo # Prefix-signed currency +--echo # + +--echo # CLU are not supported yet +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S00.99C'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S99.99L'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S99.99U'); + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S00D99C'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S99D99L'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S99D99U'); + + +SELECT to_number('-$12,345.67', 'S$999,099.99') AS c1; +SELECT to_number('+$12,345.67', 'S$999,099.99') AS c1; +SELECT to_number('-$12,345.67', 'S$999,999.99') AS c1; +SELECT to_number('+$12,345.67', 'S$999,999.99') AS c1; +SELECT to_number('$12,345.67', 'S$999,099.99') AS c1, 'Missing sign' AS comment; + +SELECT to_number('-$45', 'S$999,099.99') AS c1; +SELECT to_number('+$45', 'S$999,099.99') AS c1; +SELECT to_number('$45', 'S$999,099.99') AS c1, 'Missing sign' AS comment; + +SELECT to_number('-$45', 'S$999,999.99') AS c1; +SELECT to_number('+$45', 'S$999,999.99') AS c1; +SELECT to_number('$45', 'S$999,999.99') AS c1, 'Missing sign' AS comment; + +SELECT to_number('+$5', 'S$999,099.99') AS c1; +SELECT to_number('+$45', 'S$999,099.99') AS c1; +SELECT to_number('+$045', 'S$999,099.99') AS c1; +SELECT to_number('+$0,045', 'S$999,099.99') AS c1; +SELECT to_number('+$00,045', 'S$999,099.99') AS c1; +SELECT to_number('+$000,045', 'S$999,099.99') AS c1; +SELECT to_number('+$0000,045', 'S$999,099.99') AS c1; + + +--echo # +--echo # FM +--echo # + +SELECT to_number('1', 'FM'); +SELECT to_number('1', 'FM9'); +SELECT to_number('1,2', 'FM9,9'); +SELECT to_number('1.2', 'FM9.9'); +SELECT to_number('1-', 'FM9S'); +SELECT to_number('-1', 'FMS9'); + +SELECT to_number('12-', 'FM00S'); +SELECT to_number('12-', 'FM99S'); +SELECT to_number('12-', 'FM99S'); +SELECT to_number('12-', 'FM00.99S'); +SELECT to_number('12-', 'FM99.99S'); +SELECT to_number('12-', 'FM99.99S'); +SELECT to_number('12.34-', 'FM00.99S'); +SELECT to_number('12.34-', 'FM99.99S'); +SELECT to_number('12.34-', 'FM99.99S'); + + +--echo # +--echo # Long examples +--echo # + +SELECT to_number('123,456,789','999,999,999') AS c1; +SELECT to_number('111,222,333,444,555','999,999,999,999,999') AS c1; +SELECT to_number('111,222,333,444,555,666,777,888,999', + '999,999,999,999,999,999,999,999,999') AS c1; + + +--echo # +--echo # EEEE specific tests +--echo # + +--echo # EEEE cannot go without any integer digits + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('', 'EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('', '.EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('', '.9EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '.999EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '.9$9EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '.9B9EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', '$EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('1', 'BEEEE'); + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('', 'S.9EEEE'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('', 'S.9EEEES'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('', 'FM.EEEE'); + +--echo # +--echo # EEEE correct formats +--echo # + +--echo # Currency CLU is not supported yet + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C0EEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L0EEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U0EEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'C9EEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'L9EEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'U9EEEE'); + +--echo # +--echo # The following formats are not supported in Oracle. +--echo # However, it works if change C/L/U to dollar sign. +--echo # Looks like a bug in Oracle. +--echo # Anyway, CLU is not supported yet. +--echo # + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S00.99CEEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S99.99LEEEE'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'S99.99UEEEE'); + +--echo # Trailing gargabe: +SELECT to_number('1E+3x', '99EEEE'); +SELECT to_number('$1E+3x', '$99EEEE'); + + +--echo # +--echo # Simple examples with EEEE +--echo # + +SELECT to_number('1', '9EEEE'); +SELECT to_number('1', '9.9EEEE'); +SELECT to_number('1.2', '9.9EEEE'); + +--echo # +--echo # EEEE formats starting with zeros +--echo # + +SELECT to_number('1', '00EEEE'); + +CREATE TABLE t1 (num VARCHAR(32), fmt VARCHAR(64)); +INSERT INTO t1 VALUES +('1', '0.999'), +('111', '000.999'), +('111111','000999.999'), +('11111111','00090909.999'); + +SELECT to_number(num, @fmt:=CONCAT(fmt,'EEEE')), @fmt FROM t1; +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','D'),'EEEE')), @fmt FROM t1; +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','V'),'EEEE')), @fmt FROM t1; +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','C'),'EEEE')), @fmt FROM t1; +SELECT to_number(num, @fmt:=CONCAT(REPLACE(fmt,'.','L'),'EEEE')), @fmt FROM t1; + +DROP TABLE t1; + +--echo # +--echo # B and dollar inside a EEEE format +--echo # + +SELECT to_number('1', 'B0EEEE'); +SELECT to_number('1', 'B9EEEE'); +SELECT to_number('1', 'B0.EEEE'); +SELECT to_number('1', 'B9.EEEE'); +SELECT to_number('1', 'B0.9EEEE'); +SELECT to_number('1', 'B9.9EEEE'); + +SELECT to_number('$1E+1', '$0EEEE'); +SELECT to_number('$1E+1', '$9EEEE'); +SELECT to_number('$1E+1', '$0.EEEE'); +SELECT to_number('$1E+1', '$9.EEEE'); +SELECT to_number('$1.E+1', '$0.EEEE'); +SELECT to_number('$1.E+1', '$9.EEEE'); +SELECT to_number('$1.2E+1', '$0.EEEE'); +SELECT to_number('$1.2E+1', '$9.EEEE'); +SELECT to_number('$1.2E+1', '$0.9EEEE'); +SELECT to_number('$1.2E+1', '$9.9EEEE'); + +SELECT to_number('1', '999EEEE'); +SELECT to_number('1', '999.EEEE'); +SELECT to_number('1', '999.9999EEEE'); + +SELECT to_number ('$1', '9$9EEEE'); +SELECT to_number ('$1', '9$9.EEEE'); + +SELECT to_number('1', '9B9EEEE'); +SELECT to_number('1', '9B9.EEEE'); + + +--echo # +--echo # EEEE formats with prefix and postfix signs and FM +--echo # + +SELECT to_number('1.2E+1-', '99EEEES'); +SELECT to_number('1.2E+1+', '99EEEES'); +SELECT to_number('1.2E+1-', '99EEEEMI'); +SELECT to_number('1.2E+1 ', '99EEEEMI'); +SELECT to_number('<1.2E+1>', '99EEEEPR'); +SELECT to_number(' 1.2E+1 ', '99EEEEPR'); + +SELECT to_number('-12.34E+2', 'S00.99EEEE'); +SELECT to_number('-12.34E+2', 'S99.99EEEE'); + +SELECT to_number('$1.2E+1-', '$9.9EEEES'); +SELECT to_number('$1.2E+1+', '$9.9EEEES'); +SELECT to_number('$1.2E+1-', '$9.9EEEEMI'); +SELECT to_number('$1.2E+1 ', '$9.9EEEEMI'); +SELECT to_number('<$1.2E+1>', '$9.9EEEEPR'); +# Oracle returns an error on ' $1.2E+1 ' +# but works with ' $1.2E+1' in the next +# Looks like a bug in Oracle: +SELECT to_number(' $1.2E+1 ', '$9.9EEEEPR'); + +SELECT to_number('12.34E+2-', 'FM00.99EEEES'); +SELECT to_number('12.34E+2-', 'FM99.99EEEES'); + + +--echo # +--echo # X formats (hexadecimal) +--echo # + +--echo # X cannot co-exist with dollar, B, dec, group, signs, currency + +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '$X'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'BX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'X,X'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XGX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'X.X'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XCX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XLX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XUX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'SX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', '$X'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'CX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'LX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'UX'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'X$'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XC'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XL'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XU'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XMI'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XPR'); +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('0', 'XS'); + + +--echo # +--echo # FM and X can co-exist +--echo # + +SELECT to_number('F', 'FMXXXX'); +SELECT to_number('FF', 'FMXXXX'); +SELECT to_number('FFF', 'FMXXXX'); +SELECT to_number('FFFF', 'FMXXXX'); + + +--echo # +--echo # X simple exaples +--echo # + +SELECT to_number('0', 'X'); +SELECT to_number('20', 'XX'); +SELECT to_number('020', 'XXX'); +SELECT to_number('2020', 'XXXX'); +SELECT to_number('02020', 'XXXXX'); +SELECT to_number('202020', 'XXXXXX'); +SELECT to_number('202020', 'XXXXX'); + + +--echo # +--echo # Zeros + xchain +--echo # + +SELECT to_number('061', '00X'); +SELECT to_number('0061', '00XX'); +SELECT to_number('00061', '00XXX'); +SELECT to_number('000061', '00XXXX'); +SELECT to_number('0000061', '00XXXXX'); +SELECT to_number('00000061', '00XXXXXX'); + +--echo # +--echo # 0 vs X +--echo # + +CREATE TABLE t1 (fmt VARCHAR(32)); +CREATE TABLE t2 (sbj VARCHAR(32)); +DELIMITER $$; +FOR i IN 0..3 DO + INSERT INTO t1 VALUES (CONCAT(REPEAT('0',i), REPEAT('X',4-i))); +END FOR; +$$ +FOR i IN 0..4 DO + INSERT INTO t2 VALUES (REPEAT('1',i)); +END FOR; +$$ +DELIMITER ;$$ +--disable_warnings +SELECT fmt, sbj, to_number(sbj, fmt) AS c1 FROM t1, t2 ORDER BY fmt, sbj; +--enable_warnings +DROP TABLE t1, t2; + + +--echo # +--echo # Format TM is not supported by to_number(), only supported by to_char() +--echo # + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'TM'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'TM9'); +--error ER_NOT_SUPPORTED_YET +SELECT to_number('1', 'TME'); diff --git a/mysql-test/main/func_numconv_debug.result b/mysql-test/main/func_numconv_debug.result new file mode 100644 index 0000000000000..880b283669c1a --- /dev/null +++ b/mysql-test/main/func_numconv_debug.result @@ -0,0 +1,125 @@ +# +# MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +# +SET debug_dbug='+d,numconv_format'; +SELECT to_number('', '9') AS c; +c +0 +Warnings: +Note 1105 A='9' +SELECT to_number('', '0') AS c; +c +0 +Warnings: +Note 1105 A='0' +SELECT to_number('', '9.9') AS c; +c +0 +Warnings: +Note 1105 A='9[.]9' +SELECT to_number('', '0.0') AS c; +c +0 +Warnings: +Note 1105 A='0[.]0' +SELECT to_number('', '.9') AS c; +c +0 +Warnings: +Note 1105 A='[.]9' +SELECT to_number('', '.0') AS c; +c +0 +Warnings: +Note 1105 A='[.]0' +SELECT to_number('', '9$9') AS c; +c +0 +Warnings: +Note 1105 A='9$9' +SELECT to_number('', '0$0') AS c; +c +0 +Warnings: +Note 1105 A='0$0' +SELECT to_number('', '9B9') AS c; +c +0 +Warnings: +Note 1105 A='9B9' +SELECT to_number('', '0B0') AS c; +c +0 +Warnings: +Note 1105 A='0B0' +SELECT to_number('', '9.9$') AS c; +c +0 +Warnings: +Note 1105 A='9[.]9$' +SELECT to_number('', '9.9B') AS c; +c +0 +Warnings: +Note 1105 A='9[.]9B' +SELECT to_number('', '9C9') AS c; +ERROR 42000: This version of MariaDB doesn't yet support '='9C9'' +SHOW WARNINGS; +Level Code Message +Note 1105 A='9[C]9' +Error 1235 This version of MariaDB doesn't yet support '='9C9'' +SELECT to_number('', '9.9C') AS c; +ERROR 42000: This version of MariaDB doesn't yet support '='9.9C'' +SHOW WARNINGS; +Level Code Message +Note 1105 A='9[.]9'RC='C' +Error 1235 This version of MariaDB doesn't yet support '='9.9C'' +SELECT to_number('', '$9') AS c; +c +0 +Warnings: +Note 1105 CFl='$'A='9' +SELECT to_number('', '$0') AS c; +c +0 +Warnings: +Note 1105 CFl='$'A='0' +SELECT to_number('', 'B9') AS c; +c +0 +Warnings: +Note 1105 CFl='B'A='9' +SELECT to_number('', 'B0') AS c; +c +0 +Warnings: +Note 1105 CFl='B'A='0' +SELECT to_number('', 'C9') AS c; +ERROR 42000: This version of MariaDB doesn't yet support '='C9'' +SHOW WARNINGS; +Level Code Message +Note 1105 LC='C'A='9' +Error 1235 This version of MariaDB doesn't yet support '='C9'' +SELECT to_number('', 'L0') AS c; +ERROR 42000: This version of MariaDB doesn't yet support '='L0'' +SHOW WARNINGS; +Level Code Message +Note 1105 LC='L'A='0' +Error 1235 This version of MariaDB doesn't yet support '='L0'' +SELECT to_number('', '9PR') AS c; +c +0 +Warnings: +Note 1105 A='9'RS='PR' +SELECT to_number('', 'FMS9') AS c; +c +0 +Warnings: +Note 1105 FFl='FM'LS='S'A='9' +SELECT to_number('', 'FMTM') AS c; +ERROR 42000: This version of MariaDB doesn't yet support '='FMTM'' +SHOW WARNINGS; +Level Code Message +Note 1105 FFl='FM'A=''TM='TM' +Error 1235 This version of MariaDB doesn't yet support '='FMTM'' +SET debug_dbug=DEFAULT; diff --git a/mysql-test/main/func_numconv_debug.test b/mysql-test/main/func_numconv_debug.test new file mode 100644 index 0000000000000..7af8fb3125bbe --- /dev/null +++ b/mysql-test/main/func_numconv_debug.test @@ -0,0 +1,67 @@ +--source include/have_debug.inc + +--echo # +--echo # MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +--echo # + +SET debug_dbug='+d,numconv_format'; + +# +# Approximate::print +# + +SELECT to_number('', '9') AS c; +SELECT to_number('', '0') AS c; +SELECT to_number('', '9.9') AS c; +SELECT to_number('', '0.0') AS c; +SELECT to_number('', '.9') AS c; +SELECT to_number('', '.0') AS c; + +SELECT to_number('', '9$9') AS c; +SELECT to_number('', '0$0') AS c; +SELECT to_number('', '9B9') AS c; +SELECT to_number('', '0B0') AS c; + +SELECT to_number('', '9.9$') AS c; +SELECT to_number('', '9.9B') AS c; + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('', '9C9') AS c; +SHOW WARNINGS; + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('', '9.9C') AS c; +SHOW WARNINGS; + + +# +# Unsigned_currency::print +# + +SELECT to_number('', '$9') AS c; +SELECT to_number('', '$0') AS c; +SELECT to_number('', 'B9') AS c; +SELECT to_number('', 'B0') AS c; + +--error ER_NOT_SUPPORTED_YET +SELECT to_number('', 'C9') AS c; +SHOW WARNINGS; +--error ER_NOT_SUPPORTED_YET +SELECT to_number('', 'L0') AS c; +SHOW WARNINGS; + + +# +# Currency_with_postfix_sign::print +# +SELECT to_number('', '9PR') AS c; + +# +# Format::print +# +SELECT to_number('', 'FMS9') AS c; +--error ER_NOT_SUPPORTED_YET +SELECT to_number('', 'FMTM') AS c; +SHOW WARNINGS; + +SET debug_dbug=DEFAULT; diff --git a/mysql-test/main/func_numconv_format.result b/mysql-test/main/func_numconv_format.result new file mode 100644 index 0000000000000..b0257028473fe --- /dev/null +++ b/mysql-test/main/func_numconv_format.result @@ -0,0 +1,100 @@ +SET @saved_debug_dbug= @@debug_dbug; +SET @@debug_dbug='+d,numconv_format'; +# +# MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +# +CREATE FUNCTION bad(fmt VARCHAR(128)) RETURNS VARCHAR(128) +BEGIN +IF fmt RLIKE '(FM.*FM|B.*B|EEEE.*EEEE|[CLU$].*[CLU$]|[.VD].*[.VD]|(S|MI|PR).*(S|MI|PR))' + THEN +RETURN 'FM/B/currency/dec/sign cannot repeat'; +END IF; +IF fmt RLIKE '[09XBCDLUV,G.$].*FM' THEN RETURN 'Unexpected + FM'; END IF; +IF fmt RLIKE '^[^09]*([.DV].*)?EEEE' THEN RETURN 'EEEE with no int digits #1'; END IF; +IF fmt RLIKE '^(FM|S)?[$B]+[CLU][0-9]*EEEE' THEN RETURN 'EEEE with no int digits #2'; END IF; +IF fmt RLIKE '.*EEEE.*(FM|[B09X.DV,GLCU$V])' THEN RETURN 'EEEE + unexpected'; END IF; +IF fmt RLIKE '^([$BC.DLUVS]|FM)EEEE' THEN RETURN '^Unexpected + EEEE immediately'; END IF; +IF fmt RLIKE '(G.*,|,.*G)' THEN RETURN 'comma and G cannot co-exist'; END IF; +IF fmt RLIKE '^([$B]|[^09]|)*[,G]' THEN RETURN 'group with no int digits'; END IF; +IF fmt RLIKE '[.DV].*[,G]' THEN RETURN 'dec + group'; END IF; +IF fmt RLIKE '(FM|[S.DCLUV])[,G]' THEN RETURN 'Unexpected + group immediately'; END IF; +IF fmt RLIKE '(MI|PR).+' THEN RETURN 'Trailing sign + something'; END IF; +IF fmt RLIKE '[$09BVCLUX.D,G].*TM' THEN RETURN 'Unexpected + TM'; END IF; +IF fmt RLIKE 'TM([^E9].*|[E9].+)' THEN RETURN 'TMx + something'; END IF; +IF fmt RLIKE '([9BCDLUVS.,G$]|TM).*X' THEN RETURN 'Unexpected + X'; END IF; +IF fmt RLIKE 'X[^X]' THEN RETURN 'X + unexpected'; END IF; +-- Bad combinations consisting of three elements +IF fmt RLIKE '[.VD].*[CLU].*[09]' THEN RETURN 'Dec + CLU + digit'; END IF; +IF fmt RLIKE '[CLUV09.BD$].*[S].*([09$BVCLU.D]|EEEE)' THEN RETURN 'Trailing S sign + unexpected'; END IF; +IF fmt RLIKE '[B09].*[CLUV].*[,GV.D]' THEN RETURN 'CLUV as dec + group/dec'; END IF; +IF fmt RLIKE '[.DV].*[CLU].*[B]' THEN RETURN 'CLU as trailing currency + B'; END IF; +RETURN ''; +END; +$$ +CREATE TABLE t1 (fmt VARCHAR(32)); +INSERT INTO t1 VALUES (''); +INSERT INTO t1 VALUES ('FM') /* leading flags */; +INSERT INTO t1 VALUES ('.'),('D'),('V') /* dec */; +INSERT INTO t1 VALUES (','),('G') /* group */; +INSERT INTO t1 VALUES ('$'),('B') /* inline flags */; +INSERT INTO t1 VALUES ('C'),('L'),('U') /* currency */; +INSERT INTO t1 VALUES ('S') /* sign */; +INSERT INTO t1 VALUES ('MI'),('PR') /* trailing sign */; +INSERT INTO t1 VALUES ('TM'),('TM9'),('TME') /* TM formats */; +INSERT INTO t1 VALUES ('0'),('9'),('X') /* digits */; +INSERT INTO t1 VALUES ('EEEE') /* approximate format */; +SELECT fmt FROM t1 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +fmt +SELECT fmt FROM t1 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +fmt +CREATE VIEW v2 AS SELECT CONCAT(t1.fmt, t2.fmt) AS fmt FROM t1 t1, t1 t2; +SELECT fmt FROM v2 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +fmt +SELECT fmt FROM v2 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +fmt +DROP VIEW v2; +CREATE VIEW v3 AS SELECT CONCAT(t1.fmt, t2.fmt, t2.fmt) AS fmt FROM t1 t1, t1 t2, t1 t3; +SELECT fmt FROM v3 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +fmt +SELECT fmt FROM v3 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +fmt +DROP VIEW v3; +DROP TABLE t1; +CREATE TABLE t4 (fmt VARCHAR(32)); +INSERT INTO t4 VALUES ('.'),('D'),('V') /* dec */; +INSERT INTO t4 VALUES (','),('G') /* group */; +INSERT INTO t4 VALUES ('$'),('B') /* inline flags */; +INSERT INTO t4 VALUES ('C') /* currency - simplified */; +INSERT INTO t4 VALUES ('0'),('9'),('X') /* digits */; +CREATE VIEW v4 AS +SELECT CONCAT(t1.fmt, t2.fmt, t3.fmt,t4.fmt) AS fmt +FROM t4 t1, t4 t2, t4 t3, t4 t4; +SELECT fmt FROM v4 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +fmt +SELECT fmt FROM v4 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +fmt +DROP VIEW v4; +DROP TABLE t4; +CREATE TABLE t4 (fmt VARCHAR(32)); +INSERT INTO t4 VALUES (''); +INSERT INTO t4 VALUES ('FM') /* leading flags */; +INSERT INTO t4 VALUES ('.') /* dec - simplified */; +INSERT INTO t4 VALUES (',') /* group - simplified */; +INSERT INTO t4 VALUES ('$'),('B') /* inline flags */; +INSERT INTO t4 VALUES ('C') /* currency - simplified */; +INSERT INTO t4 VALUES ('S') /* sign */; +INSERT INTO t4 VALUES ('MI') /* trailing sign - simplified */; +INSERT INTO t4 VALUES ('TM9') /* TM formats - simplified */; +INSERT INTO t4 VALUES ('9'),('X') /* digits - simplified */; +INSERT INTO t4 VALUES ('EEEE') /* approximate format */; +CREATE VIEW v4 AS +SELECT CONCAT(t1.fmt, t2.fmt, t3.fmt,t4.fmt) AS fmt +FROM t4 t1, t4 t2, t4 t3, t4 t4; +SELECT fmt FROM v4 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +fmt +SELECT fmt FROM v4 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +fmt +DROP VIEW v4; +DROP TABLE t4; +DROP FUNCTION bad; +SET debug_dbug= @saved_debug_dbug; diff --git a/mysql-test/main/func_numconv_format.test b/mysql-test/main/func_numconv_format.test new file mode 100644 index 0000000000000..204a914bfe7de --- /dev/null +++ b/mysql-test/main/func_numconv_format.test @@ -0,0 +1,139 @@ +--source include/have_debug.inc + +SET @saved_debug_dbug= @@debug_dbug; +SET @@debug_dbug='+d,numconv_format'; + + +--echo # +--echo # MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +--echo # + +# This function detects if the passed format is correct or wrong + +DELIMITER $$; +CREATE FUNCTION bad(fmt VARCHAR(128)) RETURNS VARCHAR(128) +BEGIN + + IF fmt RLIKE '(FM.*FM|B.*B|EEEE.*EEEE|[CLU$].*[CLU$]|[.VD].*[.VD]|(S|MI|PR).*(S|MI|PR))' + THEN + RETURN 'FM/B/currency/dec/sign cannot repeat'; + END IF; + + IF fmt RLIKE '[09XBCDLUV,G.$].*FM' THEN RETURN 'Unexpected + FM'; END IF; + + IF fmt RLIKE '^[^09]*([.DV].*)?EEEE' THEN RETURN 'EEEE with no int digits #1'; END IF; + IF fmt RLIKE '^(FM|S)?[$B]+[CLU][0-9]*EEEE' THEN RETURN 'EEEE with no int digits #2'; END IF; + IF fmt RLIKE '.*EEEE.*(FM|[B09X.DV,GLCU$V])' THEN RETURN 'EEEE + unexpected'; END IF; + IF fmt RLIKE '^([$BC.DLUVS]|FM)EEEE' THEN RETURN '^Unexpected + EEEE immediately'; END IF; + + IF fmt RLIKE '(G.*,|,.*G)' THEN RETURN 'comma and G cannot co-exist'; END IF; + IF fmt RLIKE '^([$B]|[^09]|)*[,G]' THEN RETURN 'group with no int digits'; END IF; + IF fmt RLIKE '[.DV].*[,G]' THEN RETURN 'dec + group'; END IF; + IF fmt RLIKE '(FM|[S.DCLUV])[,G]' THEN RETURN 'Unexpected + group immediately'; END IF; + + IF fmt RLIKE '(MI|PR).+' THEN RETURN 'Trailing sign + something'; END IF; + + IF fmt RLIKE '[$09BVCLUX.D,G].*TM' THEN RETURN 'Unexpected + TM'; END IF; + IF fmt RLIKE 'TM([^E9].*|[E9].+)' THEN RETURN 'TMx + something'; END IF; + + IF fmt RLIKE '([9BCDLUVS.,G$]|TM).*X' THEN RETURN 'Unexpected + X'; END IF; + IF fmt RLIKE 'X[^X]' THEN RETURN 'X + unexpected'; END IF; + + -- Bad combinations consisting of three elements + IF fmt RLIKE '[.VD].*[CLU].*[09]' THEN RETURN 'Dec + CLU + digit'; END IF; + IF fmt RLIKE '[CLUV09.BD$].*[S].*([09$BVCLU.D]|EEEE)' THEN RETURN 'Trailing S sign + unexpected'; END IF; + IF fmt RLIKE '[B09].*[CLUV].*[,GV.D]' THEN RETURN 'CLUV as dec + group/dec'; END IF; + IF fmt RLIKE '[.DV].*[CLU].*[B]' THEN RETURN 'CLU as trailing currency + B'; END IF; + + RETURN ''; +END; +$$ +DELIMITER ;$$ + + +# Populate t1 with all known format elements + +CREATE TABLE t1 (fmt VARCHAR(32)); +INSERT INTO t1 VALUES (''); +INSERT INTO t1 VALUES ('FM') /* leading flags */; +INSERT INTO t1 VALUES ('.'),('D'),('V') /* dec */; +INSERT INTO t1 VALUES (','),('G') /* group */; +INSERT INTO t1 VALUES ('$'),('B') /* inline flags */; +INSERT INTO t1 VALUES ('C'),('L'),('U') /* currency */; +INSERT INTO t1 VALUES ('S') /* sign */; +INSERT INTO t1 VALUES ('MI'),('PR') /* trailing sign */; +INSERT INTO t1 VALUES ('TM'),('TM9'),('TME') /* TM formats */; +INSERT INTO t1 VALUES ('0'),('9'),('X') /* digits */; +INSERT INTO t1 VALUES ('EEEE') /* approximate format */; + +SELECT fmt FROM t1 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +--disable_warnings +SELECT fmt FROM t1 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +--enable_warnings + +CREATE VIEW v2 AS SELECT CONCAT(t1.fmt, t2.fmt) AS fmt FROM t1 t1, t1 t2; +SELECT fmt FROM v2 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +--disable_warnings +SELECT fmt FROM v2 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +--enable_warnings +DROP VIEW v2; + +CREATE VIEW v3 AS SELECT CONCAT(t1.fmt, t2.fmt, t2.fmt) AS fmt FROM t1 t1, t1 t2, t1 t3; +SELECT fmt FROM v3 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +--disable_warnings +SELECT fmt FROM v3 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +--enable_warnings +DROP VIEW v3; + +DROP TABLE t1; + +# Populate t4 only with decimal number body format elements + +CREATE TABLE t4 (fmt VARCHAR(32)); +INSERT INTO t4 VALUES ('.'),('D'),('V') /* dec */; +INSERT INTO t4 VALUES (','),('G') /* group */; +INSERT INTO t4 VALUES ('$'),('B') /* inline flags */; +INSERT INTO t4 VALUES ('C') /* currency - simplified */; +INSERT INTO t4 VALUES ('0'),('9'),('X') /* digits */; + +CREATE VIEW v4 AS +SELECT CONCAT(t1.fmt, t2.fmt, t3.fmt,t4.fmt) AS fmt +FROM t4 t1, t4 t2, t4 t3, t4 t4; + +SELECT fmt FROM v4 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +--disable_warnings +SELECT fmt FROM v4 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +--enable_warnings +DROP VIEW v4; +DROP TABLE t4; + + +# Populate t4 only with *some* known format elements, for performance purposes + +CREATE TABLE t4 (fmt VARCHAR(32)); +INSERT INTO t4 VALUES (''); +INSERT INTO t4 VALUES ('FM') /* leading flags */; +INSERT INTO t4 VALUES ('.') /* dec - simplified */; +INSERT INTO t4 VALUES (',') /* group - simplified */; +INSERT INTO t4 VALUES ('$'),('B') /* inline flags */; +INSERT INTO t4 VALUES ('C') /* currency - simplified */; +INSERT INTO t4 VALUES ('S') /* sign */; +INSERT INTO t4 VALUES ('MI') /* trailing sign - simplified */; +INSERT INTO t4 VALUES ('TM9') /* TM formats - simplified */; +INSERT INTO t4 VALUES ('9'),('X') /* digits - simplified */; +INSERT INTO t4 VALUES ('EEEE') /* approximate format */; + +CREATE VIEW v4 AS +SELECT CONCAT(t1.fmt, t2.fmt, t3.fmt,t4.fmt) AS fmt +FROM t4 t1, t4 t2, t4 t3, t4 t4; + +SELECT fmt FROM v4 WHERE bad(fmt)='' AND to_number('1',fmt) IS NULL; +--disable_warnings +SELECT fmt FROM v4 WHERE bad(fmt)<>'' AND to_number('1',fmt) IS NOT NULL; +--enable_warnings +DROP VIEW v4; +DROP TABLE t4; + +DROP FUNCTION bad; + +SET debug_dbug= @saved_debug_dbug; diff --git a/mysql-test/main/func_numconv_ucs2.result b/mysql-test/main/func_numconv_ucs2.result new file mode 100644 index 0000000000000..7b463378fcaeb --- /dev/null +++ b/mysql-test/main/func_numconv_ucs2.result @@ -0,0 +1,58 @@ +# +# MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +# +SET NAMES utf8mb4; +SELECT to_number('$123-', CONVERT('$999S' USING ucs2)) AS c1; +c1 +-123 +SELECT to_number('$123-', CONVERT('$999Š' USING ucs2)) AS c1; +ERROR HY000: Incorrect value: 'Š' for function to_number +SELECT to_number(CONVERT('$123-' USING ucs2), '$999S') AS c1; +c1 +-123 +SELECT to_number(CONVERT('$123-' USING ucs2), CONVERT('$999S' USING ucs2)) AS c1; +c1 +-123 +SELECT to_number(CONVERT('GarbageŠ' USING ucs2), CONVERT('$999S' USING ucs2)) AS c1; +c1 +NULL +Warnings: +Warning 1411 Incorrect ='$999S' value: 'GarbageŠ' for function to_number +CREATE TABLE t1 (fmt VARCHAR(32) CHARACTER SET ucs2); +INSERT INTO t1 VALUES ('$999S'), ('$999MI'), ('$999Š'); +SELECT fmt, to_number('$123-', fmt) AS c1 FROM t1; +fmt c1 +$999S -123 +$999MI -123 +$999Š NULL +Warnings: +Warning 1411 Incorrect value: 'Š' for function to_number +SELECT fmt, to_number('GarbageŠ', fmt) AS c1 FROM t1; +fmt c1 +$999S NULL +$999MI NULL +$999Š NULL +Warnings: +Warning 1411 Incorrect ='$999S' value: 'GarbageŠ' for function to_number +Warning 1411 Incorrect ='$999MI' value: 'GarbageŠ' for function to_number +Warning 1411 Incorrect value: 'Š' for function to_number +DROP TABLE t1; +CREATE TABLE t1 (fmt VARCHAR(32) CHARACTER SET ucs2); +INSERT INTO t1 VALUES ('$999S'), ('$999MI'), ('$999Š'); +SELECT fmt, to_number(CONVERT('$123-' USING ucs2), fmt) AS c1 FROM t1; +fmt c1 +$999S -123 +$999MI -123 +$999Š NULL +Warnings: +Warning 1411 Incorrect value: 'Š' for function to_number +SELECT fmt, to_number(CONVERT('GarbageŠ' USING ucs2), fmt) AS c1 FROM t1; +fmt c1 +$999S NULL +$999MI NULL +$999Š NULL +Warnings: +Warning 1411 Incorrect ='$999S' value: 'GarbageŠ' for function to_number +Warning 1411 Incorrect ='$999MI' value: 'GarbageŠ' for function to_number +Warning 1411 Incorrect value: 'Š' for function to_number +DROP TABLE t1; diff --git a/mysql-test/main/func_numconv_ucs2.test b/mysql-test/main/func_numconv_ucs2.test new file mode 100644 index 0000000000000..86553ebcc7e36 --- /dev/null +++ b/mysql-test/main/func_numconv_ucs2.test @@ -0,0 +1,38 @@ +--source include/have_ucs2.inc + +--echo # +--echo # MDEV-20022 sql_mode="oracle" does not support TO_NUMBER() function +--echo # + +SET NAMES utf8mb4; + +# Constant UCS2 format +SELECT to_number('$123-', CONVERT('$999S' USING ucs2)) AS c1; + +# Make sure the error is readable +--error ER_WRONG_VALUE_FOR_TYPE +SELECT to_number('$123-', CONVERT('$999Š' USING ucs2)) AS c1; + +# UCS2 subject + utf8mb4 format +SELECT to_number(CONVERT('$123-' USING ucs2), '$999S') AS c1; + +# UCS2 subject + UCS2 format +SELECT to_number(CONVERT('$123-' USING ucs2), CONVERT('$999S' USING ucs2)) AS c1; + +# UCS2 subject + UCS2 format - check the warning: +SELECT to_number(CONVERT('GarbageŠ' USING ucs2), CONVERT('$999S' USING ucs2)) AS c1; + + +# utf8mb4 subject + non-constant UCS2 format +CREATE TABLE t1 (fmt VARCHAR(32) CHARACTER SET ucs2); +INSERT INTO t1 VALUES ('$999S'), ('$999MI'), ('$999Š'); +SELECT fmt, to_number('$123-', fmt) AS c1 FROM t1; +SELECT fmt, to_number('GarbageŠ', fmt) AS c1 FROM t1; +DROP TABLE t1; + +# UCS2 subject + non-constant UCS2 format +CREATE TABLE t1 (fmt VARCHAR(32) CHARACTER SET ucs2); +INSERT INTO t1 VALUES ('$999S'), ('$999MI'), ('$999Š'); +SELECT fmt, to_number(CONVERT('$123-' USING ucs2), fmt) AS c1 FROM t1; +SELECT fmt, to_number(CONVERT('GarbageŠ' USING ucs2), fmt) AS c1 FROM t1; +DROP TABLE t1; diff --git a/mysql-test/main/func_regexp_pcre.result b/mysql-test/main/func_regexp_pcre.result index cbf921293f4db..bfb80943fb0c2 100644 --- a/mysql-test/main/func_regexp_pcre.result +++ b/mysql-test/main/func_regexp_pcre.result @@ -791,7 +791,7 @@ SELECT 'AB' RLIKE 'A# this is a comment\nB'; 1 SET default_regex_flags=DEFAULT; SELECT 'Aq' RLIKE 'A\\q'; -ERROR 42000: Regex error 'unrecognized character follows \ at offset 2' +ERROR 42000: Regex error 'unrecognized character follows \ at offset 3' SET default_regex_flags='EXTRA'; SELECT 'A' RLIKE 'B'; 'A' RLIKE 'B' diff --git a/mysql-test/main/func_regexp_pcre.test b/mysql-test/main/func_regexp_pcre.test index 1c89112ee8f95..ac934db5d8781 100644 --- a/mysql-test/main/func_regexp_pcre.test +++ b/mysql-test/main/func_regexp_pcre.test @@ -382,6 +382,8 @@ SELECT 'AB' RLIKE 'A B'; SELECT 'AB' RLIKE 'A# this is a comment\nB'; SET default_regex_flags=DEFAULT; +# pcre2 versions differ in the reported error offset for invalid escapes +--replace_regex /offset 2/offset 3/ --error ER_REGEXP_ERROR SELECT 'Aq' RLIKE 'A\\q'; diff --git a/mysql-test/main/func_rollback.result b/mysql-test/main/func_rollback.result index 91151302a0679..ccc6f2b2ecf6d 100644 --- a/mysql-test/main/func_rollback.result +++ b/mysql-test/main/func_rollback.result @@ -446,7 +446,7 @@ INSERT INTO t1_child SET f1 = 2, f2 = 2; RETURN 1; END// SELECT f1_two_inserts(); -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1_child`, CONSTRAINT `t1_child_ibfk_1` FOREIGN KEY (`f1`) REFERENCES `t1_parent` (`f1`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t1_child`, CONSTRAINT `1` FOREIGN KEY (`f1`) REFERENCES `t1_parent` (`f1`)) SELECT * FROM t1_child; f1 f2 DROP TABLE t1_child; diff --git a/mysql-test/main/func_str.result b/mysql-test/main/func_str.result index 5c89b9aa6b45a..5507a13d6a92e 100644 --- a/mysql-test/main/func_str.result +++ b/mysql-test/main/func_str.result @@ -5415,8 +5415,14 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci DROP TABLE t1; # -# End of 10.6 tests +# MDEV-37947 Item_func_hex doesn't check for max_allowed_packet # +select hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex('\\'))))))))))))))))))))))))))))))))))))))))))))) as x; +x +NULL +Warnings: +Warning 1301 Result of hex() was larger than max_allowed_packet (16777216) - truncated +# End of 10.6 tests # # MDEV-25704 Function random_bytes # @@ -5624,8 +5630,27 @@ DROP TABLE t2; DROP TABLE t1; SET sql_mode=DEFAULT; # -# End of 10.11 tests +# MDEV-37740 LOCATE(X,Y,NULL) is not NULL # +select locate(1,2,NULL); +locate(1,2,NULL) +NULL +# +# MDEV-37835 mysqli silently trims each json_arrayagg result to modulo 64KB +# +select group_concat(v) from ( select '$a' as v union all select '$b' as v) t; +group_concat(v) +a...aaaaa,b...bbbbb +# +# MDEV-38233 Inconsistent results for make_set of cast +# +create table t1 (c1 int); +insert into t1 values (9067); +select cast(make_set(3, cast(c1 as binary), 0) as char) from t1; +cast(make_set(3, cast(c1 as binary), 0) as char) +9067,0 +drop table t1; +# End of 10.11 tests # # MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm # diff --git a/mysql-test/main/func_str.test b/mysql-test/main/func_str.test index 11fbac20136b7..f72096bd31f99 100644 --- a/mysql-test/main/func_str.test +++ b/mysql-test/main/func_str.test @@ -2451,8 +2451,11 @@ SHOW CREATE TABLE t1; DROP TABLE t1; --echo # ---echo # End of 10.6 tests +--echo # MDEV-37947 Item_func_hex doesn't check for max_allowed_packet --echo # +select hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex(hex('\\'))))))))))))))))))))))))))))))))))))))))))))) as x; + +--echo # End of 10.6 tests --echo # --echo # MDEV-25704 Function random_bytes @@ -2576,8 +2579,27 @@ DROP TABLE t1; SET sql_mode=DEFAULT; --echo # ---echo # End of 10.11 tests +--echo # MDEV-37740 LOCATE(X,Y,NULL) is not NULL +--echo # +select locate(1,2,NULL); + +--echo # +--echo # MDEV-37835 mysqli silently trims each json_arrayagg result to modulo 64KB --echo # +let $a=`select repeat('a', 65540)`; +let $b=`select repeat('b', 65540)`; +replace_regex /a{65535}/a.../ /b{65535}/b.../; +evalp select group_concat(v) from ( select '$a' as v union all select '$b' as v) t; + +--echo # +--echo # MDEV-38233 Inconsistent results for make_set of cast +--echo # +create table t1 (c1 int); +insert into t1 values (9067); +select cast(make_set(3, cast(c1 as binary), 0) as char) from t1; +drop table t1; + +--echo # End of 10.11 tests --echo # --echo # MDEV-9069 extend AES_ENCRYPT() and AES_DECRYPT() to support IV and the algorithm diff --git a/mysql-test/main/func_time.result b/mysql-test/main/func_time.result index 65c40debf03ea..d80fae09562a4 100644 --- a/mysql-test/main/func_time.result +++ b/mysql-test/main/func_time.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; set time_zone="+03:00"; select from_days(to_days("960101")),to_days(960201)-to_days("19960101"),to_days(date_add(curdate(), interval 1 day))-to_days(curdate()),weekday("1997-11-29"); from_days(to_days("960101")) to_days(960201)-to_days("19960101") to_days(date_add(curdate(), interval 1 day))-to_days(curdate()) weekday("1997-11-29") @@ -501,12 +500,12 @@ SELECT month(updated) from t1; month(updated) NULL Warnings: -Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`updated` at row 1 SELECT year(updated) from t1; year(updated) NULL Warnings: -Warning 1292 Incorrect datetime value: '' +Warning 1292 Incorrect datetime value: '' for column `test`.`t1`.`updated` at row 1 drop table t1; create table t1 (d date, dt datetime, t timestamp, c char(10)); insert into t1 values ("0000-00-00", "0000-00-00", "0000-00-00", "0000-00-00"); @@ -515,7 +514,7 @@ dayofyear("0000-00-00") dayofyear(d) dayofyear(dt) dayofyear(t) dayofyear(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select dayofmonth("0000-00-00"),dayofmonth(d),dayofmonth(dt),dayofmonth(t),dayofmonth(c) from t1; dayofmonth("0000-00-00") dayofmonth(d) dayofmonth(dt) dayofmonth(t) dayofmonth(c) 0 0 0 0 0 @@ -530,7 +529,7 @@ week("0000-00-00") week(d) week(dt) week(t) week(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select year("0000-00-00"),year(d),year(dt),year(t),year(c) from t1; year("0000-00-00") year(d) year(dt) year(t) year(c) 0 0 0 0 0 @@ -539,13 +538,13 @@ yearweek("0000-00-00") yearweek(d) yearweek(dt) yearweek(t) yearweek(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select to_days("0000-00-00"),to_days(d),to_days(dt),to_days(t),to_days(c) from t1; to_days("0000-00-00") to_days(d) to_days(dt) to_days(t) to_days(c) NULL NULL NULL NULL NULL Warnings: Warning 1292 Incorrect datetime value: '0000-00-00' -Warning 1292 Incorrect datetime value: '0000-00-00' +Warning 1292 Incorrect datetime value: '0000-00-00' for column `test`.`t1`.`c` at row 1 select extract(MONTH FROM "0000-00-00"),extract(MONTH FROM d),extract(MONTH FROM dt),extract(MONTH FROM t),extract(MONTH FROM c) from t1; extract(MONTH FROM "0000-00-00") extract(MONTH FROM d) extract(MONTH FROM dt) extract(MONTH FROM t) extract(MONTH FROM c) 0 0 0 0 0 @@ -1407,9 +1406,9 @@ SELECT COUNT(*) FROM t1 GROUP BY TIME_TO_SEC(a); COUNT(*) 2 Warnings: -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '' -Warning 1292 Incorrect time value: '' +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 1 +Warning 1292 Incorrect time value: '' for column `test`.`t1`.`a` at row 2 DROP TABLE t1; # # Bug#11766112 59151:UNINITIALIZED VALUES IN EXTRACT_DATE_TIME WITH STR_TO_DATE(SPACE(..) ... @@ -6453,12 +6452,23 @@ a NULL SET @@time_zone=DEFAULT; DROP TABLE t1; -# # End of 10.5 tests # +# MDEV-38006 Inconsistent behaviors when casting into time # -# Start of 11.6 tests -# +create table t1 (c1 char(20), c2 mediumint unsigned); +insert into t1 values (9430886, 9430886), (9430816, 9430816); +select cast(c1 as time), cast(c2 as time) from t1; +cast(c1 as time) cast(c2 as time) +NULL NULL +838:59:59 838:59:59 +Warnings: +Warning 1292 Incorrect time value: '9430886' for column `test`.`t1`.`c1` at row 1 +Warning 1292 Incorrect time value: '9430886' for column `test`.`t1`.`c2` at row 1 +Warning 1292 Incorrect time value: '9430816' for column `test`.`t1`.`c1` at row 2 +Warning 1292 Incorrect time value: '9430816' for column `test`.`t1`.`c2` at row 2 +drop table t1; +# End of 10.11 tests # # MDEV-34829 LOCALTIME returns a wrong data type # @@ -6482,13 +6492,8 @@ LOCALTIME 14:47:00 DROP TABLE t1; SET timestamp=DEFAULT; -# # End of 11.6 tests # -# -# Start of 11.7 tests -# -# # MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?] # CREATE TABLE t1 (localtimestamp TIMESTAMP); @@ -6599,6 +6604,4 @@ t1 CREATE TABLE `t1` ( `from_unixtime(1000000.12345678912)` timestamp(6) NULL DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci DROP TABLE t1; -# # End of 11.7 tests -# diff --git a/mysql-test/main/func_time.test b/mysql-test/main/func_time.test index ba7c4c09eb08c..c0e5bad2fc47a 100644 --- a/mysql-test/main/func_time.test +++ b/mysql-test/main/func_time.test @@ -1,9 +1,6 @@ # # time functions # ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings # Set timezone to GMT-3, to make it possible to use "interval 3 hour" set time_zone="+03:00"; @@ -3286,13 +3283,17 @@ SELECT UNIX_TIMESTAMP(MAX(a)) AS a FROM t1; SET @@time_zone=DEFAULT; DROP TABLE t1; ---echo # --echo # End of 10.5 tests ---echo # --echo # ---echo # Start of 11.6 tests +--echo # MDEV-38006 Inconsistent behaviors when casting into time --echo # +create table t1 (c1 char(20), c2 mediumint unsigned); +insert into t1 values (9430886, 9430886), (9430816, 9430816); +select cast(c1 as time), cast(c2 as time) from t1; +drop table t1; + +--echo # End of 10.11 tests --echo # --echo # MDEV-34829 LOCALTIME returns a wrong data type @@ -3307,13 +3308,7 @@ SELECT * FROM t1; DROP TABLE t1; SET timestamp=DEFAULT; ---echo # --echo # End of 11.6 tests ---echo # - ---echo # ---echo # Start of 11.7 tests ---echo # --echo # --echo # MDEV-15751 CURRENT_TIMESTAMP should return a TIMESTAMP [WITH TIME ZONE?] @@ -3338,7 +3333,6 @@ SELECT SHOW CREATE TABLE t1; DROP TABLE t1; - CREATE TABLE t1 AS SELECT current_timestamp(), @@ -3383,6 +3377,4 @@ SELECT SHOW CREATE TABLE t1; DROP TABLE t1; ---echo # --echo # End of 11.7 tests ---echo # diff --git a/mysql-test/main/func_time_round.result b/mysql-test/main/func_time_round.result index 75c6c373291f4..7076a95afff7e 100644 --- a/mysql-test/main/func_time_round.result +++ b/mysql-test/main/func_time_round.result @@ -98,14 +98,14 @@ GREATEST(TIME'00:00:00', a) 838:59:59.999999 838:59:59.999999 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Warning 1292 Truncated incorrect time value: '838:59:59.9999999' -Warning 1292 Truncated incorrect time value: '839:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Warning 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Warning 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Warning 1292 Incorrect time value: '87649414:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 19 +Warning 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Warning 1292 Incorrect time value: '87649415:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 21 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 SELECT GREATEST(TIME'00:00:00', a) FROM t1_time_in_decimal; GREATEST(TIME'00:00:00', a) 00:00:00.000000 @@ -114,23 +114,27 @@ GREATEST(TIME'00:00:00', a) 00:00:00.999000 00:00:00.999900 00:00:00.999990 -00:00:00.999999 -00:00:01.000000 -838:00:00.000000 +NULL +NULL +NULL 838:59:59.000000 838:59:59.900000 838:59:59.990000 838:59:59.999000 838:59:59.999900 838:59:59.999990 -838:59:59.999999 -838:59:59.999999 -838:59:59.999999 +NULL +NULL +NULL NULL NULL NULL NULL Warnings: +Warning 1292 Incorrect time value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect time value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect time value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 Warning 1292 Incorrect time value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Warning 1292 Incorrect time value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 Warning 1292 Incorrect time value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 @@ -167,8 +171,8 @@ SECOND(a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT MINUTE(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; MINUTE(a) CAST(a AS TIME(6)) a 59 23:59:59.000000 2000-12-31 23:59:59 @@ -180,8 +184,8 @@ MINUTE(a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT HOUR(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; HOUR(a) CAST(a AS TIME(6)) a 23 23:59:59.000000 2000-12-31 23:59:59 @@ -193,8 +197,8 @@ HOUR(a) CAST(a AS TIME(6)) a 23 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT EXTRACT(SECOND FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; EXTRACT(SECOND FROM a) CAST(a AS TIME(6)) a 59 23:59:59.000000 2000-12-31 23:59:59 @@ -206,8 +210,8 @@ EXTRACT(SECOND FROM a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT EXTRACT(MINUTE FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; EXTRACT(MINUTE FROM a) CAST(a AS TIME(6)) a 59 23:59:59.000000 2000-12-31 23:59:59 @@ -219,8 +223,8 @@ EXTRACT(MINUTE FROM a) CAST(a AS TIME(6)) a 59 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT EXTRACT(HOUR FROM a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; EXTRACT(HOUR FROM a) CAST(a AS TIME(6)) a 23 23:59:59.000000 2000-12-31 23:59:59 @@ -232,8 +236,8 @@ EXTRACT(HOUR FROM a) CAST(a AS TIME(6)) a 23 23:59:59.999999 2000-12-31 23:59:59.999999 0 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT TIME_TO_SEC(a), CAST(a AS TIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; TIME_TO_SEC(a) CAST(a AS TIME(6)) a 86399.000000 23:59:59.000000 2000-12-31 23:59:59 @@ -245,8 +249,8 @@ TIME_TO_SEC(a) CAST(a AS TIME(6)) a 86399.999999 23:59:59.999999 2000-12-31 23:59:59.999999 0.000000 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 # # Functions with a single TIME input, conversion from DATETIME-in-DECIMAL # @@ -356,41 +360,41 @@ EXTRACT(DAY FROM a) EXTRACT(HOUR FROM a) EXTRACT(MINUTE FROM a) EXTRACT(SECOND F 3652058 23 59 59 999999 3652058 23:59:59.999999 87649415:59:59.999999 3652058 23 59 59 999999 3652058 23:59:59.999999 87649415:59:59.9999999 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '838:59:59.9999999' +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Note 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '838:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '839:59:59.9999999' +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Note 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '839:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Note 1292 Truncated incorrect time value: '87649414:59:59.9999999' +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Note 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '87649415:59:59.9999999' SELECT TIME_TO_SEC(a), @@ -421,22 +425,22 @@ TIME_TO_SEC(a) CAST(a AS TIME(6)) a 3020399.999999 838:59:59.999999 87649415:59:59.999999 3020399.999999 838:59:59.999999 87649415:59:59.9999999 Warnings: -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Note 1292 Truncated incorrect time value: '837:59:59.9999999' -Warning 1292 Truncated incorrect time value: '838:59:59.9999999' -Warning 1292 Truncated incorrect time value: '838:59:59.9999999' -Warning 1292 Truncated incorrect time value: '839:59:59.9999999' -Warning 1292 Truncated incorrect time value: '839:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649414:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' -Warning 1292 Truncated incorrect time value: '87649415:59:59.9999999' +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 8 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Note 1292 Incorrect time value: '837:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 9 +Warning 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Warning 1292 Incorrect time value: '838:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 17 +Warning 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Warning 1292 Incorrect time value: '839:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 18 +Warning 1292 Incorrect time value: '87649414:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 19 +Warning 1292 Incorrect time value: '87649414:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 19 +Warning 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Warning 1292 Incorrect time value: '87649414:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 20 +Warning 1292 Incorrect time value: '87649415:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 21 +Warning 1292 Incorrect time value: '87649415:59:59.999999' for column `test`.`t1_time_in_varchar`.`a` at row 21 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 +Warning 1292 Incorrect time value: '87649415:59:59.9999999' for column `test`.`t1_time_in_varchar`.`a` at row 22 # # Functions with a single TIME interval input, conversion from TIME-interval-in-DECIMAL # @@ -456,22 +460,22 @@ EXTRACT(DAY FROM a) EXTRACT(HOUR FROM a) EXTRACT(MINUTE FROM a) EXTRACT(SECOND F 0 0 0 0 999000 00:00:00.999000 0.9990000000 0 0 0 0 999900 00:00:00.999900 0.9999000000 0 0 0 0 999990 00:00:00.999990 0.9999900000 -0 0 0 0 999999 00:00:00.999999 0.9999990000 -0 0 0 1 0 00:00:01.000000 0.9999999000 -34 22 0 0 0 34 22:00:00.000000 8375959.9999999000 +NULL NULL NULL NULL NULL 00:00:00.999999 0.9999990000 +NULL NULL NULL NULL NULL 00:00:01.000000 0.9999999000 +NULL NULL NULL NULL NULL 34 22:00:00.000000 8375959.9999999000 34 22 59 59 0 34 22:59:59.000000 8385959.0000000000 34 22 59 59 900000 34 22:59:59.900000 8385959.9000000000 34 22 59 59 990000 34 22:59:59.990000 8385959.9900000000 34 22 59 59 999000 34 22:59:59.999000 8385959.9990000000 34 22 59 59 999900 34 22:59:59.999900 8385959.9999000000 34 22 59 59 999990 34 22:59:59.999990 8385959.9999900000 -34 22 59 59 999999 34 22:59:59.999999 8385959.9999990000 -34 23 0 0 0 34 23:00:00.000000 8385959.9999999000 -35 0 0 0 0 35 00:00:00.000000 8395959.9999999000 -3652058 22 59 59 999999 3652058 22:59:59.999999 876494145959.9999990000 -3652058 23 0 0 0 3652058 23:00:00.000000 876494145959.9999999000 -3652058 23 59 59 999999 3652058 23:59:59.999999 876494155959.9999990000 -3652058 23 59 59 999999 3652058 23:59:59.999999 876494155959.9999999000 +NULL NULL NULL NULL NULL 34 22:59:59.999999 8385959.9999990000 +NULL NULL NULL NULL NULL 34 23:00:00.000000 8385959.9999999000 +NULL NULL NULL NULL NULL 35 00:00:00.000000 8395959.9999999000 +NULL NULL NULL NULL NULL 3652058 22:59:59.999999 876494145959.9999990000 +NULL NULL NULL NULL NULL 3652058 23:00:00.000000 876494145959.9999999000 +NULL NULL NULL NULL NULL 3652058 23:59:59.999999 876494155959.9999990000 +NULL NULL NULL NULL NULL 3652058 23:59:59.999999 876494155959.9999999000 Warnings: Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.0000000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9000000000' @@ -479,8 +483,23 @@ Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9900000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9990000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999900000' +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect interval value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999990000' +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect interval value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '0.9999999000' +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect interval value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8375959.9999999000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.0000000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9000000000' @@ -488,18 +507,40 @@ Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9900000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9990000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999000000' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999900000' +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect interval value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999990000' +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 +Warning 1292 Incorrect interval value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8385959.9999999000' +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 +Warning 1292 Incorrect interval value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '8395959.9999999000' +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 +Warning 1292 Incorrect interval value: '876494145959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 19 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494145959.9999990000' +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 +Warning 1292 Incorrect interval value: '876494145959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 20 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494145959.9999999000' -Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '876494155959.9999990000' -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect time value: '876494155959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 22 -Warning 1292 Incorrect INTERVAL DAY TO SECOND value: '876494155959.9999999000' +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 +Warning 1292 Incorrect interval value: '876494155959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 21 SELECT TIME_TO_SEC(a), CAST(a AS TIME(6)), @@ -512,23 +553,31 @@ TIME_TO_SEC(a) CAST(a AS TIME(6)) a 0.999000 00:00:00.999000 0.9990000000 0.999900 00:00:00.999900 0.9999000000 0.999990 00:00:00.999990 0.9999900000 -0.999999 00:00:00.999999 0.9999990000 -1.000000 00:00:01.000000 0.9999999000 -3016800.000000 838:00:00.000000 8375959.9999999000 +NULL NULL 0.9999990000 +NULL NULL 0.9999999000 +NULL NULL 8375959.9999999000 3020399.000000 838:59:59.000000 8385959.0000000000 3020399.900000 838:59:59.900000 8385959.9000000000 3020399.990000 838:59:59.990000 8385959.9900000000 3020399.999000 838:59:59.999000 8385959.9990000000 3020399.999900 838:59:59.999900 8385959.9999000000 3020399.999990 838:59:59.999990 8385959.9999900000 -3020399.999999 838:59:59.999999 8385959.9999990000 -3020399.999999 838:59:59.999999 8385959.9999999000 -3020399.999999 838:59:59.999999 8395959.9999999000 +NULL NULL 8385959.9999990000 +NULL NULL 8385959.9999999000 +NULL NULL 8395959.9999999000 NULL NULL 876494145959.9999990000 NULL NULL 876494145959.9999999000 NULL NULL 876494155959.9999990000 NULL NULL 876494155959.9999999000 Warnings: +Warning 1292 Incorrect time value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect time value: '0.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 7 +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect time value: '0.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 8 +Warning 1292 Incorrect time value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect time value: '8375959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 9 +Warning 1292 Incorrect time value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 +Warning 1292 Incorrect time value: '8385959.9999990000' for column `test`.`t1_time_in_decimal`.`a` at row 16 Warning 1292 Incorrect time value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Warning 1292 Incorrect time value: '8385959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 17 Warning 1292 Incorrect time value: '8395959.9999999000' for column `test`.`t1_time_in_decimal`.`a` at row 18 @@ -555,8 +604,8 @@ QUARTER(a) CAST(a AS DATE) a 4 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; DAY(a) CAST(a AS DATE) a 31 2000-12-31 2000-12-31 23:59:59 @@ -568,8 +617,8 @@ DAY(a) CAST(a AS DATE) a 31 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT MONTH(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; MONTH(a) CAST(a AS DATE) a 12 2000-12-31 2000-12-31 23:59:59 @@ -581,8 +630,8 @@ MONTH(a) CAST(a AS DATE) a 12 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT YEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; YEAR(a) CAST(a AS DATE) a 2000 2000-12-31 2000-12-31 23:59:59 @@ -594,8 +643,8 @@ YEAR(a) CAST(a AS DATE) a 2000 2000-12-31 2000-12-31 23:59:59.999999 2001 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT DAYNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; DAYNAME(a) CAST(a AS DATE) a Sunday 2000-12-31 2000-12-31 23:59:59 @@ -607,8 +656,8 @@ Sunday 2000-12-31 2000-12-31 23:59:59.99999 Sunday 2000-12-31 2000-12-31 23:59:59.999999 Monday 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT MONTHNAME(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; MONTHNAME(a) CAST(a AS DATE) a December 2000-12-31 2000-12-31 23:59:59 @@ -620,8 +669,8 @@ December 2000-12-31 2000-12-31 23:59:59.99999 December 2000-12-31 2000-12-31 23:59:59.999999 January 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT LAST_DAY(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; LAST_DAY(a) CAST(a AS DATE) a 2000-12-31 2000-12-31 2000-12-31 23:59:59 @@ -633,8 +682,8 @@ LAST_DAY(a) CAST(a AS DATE) a 2000-12-31 2000-12-31 2000-12-31 23:59:59.999999 2000-12-31 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT TO_DAYS(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; TO_DAYS(a) CAST(a AS DATE) a 730850 2000-12-31 2000-12-31 23:59:59 @@ -646,8 +695,8 @@ TO_DAYS(a) CAST(a AS DATE) a 730850 2000-12-31 2000-12-31 23:59:59.999999 730851 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SELECT DAYOFYEAR(a), CAST(a AS DATE), a FROM t1_datetime_in_varchar ORDER BY id; DAYOFYEAR(a) CAST(a AS DATE) a 366 2000-12-31 2000-12-31 23:59:59 @@ -659,8 +708,8 @@ DAYOFYEAR(a) CAST(a AS DATE) a 366 2000-12-31 2000-12-31 23:59:59.999999 1 2000-12-31 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 CREATE TABLE t1 (a VARCHAR(32)); INSERT INTO t1 VALUES ('2002-01-05 23:59:59'), @@ -672,21 +721,21 @@ YEARWEEK(a) a 200152 2002-01-05 23:59:59.999999 200201 2002-01-05 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2002-01-05 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2002-01-05 23:59:59.9999999' for column `test`.`t1`.`a` at row 3 SELECT WEEK(a), a FROM t1; WEEK(a) a 0 2002-01-05 23:59:59 0 2002-01-05 23:59:59.999999 1 2002-01-05 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2002-01-05 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2002-01-05 23:59:59.9999999' for column `test`.`t1`.`a` at row 3 SELECT WEEKDAY(a), a FROM t1; WEEKDAY(a) a 5 2002-01-05 23:59:59 5 2002-01-05 23:59:59.999999 6 2002-01-05 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2002-01-05 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2002-01-05 23:59:59.9999999' for column `test`.`t1`.`a` at row 3 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(32,9)); INSERT INTO t1 VALUES @@ -836,8 +885,8 @@ TO_SECONDS(a) CAST(a AS DATETIME(6)) a 63145526399 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 63145526400 2001-01-01 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SET time_zone='+00:00'; SELECT UNIX_TIMESTAMP(a), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; UNIX_TIMESTAMP(a) CAST(a AS DATETIME(6)) a @@ -850,8 +899,8 @@ UNIX_TIMESTAMP(a) CAST(a AS DATETIME(6)) a 978307199.999999 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 978307200.000000 2001-01-01 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 SET time_zone=DEFAULT; SELECT CONVERT_TZ(a, '+00:00','+00:00'), CAST(a AS DATETIME(6)), a FROM t1_datetime_in_varchar ORDER BY id; CONVERT_TZ(a, '+00:00','+00:00') CAST(a AS DATETIME(6)) a @@ -864,8 +913,8 @@ CONVERT_TZ(a, '+00:00','+00:00') CAST(a AS DATETIME(6)) a 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 2000-12-31 23:59:59.999999 2001-01-01 00:00:00.000000 2001-01-01 00:00:00.000000 2000-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2000-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 +Note 1292 Incorrect datetime value: '2000-12-31 23:59:59.9999999' for column `test`.`t1_datetime_in_varchar`.`a` at row 8 # # Functions with a single DATETIME input, conversion from DATETIME-in-DECIMAL # @@ -1047,22 +1096,22 @@ dt6 2018-01-01 00:00:00.000000 Warnings: Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 Level Note Code 1292 -Message Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Message Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 4 DROP TABLE t1; CREATE TABLE t1 (a DECIMAL(32,9)); INSERT INTO t1 VALUES @@ -1147,13 +1196,13 @@ TIMESTAMP(t1.a, t2.a) a a 2018-01-01 00:00:00.999999 2017-12-31 23:59:59.9999999 00:00:00.999999 2018-01-01 00:00:01.000000 2017-12-31 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' SELECT ADDTIME(t1.a, t2.a), t1.a, t2.a FROM t1,t2 ORDER BY t1.a, t2.a; ADDTIME(t1.a, t2.a) a a @@ -1174,13 +1223,13 @@ ADDTIME(t1.a, t2.a) a a 2018-01-01 00:00:00.999999 2017-12-31 23:59:59.9999999 00:00:00.999999 2018-01-01 00:00:01 2017-12-31 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 Note 1292 Truncated incorrect INTERVAL DAY TO SECOND value: '00:00:00.9999999' DROP TABLE t1, t2; CREATE TABLE t1 (a VARCHAR(64)); @@ -1214,14 +1263,14 @@ TIMEDIFF(t1.a, t2.a) a a 23:59:59.000001 23:59:59.9999999 00:00:00.999999 23:59:59.000000 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 DROP TABLE t1, t2; CREATE TABLE t1 (a VARCHAR(64)); CREATE TABLE t2 (a VARCHAR(64)); @@ -1254,14 +1303,14 @@ TIMESTAMPDIFF(MICROSECOND,t1.a, t2.a) a a -1 2001-12-31 23:59:59.9999999 2001-12-31 23:59:59.999999 0 2001-12-31 23:59:59.9999999 2001-12-31 23:59:59.9999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2001-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2001-12-31 23:59:59.9999999' for column `test`.`t2`.`a` at row 5 DROP TABLE t1, t2; CREATE TABLE t1 (a VARCHAR(64)); CREATE TABLE t2 (a VARCHAR(64)); @@ -1294,14 +1343,14 @@ TIMEDIFF(t1.a, t2.a) a a 23:59:59.000001 23:59:59.9999999 00:00:00.999999 23:59:59.000000 23:59:59.9999999 00:00:00.9999999 Warnings: -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' -Note 1292 Truncated incorrect time value: '23:59:59.9999999' -Note 1292 Truncated incorrect time value: '00:00:00.9999999' +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 +Note 1292 Incorrect time value: '23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect time value: '00:00:00.9999999' for column `test`.`t2`.`a` at row 5 DROP TABLE t1, t2; # # STR_TO_DATE behaviour is questionable in MySQL 5.6 (MySQL Bug #92474) @@ -1365,8 +1414,8 @@ a b DATE_ADD(a, INTERVAL b SECOND) 2017-12-31 23:59:59.9999999 0.999999000 2018-01-01 00:00:00.999999 2017-12-31 23:59:59.9999999 0.999999900 2018-01-01 00:00:00.999999 Warnings: -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' -Note 1292 Truncated incorrect datetime value: '2017-12-31 23:59:59.9999999' +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 +Note 1292 Incorrect datetime value: '2017-12-31 23:59:59.9999999' for column `test`.`t1`.`a` at row 5 DROP TABLE t1, t2; diff --git a/mysql-test/main/gis-precise.result b/mysql-test/main/gis-precise.result index ca1fa66653079..242fa2eb5ef76 100644 --- a/mysql-test/main/gis-precise.result +++ b/mysql-test/main/gis-precise.result @@ -860,3 +860,11 @@ TRUNCATE(ST_Distance_Sphere(@zenica, @sarajevo), 10) SELECT TRUNCATE(ST_Distance_Sphere(@sarajevo, @zenica), 10); TRUNCATE(ST_Distance_Sphere(@sarajevo, @zenica), 10) 55878.5933759170 +# +# MDEV-31499 Assertion `(0)' failed in Gis_geometry_collection::init_from_opresult. +# +SELECT ST_NUMGEOMETRIES( +ST_INTERSECTION( +ST_MULTIPOLYGONFROMTEXT(' MULTIPOLYGON(((3.8571428571428568 2.857142857142857,5.571428571428571 4.571428571428571,9 4,3.8571428571428568 2.857142857142857)),((4.5 4.75,3 5,4.6 7.4,6 6,4.5 4.75))) '), ST_MULTIPOLYGONFROMTEXT(' MULTIPOLYGON(((3 4,3 5,2 5,2 7,5 4,3 4),(5 4,7.4 7,8 7,8 4,5 4))) ') )) as V; +V +3 diff --git a/mysql-test/main/gis-precise.test b/mysql-test/main/gis-precise.test index e135bedc38d10..4f84589c9995b 100644 --- a/mysql-test/main/gis-precise.test +++ b/mysql-test/main/gis-precise.test @@ -476,3 +476,13 @@ set @zenica = ST_GeomFromText('POINT(17.907743 44.203438)'); set @sarajevo = ST_GeomFromText('POINT(18.413076 43.856258)'); SELECT TRUNCATE(ST_Distance_Sphere(@zenica, @sarajevo), 10); SELECT TRUNCATE(ST_Distance_Sphere(@sarajevo, @zenica), 10); + + +--echo # +--echo # MDEV-31499 Assertion `(0)' failed in Gis_geometry_collection::init_from_opresult. +--echo # + +SELECT ST_NUMGEOMETRIES( + ST_INTERSECTION( + ST_MULTIPOLYGONFROMTEXT(' MULTIPOLYGON(((3.8571428571428568 2.857142857142857,5.571428571428571 4.571428571428571,9 4,3.8571428571428568 2.857142857142857)),((4.5 4.75,3 5,4.6 7.4,6 6,4.5 4.75))) '), ST_MULTIPOLYGONFROMTEXT(' MULTIPOLYGON(((3 4,3 5,2 5,2 7,5 4,3 4),(5 4,7.4 7,8 7,8 4,5 4))) ') )) as V; + diff --git a/mysql-test/main/gis-rtree.result b/mysql-test/main/gis-rtree.result index 2263c484041e4..40b5e49c525ce 100644 --- a/mysql-test/main/gis-rtree.result +++ b/mysql-test/main/gis-rtree.result @@ -1655,3 +1655,8 @@ DROP TABLE t1; # # End of 10.1 tests # +CREATE TABLE t1 (c POINT NOT NULL,SPATIAL (c)); +INSERT INTO t1 VALUES (ST_GEOMFROMTEXT ('POINT(1 0)')); +UPDATE t1 SET c=''; +ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field +DROP TABLE t1; diff --git a/mysql-test/main/gis-rtree.test b/mysql-test/main/gis-rtree.test index 2a87814e09a6f..bfc4eff41f6eb 100644 --- a/mysql-test/main/gis-rtree.test +++ b/mysql-test/main/gis-rtree.test @@ -1043,3 +1043,15 @@ DROP TABLE t1; --echo # --echo # End of 10.1 tests --echo # + +# +# Bug #31766 SIGSEGV in maria_rtree_split_page | maria_rtree_add_key +# + +CREATE TABLE t1 (c POINT NOT NULL,SPATIAL (c)); +INSERT INTO t1 VALUES (ST_GEOMFROMTEXT ('POINT(1 0)')); +--error ER_CANT_CREATE_GEOMETRY_OBJECT +UPDATE t1 SET c=''; +DROP TABLE t1; + + diff --git a/mysql-test/main/gis.result b/mysql-test/main/gis.result index 5190e4ff4fd1c..23838945f4c10 100644 --- a/mysql-test/main/gis.result +++ b/mysql-test/main/gis.result @@ -1109,8 +1109,8 @@ ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))) # BUG#12537203 - CRASH WHEN SUBSELECTING GLOBAL VARIABLES IN # GEOMETRY FUNCTION ARGUMENTS # -SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); -ERROR HY000: Illegal parameter data type bigint for operation 'geometrycollection' +SELECT GEOMETRYCOLLECTION((SELECT @@OLD_MODE)); +ERROR HY000: Illegal parameter data type varchar for operation 'geometrycollection' # # MDEV-4252 geometry query crashes server # diff --git a/mysql-test/main/gis.test b/mysql-test/main/gis.test index 94528439b4902..d3ecb20f38859 100644 --- a/mysql-test/main/gis.test +++ b/mysql-test/main/gis.test @@ -371,7 +371,7 @@ insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363 # Expected results are 115.2970604672862 and 36.23335610879993, but IA64 returns # slightly different values due to fused multiply-add instructions. ---replace_result 115.29706047613604 115.2970604672862 36.23335611157958 36.23335610879993 +--replace_regex /115.2970604[67]\d+/115.2970604672862/ /36.233356111579\d+/36.23335610879993/ select object_id, geometrytype(geo), ISSIMPLE(GEO), ASTEXT(centroid(geo)) from t1 where object_id=85998; @@ -844,7 +844,7 @@ SELECT ISCLOSED(CONVERT(CONCAT(' ', 0x2), BINARY(20))); --echo # --replace_regex /non geometric .* value/non geometric '' value/ --error ER_ILLEGAL_PARAMETER_DATA_TYPE_FOR_OPERATION -SELECT GEOMETRYCOLLECTION((SELECT @@OLD)); +SELECT GEOMETRYCOLLECTION((SELECT @@OLD_MODE)); --echo # --echo # MDEV-4252 geometry query crashes server diff --git a/mysql-test/main/grant.result b/mysql-test/main/grant.result index 3f70f1b2b93de..801e0e57f6cbc 100644 --- a/mysql-test/main/grant.result +++ b/mysql-test/main/grant.result @@ -854,7 +854,7 @@ create user mysqltest_8; ERROR HY000: Operation CREATE USER failed for 'mysqltest_8'@'%' create user mysqltest_8@host8; ERROR HY000: Operation CREATE USER failed for 'mysqltest_8'@'host8' -select user, QUOTE(host) from mysql.user where user="mysqltest_8"; +select User, QUOTE(host) from mysql.user where user="mysqltest_8"; User QUOTE(host) mysqltest_8 '%' mysqltest_8 'host8' @@ -1294,13 +1294,11 @@ connection bug23556; USE bug23556; TRUNCATE t1; connection default; -USE bug23556; -DROP TABLE t1; +disconnect bug23556; USE test; DROP DATABASE bug23556; DROP USER bug23556@localhost; connection default; -disconnect bug23556; connect con1, localhost, root,,*NO-ONE*; connection con1; GRANT PROCESS ON * TO user@localhost; @@ -1587,6 +1585,8 @@ mysqltest1.f1() 0 connection default; drop user mysqluser1@localhost; +Warnings: +Note 4227 Dropped users 'mysqluser1'@'localhost' have active connections. Use KILL CONNECTION if they should not be used anymore. # # Test that dropping of user is properly reflected in # both privilege tables and in in-memory structures. @@ -1779,14 +1779,8 @@ ERROR 42S01: Table 't4' already exists create table t1 select * from t2; ERROR 42000: INSERT command denied to user 'mysqltest'@'localhost' for table `mysqltest`.`t1` connection default; -drop table t1,t2,t4,t5,t6; -revoke create on mysqltest.* from mysqltest@localhost; -revoke select, insert on mysqltest.t2 from mysqltest@localhost; -revoke insert on mysqltest.t4 from mysqltest@localhost; -revoke create, insert on mysqltest.t5 from mysqltest@localhost; -revoke create, insert on mysqltest.t6 from mysqltest@localhost; -drop user mysqltest@localhost; disconnect user1; +drop user mysqltest@localhost; drop database mysqltest; use test; call mtr.add_suppression("Can't open and lock privilege tables"); @@ -1954,7 +1948,7 @@ DROP DATABASE db2; # grant usage on Foo.* to myuser@Localhost identified by 'foo'; grant select on Foo.* to myuser@localhost; -select host,user from mysql.user where User='myuser'; +select Host,User from mysql.user where User='myuser'; Host User localhost myuser revoke select on Foo.* from myuser@localhost; @@ -2833,13 +2827,8 @@ CREATE USER bug33578113; GRANT DROP ON performance_schema.* TO bug33578113; REVOKE DROP ON performance_schema.* FROM bug33578113; DROP USER bug33578113; -# # End of 10.2 tests # -# -# Start of 10.3 tests -# -# # MDEV-19948 'show grants' return privileges individually # # switching from mysql.global_priv to mysql.user @@ -2854,10 +2843,8 @@ Grants for ten2@% GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, RELOAD, SHUTDOWN, PROCESS, FILE, REFERENCES, INDEX, ALTER, SHOW DATABASES, SUPER, CREATE TEMPORARY TABLES, LOCK TABLES, EXECUTE, REPLICATION SLAVE, BINLOG MONITOR, CREATE VIEW, SHOW VIEW, CREATE ROUTINE, ALTER ROUTINE, CREATE USER, EVENT, TRIGGER, CREATE TABLESPACE, DELETE HISTORY, SET USER, FEDERATED ADMIN, CONNECTION ADMIN, READ_ONLY ADMIN, REPLICATION SLAVE ADMIN, REPLICATION MASTER ADMIN, BINLOG ADMIN, BINLOG REPLAY, SLAVE MONITOR ON *.* TO `ten2`@`%` DROP USER ten2; # switching back from mysql.user to mysql.global_priv -# # End of 10.3 tests # -# # MDEV-17932 : Assertion upon double RENAME USER # CREATE USER foo@localhost; @@ -2876,7 +2863,5 @@ GRANT UPDATE ON test.* TO foo; RENAME USER 'name' to 'a'; DROP USER foo; DROP USER a; -# # End of 10.4 tests -# update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; diff --git a/mysql-test/main/grant.test b/mysql-test/main/grant.test index 0aafc43601be7..17f45fb38ba37 100644 --- a/mysql-test/main/grant.test +++ b/mysql-test/main/grant.test @@ -2,17 +2,13 @@ # Grant tests not performed with embedded server --source include/not_embedded.inc - -# Save the initial number of concurrent sessions ---source include/count_sessions.inc +--disable_service_connection set GLOBAL sql_mode=""; set LOCAL sql_mode=""; SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; SET GLOBAL log_bin_trust_function_creators = 1; ---disable_cursor_protocol select priv into @root_priv from mysql.global_priv where user='root' and host='localhost'; ---enable_cursor_protocol connect (master,localhost,root,,); connection master; @@ -594,7 +590,7 @@ create user mysqltest_8; --error ER_CANNOT_USER create user mysqltest_8@host8; -select user, QUOTE(host) from mysql.user where user="mysqltest_8"; +select User, QUOTE(host) from mysql.user where user="mysqltest_8"; --echo Schema privileges grant select on mysqltest.* to mysqltest_8@''; @@ -967,13 +963,11 @@ USE bug23556; TRUNCATE t1; connection default; -USE bug23556; -DROP TABLE t1; +disconnect bug23556; USE test; DROP DATABASE bug23556; DROP USER bug23556@localhost; connection default; -disconnect bug23556; # @@ -1570,18 +1564,9 @@ create table t4 select * from t2; --error ER_TABLEACCESS_DENIED_ERROR create table t1 select * from t2; - connection default; -drop table t1,t2,t4,t5,t6; - -revoke create on mysqltest.* from mysqltest@localhost; -revoke select, insert on mysqltest.t2 from mysqltest@localhost; -revoke insert on mysqltest.t4 from mysqltest@localhost; -revoke create, insert on mysqltest.t5 from mysqltest@localhost; -revoke create, insert on mysqltest.t6 from mysqltest@localhost; -drop user mysqltest@localhost; - disconnect user1; +drop user mysqltest@localhost; drop database mysqltest; use test; @@ -1781,7 +1766,7 @@ DROP DATABASE db2; --echo # grant usage on Foo.* to myuser@Localhost identified by 'foo'; grant select on Foo.* to myuser@localhost; -select host,user from mysql.user where User='myuser'; +select Host,User from mysql.user where User='myuser'; revoke select on Foo.* from myuser@localhost; delete from mysql.user where User='myuser'; flush privileges; @@ -2228,8 +2213,6 @@ DROP USER untrusted@localhost; DROP DATABASE secret; set GLOBAL sql_mode=default; -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc --echo # --echo # MDEV-22755 CREATE USER leads to indirect SIGABRT in __stack_chk_fail () from fill_schema_user_privileges + *** stack smashing detected *** (on optimized builds) @@ -2299,15 +2282,8 @@ CREATE USER bug33578113; GRANT DROP ON performance_schema.* TO bug33578113; REVOKE DROP ON performance_schema.* FROM bug33578113; DROP USER bug33578113; ---source include/wait_until_count_sessions.inc ---echo # --echo # End of 10.2 tests ---echo # - ---echo # ---echo # Start of 10.3 tests ---echo # --echo # --echo # MDEV-19948 'show grants' return privileges individually @@ -2330,9 +2306,7 @@ SHOW GRANTS FOR ten2; DROP USER ten2; source include/switch_to_mysql_global_priv.inc; ---echo # --echo # End of 10.3 tests ---echo # --echo # --echo # MDEV-17932 : Assertion upon double RENAME USER @@ -2355,8 +2329,6 @@ RENAME USER 'name' to 'a'; DROP USER foo; DROP USER a; ---echo # --echo # End of 10.4 tests ---echo # update mysql.global_priv set priv=@root_priv where user='root' and host='localhost'; diff --git a/mysql-test/main/grant2.result b/mysql-test/main/grant2.result index ebf8327271344..b1667253e2c28 100644 --- a/mysql-test/main/grant2.result +++ b/mysql-test/main/grant2.result @@ -2,13 +2,6 @@ select priv into @root_priv from mysql.global_priv where user='root' and host='l set GLOBAL sql_mode=""; set LOCAL sql_mode=""; SET NAMES binary; -drop database if exists mysqltest; -drop database if exists mysqltest_1; -delete from mysql.user where user like 'mysqltest\_%'; -delete from mysql.db where user like 'mysqltest\_%'; -delete from mysql.tables_priv where user like 'mysqltest\_%'; -delete from mysql.columns_priv where user like 'mysqltest\_%'; -flush privileges; grant all privileges on `my\_1`.* to mysqltest_1@localhost with grant option; grant create user on *.* to mysqltest_1@localhost; create user mysqltest_2@localhost; @@ -181,7 +174,7 @@ grant select on *.* to 'mysqltest_2'; grant insert on test.* to 'mysqltest_2'; grant update on test.t1 to 'mysqltest_2'; grant update (c2) on test.t2 to 'mysqltest_2'; -select host,user,password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; +select Host,User,Password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; Host User Password plugin authentication_string % mysqltest_1 mysql_native_password % mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 mysql_native_password *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 @@ -206,7 +199,7 @@ GRANT INSERT ON "test".* TO "mysqltest_2"@"%" GRANT UPDATE ("c2") ON "test"."t2" TO "mysqltest_2"@"%" GRANT UPDATE ON "test"."t1" TO "mysqltest_2"@"%" drop user 'mysqltest_1'; -select host,user,password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; +select Host,User,Password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; Host User Password plugin authentication_string % mysqltest_2 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 mysql_native_password *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 % mysqltest_3 fffffffffffffffffffffffffffffffffffffffff mysql_native_password fffffffffffffffffffffffffffffffffffffffff @@ -223,7 +216,7 @@ host db user table_name column_name show grants for 'mysqltest_1'; ERROR 42000: There is no such grant defined for user 'mysqltest_1' on host '%' rename user 'mysqltest_2' to 'mysqltest_1'; -select host,user,password,plugin,authentication_string from mysql.user where user like 'mysqltest_%' ; +select Host,User,Password,plugin,authentication_string from mysql.user where user like 'mysqltest_%' ; Host User Password plugin authentication_string % mysqltest_1 *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 mysql_native_password *BD447CBA355AF58578D3AE33BA2E2CD388BA08D1 % mysqltest_3 fffffffffffffffffffffffffffffffffffffffff mysql_native_password fffffffffffffffffffffffffffffffffffffffff @@ -367,7 +360,7 @@ mysqltest_1@127.0.0.1 set password = password('changed'); disconnect b12302; connection default; -select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; +select Host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; Host length(authentication_string) 127.0.0.1 41 revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.1'; @@ -382,7 +375,7 @@ mysqltest_1@127.0.0.0/255.0.0.0 set password = password('changed'); disconnect b12302_2; connection default; -select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; +select Host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; Host length(authentication_string) 127.0.0.0/255.0.0.0 41 revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.0/255.0.0.0'; diff --git a/mysql-test/main/grant2.test b/mysql-test/main/grant2.test index 26a2a40245f2a..123899d3d242d 100644 --- a/mysql-test/main/grant2.test +++ b/mysql-test/main/grant2.test @@ -1,9 +1,6 @@ # Grant tests not performed with embedded server -- source include/not_embedded.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - select priv into @root_priv from mysql.global_priv where user='root' and host='localhost'; set GLOBAL sql_mode=""; @@ -15,19 +12,6 @@ SET NAMES binary; # (usually it's GRANT, reconnect as another user, try something) # - -# prepare playground before tests ---disable_warnings -drop database if exists mysqltest; -drop database if exists mysqltest_1; ---enable_warnings -delete from mysql.user where user like 'mysqltest\_%'; -delete from mysql.db where user like 'mysqltest\_%'; -delete from mysql.tables_priv where user like 'mysqltest\_%'; -delete from mysql.columns_priv where user like 'mysqltest\_%'; -flush privileges; - - grant all privileges on `my\_1`.* to mysqltest_1@localhost with grant option; grant create user on *.* to mysqltest_1@localhost; create user mysqltest_2@localhost; @@ -233,7 +217,7 @@ grant insert on test.* to 'mysqltest_2'; grant update on test.t1 to 'mysqltest_2'; grant update (c2) on test.t2 to 'mysqltest_2'; --sorted_result -select host,user,password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; +select Host,User,Password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; --sorted_result select host,db,user from mysql.db where user like 'mysqltest_%'; --sorted_result @@ -246,7 +230,7 @@ show grants for 'mysqltest_2'; # Drop drop user 'mysqltest_1'; --sorted_result -select host,user,password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; +select Host,User,Password,plugin,authentication_string from mysql.user where user like 'mysqltest_%'; --sorted_result select host,db,user from mysql.db where user like 'mysqltest_%'; --sorted_result @@ -259,7 +243,7 @@ show grants for 'mysqltest_1'; # Rename rename user 'mysqltest_2' to 'mysqltest_1'; --sorted_result -select host,user,password,plugin,authentication_string from mysql.user where user like 'mysqltest_%' ; +select Host,User,Password,plugin,authentication_string from mysql.user where user like 'mysqltest_%' ; --sorted_result select host,db,user from mysql.db where user like 'mysqltest_%' ; --sorted_result @@ -401,7 +385,7 @@ select current_user(); set password = password('changed'); disconnect b12302; connection default; -select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; +select Host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.1'; delete from mysql.user where user like 'mysqltest\_1'; flush privileges; @@ -412,7 +396,7 @@ select current_user(); set password = password('changed'); disconnect b12302_2; connection default; -select host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; +select Host, length(authentication_string) from mysql.user where user like 'mysqltest\_1'; revoke all on mysqltest_1.* from mysqltest_1@'127.0.0.0/255.0.0.0'; delete from mysql.user where user like 'mysqltest\_1'; flush privileges; @@ -1022,7 +1006,4 @@ DROP USER mysqltest_u3@localhost; DROP USER mysqltest_u4@localhost; DROP USER mysqltest_u5@localhost; - set GLOBAL sql_mode=default; -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/grant3.result b/mysql-test/main/grant3.result index 66f081a5689dc..24537ab9c1552 100644 --- a/mysql-test/main/grant3.result +++ b/mysql-test/main/grant3.result @@ -3,7 +3,6 @@ set local sql_mode=""; SET NAMES binary; connect master,localhost,root,,; connection master; -drop table if exists t1; delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; @@ -28,7 +27,7 @@ flush privileges; grant select on test.* to CUser@localhost; grant select on test.* to CUser@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; @@ -36,14 +35,14 @@ user host db select_priv CUser localhost test Y REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; user host db select_priv REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; @@ -55,7 +54,7 @@ create table t1 (a int); grant select on test.t1 to CUser@localhost; grant select on test.t1 to CUser@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; @@ -63,14 +62,14 @@ user host db Table_name Table_priv Column_priv CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; @@ -81,7 +80,7 @@ ERROR HY000: Operation DROP USER failed for 'CUser'@'localhost' grant select(a) on test.t1 to CUser@localhost; grant select(a) on test.t1 to CUser@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; @@ -89,14 +88,14 @@ user host db Table_name Table_priv Column_priv CUser localhost test t1 Select REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; user host db Table_name Table_priv Column_priv REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; User Host CUser localhost SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; @@ -108,7 +107,7 @@ drop table t1; grant select on test.* to CUser2@localhost; grant select on test.* to CUser2@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser2' order by 1,2; User Host CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; @@ -116,7 +115,7 @@ user host db select_priv CUser2 localhost test Y REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser2' order by 1,2; User Host CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; @@ -124,7 +123,7 @@ user host db select_priv REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; ERROR 42000: There is no such grant defined for user 'CUser2' on host 'localhost' flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser2' order by 1,2; User Host CUser2 localhost SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; diff --git a/mysql-test/main/grant3.test b/mysql-test/main/grant3.test index 7842233d9bdc4..31cdc4e240a5e 100644 --- a/mysql-test/main/grant3.test +++ b/mysql-test/main/grant3.test @@ -1,8 +1,5 @@ # Can't run with embedded server because we use GRANT --- source include/not_embedded.inc - -# Save the initial number of concurrent sessions ---source include/count_sessions.inc +--source include/not_embedded.inc set global sql_mode=""; set local sql_mode=""; @@ -13,11 +10,6 @@ SET NAMES binary; connect (master,localhost,root,,); connection master; -# Cleanup ---disable_warnings -drop table if exists t1; ---enable_warnings - delete from mysql.user where user like 'mysqltest\_%'; delete from mysql.db where user like 'mysqltest\_%'; delete from mysql.tables_priv where user like 'mysqltest\_%'; @@ -50,19 +42,19 @@ grant select on test.* to CUser@localhost; grant select on test.* to CUser@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser' order by 1,2; DROP USER CUser@localhost; @@ -75,19 +67,19 @@ grant select on test.t1 to CUser@localhost; grant select on test.t1 to CUser@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; DROP USER CUser@localhost; @@ -100,19 +92,19 @@ grant select(a) on test.t1 to CUser@localhost; grant select(a) on test.t1 to CUser@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'CUser'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser' order by 1,2; SELECT user, host, db, Table_name, Table_priv, Column_priv FROM mysql.tables_priv where user = 'CUser' order by 1,2; DROP USER CUser@localhost; @@ -127,20 +119,20 @@ grant select on test.* to CUser2@localhost; grant select on test.* to CUser2@LOCALHOST; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; REVOKE SELECT ON test.* FROM 'CUser2'@'LOCALHOST'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; --error ER_NONEXISTING_GRANT REVOKE SELECT ON test.* FROM 'CUser2'@'localhost'; flush privileges; -SELECT user, host FROM mysql.user where user = 'CUser2' order by 1,2; +SELECT User, Host FROM mysql.user where user = 'CUser2' order by 1,2; SELECT user, host, db, select_priv FROM mysql.db where user = 'CUser2' order by 1,2; DROP USER CUser2@localhost; @@ -237,6 +229,3 @@ disconnect foo; connection default; drop user foo@localhost; drop database db1; - -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/grant4.result b/mysql-test/main/grant4.result index 321eee1847d23..daad4d6733597 100644 --- a/mysql-test/main/grant4.result +++ b/mysql-test/main/grant4.result @@ -107,7 +107,7 @@ Table Op Msg_type Msg_text mysqltest_db1.t6 check status OK ** With no privileges access is naturally denied: CHECK TABLE t5; -ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t5` +ERROR 42000: CHECK TABLE command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t5` ** CHECKSUM TABLE requires SELECT privileges on the table. The following should fail: CHECKSUM TABLE t6; ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t6` @@ -143,15 +143,15 @@ drop temporary table mysql.user; rename table mysql.user1 to mysql.user; # switching back from mysql.user to mysql.global_priv # switching from mysql.global_priv to mysql.user -call mtr.add_suppression('mysql.user table is damaged'); +call mtr.add_suppression('mysql\\.user'); rename table mysql.user to mysql.user1; create table mysql.user (Host char(100), User char(100)); flush privileges; -ERROR HY000: Fatal error: mysql.user table is damaged or in unsupported 3.20 format +ERROR HY000: Cannot load from mysql.user. The table is probably corrupted drop table mysql.user; rename table mysql.user1 to mysql.user; # switching back from mysql.user to mysql.global_priv -End of 5.5 tests +# End of 5.5 tests # # Additional coverage for refactoring which is made as part # of fix for bug #27480 "Extend CREATE TEMPORARY TABLES privilege @@ -193,9 +193,6 @@ mysqltest_db1.t1 check error Corrupt # Otherwise info about such repair will be missing from its result-set. repair table mysqltest_db1.t1, mysqltest_db1.t2; ERROR 42000: SELECT, INSERT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t2` -# The same is true for CHECK TABLE statement. -check table mysqltest_db1.t1, mysqltest_db1.t2; -ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table `mysqltest_db1`.`t2` check table mysqltest_db1.t1; Table Op Msg_type Msg_text mysqltest_db1.t1 check warning Table is marked as crashed diff --git a/mysql-test/main/grant4.test b/mysql-test/main/grant4.test index cda1c5fb28125..37c42b642e155 100644 --- a/mysql-test/main/grant4.test +++ b/mysql-test/main/grant4.test @@ -169,16 +169,16 @@ source include/switch_to_mysql_global_priv.inc; # Bug#28986737: RENAMING AND REPLACING MYSQL.USER TABLE CAN LEAD TO A SERVER CRASH # source include/switch_to_mysql_user.inc; -call mtr.add_suppression('mysql.user table is damaged'); +call mtr.add_suppression('mysql\\.user'); rename table mysql.user to mysql.user1; create table mysql.user (Host char(100), User char(100)); ---error ER_UNKNOWN_ERROR +--error ER_CANNOT_LOAD_FROM_TABLE_V2 flush privileges; drop table mysql.user; rename table mysql.user1 to mysql.user; source include/switch_to_mysql_global_priv.inc; ---echo End of 5.5 tests +--echo # End of 5.5 tests --echo # --echo # Additional coverage for refactoring which is made as part @@ -223,15 +223,11 @@ check table mysqltest_db1.t1; --echo # Otherwise info about such repair will be missing from its result-set. --error ER_TABLEACCESS_DENIED_ERROR repair table mysqltest_db1.t1, mysqltest_db1.t2; ---echo # The same is true for CHECK TABLE statement. ---error ER_TABLEACCESS_DENIED_ERROR -check table mysqltest_db1.t1, mysqltest_db1.t2; check table mysqltest_db1.t1; repair table mysqltest_db1.t1; --echo # Clean-up. disconnect con1; ---source include/wait_until_disconnected.inc connection default; drop database mysqltest_db1; drop user mysqltest_u1@localhost; diff --git a/mysql-test/main/grant5.result b/mysql-test/main/grant5.result index b112e15268104..25c12f21885b6 100644 --- a/mysql-test/main/grant5.result +++ b/mysql-test/main/grant5.result @@ -16,6 +16,7 @@ GRANT USAGE ON *.* TO `foo` show grants for foo@'%'; ERROR 42000: Access denied for user 'test'@'%' to database 'mysql' connection default; +disconnect conn_1; drop user test, foo; drop role foo; CREATE TABLE t1 (a INT); @@ -347,6 +348,8 @@ create user u7@h identified with 'mysql_old_password'; set password for u7@h = 'pwd'; ERROR HY000: Password hash should be a 41-digit hexadecimal number set password for u7@h = old_password('pwd'); +Warnings: +Warning 1287 'OLD_PASSWORD()' is deprecated and will be removed in a future release. Please use 'PASSWORD()' instead create user u8@h identified with 'mysql_old_password'; set password for u8@h = '78a302dd267f6044'; select user as User,host as Host,plugin,authentication_string from mysql.user where host='h'; @@ -451,11 +454,11 @@ disconnect con1; connection default; drop database db; drop user foo; -call mtr.add_suppression('mysql.host table is damaged'); +call mtr.add_suppression('mysql\\.host'); create table mysql.host (c1 int); insert mysql.host values (1); flush privileges; -ERROR HY000: Fatal error: mysql.host table is damaged or in unsupported 3.20 format +ERROR HY000: Cannot load from mysql.host. The table is probably corrupted drop table mysql.host; # # MDEV-30826 Invalid data on mysql.host segfaults the server after an upgrade to 10.4 diff --git a/mysql-test/main/grant5.test b/mysql-test/main/grant5.test index c1253c55ac6dc..13caffdd4ad4b 100644 --- a/mysql-test/main/grant5.test +++ b/mysql-test/main/grant5.test @@ -20,6 +20,7 @@ show grants for foo; # role --error ER_DBACCESS_DENIED_ERROR show grants for foo@'%'; # user --connection default +--disconnect conn_1 drop user test, foo; drop role foo; @@ -307,7 +308,9 @@ eval create user u6@h identified with 'mysql_old_password' using '$p'; create user u7@h identified with 'mysql_old_password'; error ER_PASSWD_LENGTH; set password for u7@h = 'pwd'; +--enable_prepare_warnings set password for u7@h = old_password('pwd'); +--disable_prepare_warnings create user u8@h identified with 'mysql_old_password'; eval set password for u8@h = '$p'; sorted_result; @@ -403,10 +406,10 @@ drop user foo; # # MDEV-23009 SIGSEGV in get_field from acl_load (on optimized builds) # -call mtr.add_suppression('mysql.host table is damaged'); +call mtr.add_suppression('mysql\\.host'); create table mysql.host (c1 int); insert mysql.host values (1); ---error ER_UNKNOWN_ERROR +--error ER_CANNOT_LOAD_FROM_TABLE_V2 flush privileges; drop table mysql.host; diff --git a/mysql-test/main/grant_cache_no_prot.result b/mysql-test/main/grant_cache_no_prot.result index daf382d65d31d..7c5dd05f34921 100644 --- a/mysql-test/main/grant_cache_no_prot.result +++ b/mysql-test/main/grant_cache_no_prot.result @@ -226,19 +226,12 @@ Qcache_hits 8 show status like "Qcache_not_cached"; Variable_name Value Qcache_not_cached 5 -connection root; disconnect root; -connection root2; disconnect root2; -connection user1; disconnect user1; -connection user2; disconnect user2; -connection user3; disconnect user3; -connection user4; disconnect user4; -connection unkuser; disconnect unkuser; connection default; set names binary; diff --git a/mysql-test/main/grant_cache_ps_prot.result b/mysql-test/main/grant_cache_ps_prot.result index 0fde04ac0f33b..36937323cdb8d 100644 --- a/mysql-test/main/grant_cache_ps_prot.result +++ b/mysql-test/main/grant_cache_ps_prot.result @@ -226,19 +226,12 @@ Qcache_hits 8 show status like "Qcache_not_cached"; Variable_name Value Qcache_not_cached 4 -connection root; disconnect root; -connection root2; disconnect root2; -connection user1; disconnect user1; -connection user2; disconnect user2; -connection user3; disconnect user3; -connection user4; disconnect user4; -connection unkuser; disconnect unkuser; connection default; set names binary; diff --git a/mysql-test/main/grant_explain_non_select.test b/mysql-test/main/grant_explain_non_select.test index 2bde3bed17ce3..4945ebf027f35 100644 --- a/mysql-test/main/grant_explain_non_select.test +++ b/mysql-test/main/grant_explain_non_select.test @@ -3,10 +3,7 @@ # # Grant tests not performed with embedded server --- source include/not_embedded.inc - -# Save the initial number of concurrent sessions ---source include/count_sessions.inc +--source include/not_embedded.inc --source include/default_optimizer_switch.inc set GLOBAL sql_mode=""; @@ -261,5 +258,3 @@ DROP DATABASE privtest_db; set GLOBAL sql_mode=default; set LOCAL sql_mode=default; -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/grant_kill.result b/mysql-test/main/grant_kill.result index 39a7e8fd5cb30..fbae4de436b44 100644 --- a/mysql-test/main/grant_kill.result +++ b/mysql-test/main/grant_kill.result @@ -14,11 +14,9 @@ GRANT ALL PRIVILEGES ON *.* TO bar@localhost; REVOKE CONNECTION ADMIN ON *.* FROM bar@localhost; connect foo,localhost,foo,,; connect bar,localhost,bar,,; -SELECT user FROM information_schema.processlist ORDER BY user; +SELECT user FROM information_schema.processlist WHERE id=$id; user -bar foo -root KILL ID; ERROR HY000: You are not owner of thread ID disconnect foo; @@ -35,17 +33,13 @@ CREATE USER bar@localhost; GRANT PROCESS, CONNECTION ADMIN ON *.* TO bar@localhost; connect foo,localhost,foo,,; connect bar,localhost,bar,,; -SELECT user FROM information_schema.processlist ORDER BY user; +SELECT user FROM information_schema.processlist WHERE id=$id; user -bar foo -root KILL ID; connection default; disconnect foo; disconnect bar; DROP USER foo@localhost; DROP USER bar@localhost; -# # End of 10.5 tests -# diff --git a/mysql-test/main/grant_kill.test b/mysql-test/main/grant_kill.test index 4cd7a84d18d90..1e249536c755d 100644 --- a/mysql-test/main/grant_kill.test +++ b/mysql-test/main/grant_kill.test @@ -9,8 +9,6 @@ --echo # --disable_service_connection ---let $count_sessions=1 - --echo # --echo # Test that KILL is not allowed without CONNECTION ADMIN --echo # @@ -21,16 +19,15 @@ CREATE USER bar@localhost; GRANT ALL PRIVILEGES ON *.* TO bar@localhost; REVOKE CONNECTION ADMIN ON *.* FROM bar@localhost; --connect (foo,localhost,foo,,) -let $id=`(SELECT id FROM INFORMATION_SCHEMA.PROCESSLIST WHERE user='foo')`; +let $id=`select connection_id()`; --connect (bar,localhost,bar,,) -SELECT user FROM information_schema.processlist ORDER BY user; +evalp SELECT user FROM information_schema.processlist WHERE id=$id; --replace_result $id ID --error ER_KILL_DENIED_ERROR --eval KILL $id --disconnect foo --disconnect bar --connection default ---source include/wait_until_count_sessions.inc DROP USER foo@localhost; DROP USER bar@localhost; @@ -43,9 +40,9 @@ GRANT SELECT ON *.* TO foo@localhost; CREATE USER bar@localhost; GRANT PROCESS, CONNECTION ADMIN ON *.* TO bar@localhost; --connect (foo,localhost,foo,,) -let $id=`(SELECT id FROM INFORMATION_SCHEMA.PROCESSLIST WHERE user='foo')`; +let $id=`select connection_id()`; --connect (bar,localhost,bar,,) -SELECT user FROM information_schema.processlist ORDER BY user; +evalp SELECT user FROM information_schema.processlist WHERE id=$id; --replace_result $id ID --eval KILL $id --connection default @@ -55,12 +52,9 @@ let $wait_condition= --source include/wait_condition.inc --disconnect foo --disconnect bar ---source include/wait_until_count_sessions.inc DROP USER foo@localhost; DROP USER bar@localhost; --enable_service_connection ---echo # --echo # End of 10.5 tests ---echo # diff --git a/mysql-test/main/grant_lowercase.test b/mysql-test/main/grant_lowercase.test index ee85bb592d320..02963816a2646 100644 --- a/mysql-test/main/grant_lowercase.test +++ b/mysql-test/main/grant_lowercase.test @@ -1,5 +1,6 @@ # test cases for strmov(tmp_db, db) -> strnmov replacement in sql_acl.cc --source include/not_embedded.inc +--source include/have_lowercase1.inc # # http://seclists.org/fulldisclosure/2012/Dec/4 diff --git a/mysql-test/main/grant_master_admin.result b/mysql-test/main/grant_master_admin.result index bd08ade940c9c..7b68551b8ac7b 100644 --- a/mysql-test/main/grant_master_admin.result +++ b/mysql-test/main/grant_master_admin.result @@ -30,6 +30,7 @@ connection con1; SHOW SLAVE HOSTS; Server_id Host Port Master_id connection default; +disconnect con1; DROP USER user1@localhost; # # End of 10.5 tests diff --git a/mysql-test/main/grant_master_admin.test b/mysql-test/main/grant_master_admin.test index c98c374f7e93f..adb64a8701298 100644 --- a/mysql-test/main/grant_master_admin.test +++ b/mysql-test/main/grant_master_admin.test @@ -39,9 +39,9 @@ connection con1; SHOW SLAVE HOSTS; connection default; +disconnect con1; DROP USER user1@localhost; - --echo # --echo # End of 10.5 tests --echo # diff --git a/mysql-test/main/grant_repair.result b/mysql-test/main/grant_repair.result index 6ebe043e4d4e9..565450047493e 100644 --- a/mysql-test/main/grant_repair.result +++ b/mysql-test/main/grant_repair.result @@ -1,3 +1,6 @@ +# +# MDEV-20257 Server crashes in Grant_table_base::init_read_record upon crash-upgrade +# call mtr.add_suppression("mysql.user"); # switching from mysql.global_priv to mysql.user flush tables; @@ -7,3 +10,90 @@ Error 145 Got error '145 "Table was marked as crashed and should be repaired"' f Warning 1034 12544 clients are using or haven't closed the table properly Note 1034 Table is fixed # switching back from mysql.user to mysql.global_priv +# +# MDEV-28128 SIGSEGV in replace_column_table on GRANT +# +call mtr.add_suppression("The table is probably corrupted"); +create user a@localhost; +rename table mysql.columns_priv to mysql.columns_priv_bak; +create table mysql.columns_priv select * from mysql.columns_priv_bak; +create table t (c int); +grant update (c) on t to a@localhost; +ERROR HY000: Cannot load from mysql.columns_priv. The table is probably corrupted +drop table t; +drop table mysql.columns_priv; +rename table mysql.columns_priv_bak to mysql.columns_priv; +drop user a@localhost; +# +# MDEV-23731 SIGSEGV in replace_user_table when changing mysql db tables +# +rename table mysql.global_priv to mysql.global_priv_bak; +rename table mysql.user to mysql.user_bak; +create table mysql.user (host char(100), user char(100)) engine=merge; +alter user 'a' identified by ''; +ERROR HY000: Cannot load from mysql.user. The table is probably corrupted +drop table mysql.user; +rename table mysql.global_priv_bak to mysql.global_priv; +rename table mysql.user_bak to mysql.user; +# +# MDEV-24206 SIGSEGV in replace_db_table on GRANT +# +rename table mysql.db to mysql.db_bak; +create table mysql.db engine=memory select * from mysql.db_bak; +grant select on mysql.* to 'a'@'a' identified by 'a'; +ERROR HY000: Cannot load from mysql.db. The table is probably corrupted +drop table mysql.db; +rename table mysql.db_bak to mysql.db; +# +# MDEV-24814 SIGSEGV in replace_table_table on GRANT +# +create user m@localhost; +rename table mysql.tables_priv to mysql.tables_priv_bak; +create table t (c int); +create table mysql.tables_priv select * from mysql.tables_priv_bak; +grant select on t to m@localhost; +ERROR HY000: Cannot load from mysql.tables_priv. The table is probably corrupted +drop table mysql.tables_priv; +rename table mysql.tables_priv_bak to mysql.tables_priv; +drop user m@localhost; +drop table t; +# +# MDEV-27842 SIGSEGV in replace_routine_table on GRANT +# +create user a@b; +set global log_bin_trust_function_creators=1; +rename table mysql.procs_priv to mysql.procs_priv_bak; +create table mysql.procs_priv (dummy int); +create function f() returns int return (select 1 t); +grant execute on function f to a@b; +ERROR HY000: Cannot load from mysql.procs_priv. The table is probably corrupted +drop table mysql.procs_priv; +rename table mysql.procs_priv_bak to mysql.procs_priv; +drop function f; +drop user a@b; +# +# MDEV-27893 SIGSEGV in replace_proxies_priv_table on GRANT PROXY +# +rename table mysql.proxies_priv to mysql.proxies_priv_bak; +create table mysql.proxies_priv select * from mysql.proxies_priv_bak; +grant proxy on grant_plug to grant_plug_dest; +ERROR HY000: Cannot load from mysql.proxies_priv. The table is probably corrupted +drop table mysql.proxies_priv; +rename table mysql.proxies_priv_bak to mysql.proxies_priv; +# +# MDEV-28773 SIGSEGV in TABLE::use_all_columns, replace_roles_mapping_table +# +rename table mysql.roles_mapping to mysql.roles_mapping_bak; +create role r1; +drop role r1; +rename table mysql.roles_mapping_bak to mysql.roles_mapping; +# +# MDEV-28482 SIGSEGV in get_access_value_from_val_int +# +create temporary table t1 select * from mysql.tables_priv; +alter table mysql.tables_priv drop column timestamp; +flush privileges; +ERROR HY000: Cannot load from mysql.tables_priv. The table is probably corrupted +alter table mysql.tables_priv add column Timestamp timestamp not null default now() on update now() after grantor; +replace mysql.tables_priv select * from t1; +# End of 10.11 tests diff --git a/mysql-test/main/grant_repair.test b/mysql-test/main/grant_repair.test index f07e4df3ae6ab..eb2b6ebb587fe 100644 --- a/mysql-test/main/grant_repair.test +++ b/mysql-test/main/grant_repair.test @@ -1,6 +1,6 @@ -# -# MDEV-20257 Server crashes in Grant_table_base::init_read_record upon crash-upgrade -# +--echo # +--echo # MDEV-20257 Server crashes in Grant_table_base::init_read_record upon crash-upgrade +--echo # source include/not_embedded.inc; call mtr.add_suppression("mysql.user"); @@ -19,3 +19,99 @@ replace_result \\ /; flush privileges; source include/switch_to_mysql_global_priv.inc; + +--echo # +--echo # MDEV-28128 SIGSEGV in replace_column_table on GRANT +--echo # +call mtr.add_suppression("The table is probably corrupted"); +create user a@localhost; +rename table mysql.columns_priv to mysql.columns_priv_bak; +create table mysql.columns_priv select * from mysql.columns_priv_bak; +create table t (c int); +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +grant update (c) on t to a@localhost; +drop table t; +drop table mysql.columns_priv; +rename table mysql.columns_priv_bak to mysql.columns_priv; +drop user a@localhost; + +--echo # +--echo # MDEV-23731 SIGSEGV in replace_user_table when changing mysql db tables +--echo # +rename table mysql.global_priv to mysql.global_priv_bak; +rename table mysql.user to mysql.user_bak; +create table mysql.user (host char(100), user char(100)) engine=merge; +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +alter user 'a' identified by ''; +drop table mysql.user; +rename table mysql.global_priv_bak to mysql.global_priv; +rename table mysql.user_bak to mysql.user; + +--echo # +--echo # MDEV-24206 SIGSEGV in replace_db_table on GRANT +--echo # +rename table mysql.db to mysql.db_bak; +create table mysql.db engine=memory select * from mysql.db_bak; +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +grant select on mysql.* to 'a'@'a' identified by 'a'; +drop table mysql.db; +rename table mysql.db_bak to mysql.db; + +--echo # +--echo # MDEV-24814 SIGSEGV in replace_table_table on GRANT +--echo # +create user m@localhost; +rename table mysql.tables_priv to mysql.tables_priv_bak; +create table t (c int); +create table mysql.tables_priv select * from mysql.tables_priv_bak; +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +grant select on t to m@localhost; +drop table mysql.tables_priv; +rename table mysql.tables_priv_bak to mysql.tables_priv; +drop user m@localhost; +drop table t; + +--echo # +--echo # MDEV-27842 SIGSEGV in replace_routine_table on GRANT +--echo # +create user a@b; +set global log_bin_trust_function_creators=1; +rename table mysql.procs_priv to mysql.procs_priv_bak; +create table mysql.procs_priv (dummy int); +create function f() returns int return (select 1 t); +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +grant execute on function f to a@b; +drop table mysql.procs_priv; +rename table mysql.procs_priv_bak to mysql.procs_priv; +drop function f; +drop user a@b; + +--echo # +--echo # MDEV-27893 SIGSEGV in replace_proxies_priv_table on GRANT PROXY +--echo # +rename table mysql.proxies_priv to mysql.proxies_priv_bak; +create table mysql.proxies_priv select * from mysql.proxies_priv_bak; +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +grant proxy on grant_plug to grant_plug_dest; +drop table mysql.proxies_priv; +rename table mysql.proxies_priv_bak to mysql.proxies_priv; + +--echo # +--echo # MDEV-28773 SIGSEGV in TABLE::use_all_columns, replace_roles_mapping_table +--echo # +rename table mysql.roles_mapping to mysql.roles_mapping_bak; +create role r1; +drop role r1; +rename table mysql.roles_mapping_bak to mysql.roles_mapping; + +--echo # +--echo # MDEV-28482 SIGSEGV in get_access_value_from_val_int +--echo # +create temporary table t1 select * from mysql.tables_priv; +alter table mysql.tables_priv drop column timestamp; +--error ER_CANNOT_LOAD_FROM_TABLE_V2 +flush privileges; +alter table mysql.tables_priv add column Timestamp timestamp not null default now() on update now() after grantor; +replace mysql.tables_priv select * from t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/grant_utf8_cli.result b/mysql-test/main/grant_utf8_cli.result index fedfaf984b2bb..93f62747f54bc 100644 --- a/mysql-test/main/grant_utf8_cli.result +++ b/mysql-test/main/grant_utf8_cli.result @@ -3,6 +3,5 @@ create user юзер_юзер@localhost; grant select on test.* to юзер_юзер@localhost; user() юзер_юзер@localhost -revoke all on test.* from юзер_юзер@localhost; drop user юзер_юзер@localhost; set names default; diff --git a/mysql-test/main/grant_utf8_cli.test b/mysql-test/main/grant_utf8_cli.test index bc811d5298e02..58e3bb5379732 100644 --- a/mysql-test/main/grant_utf8_cli.test +++ b/mysql-test/main/grant_utf8_cli.test @@ -8,6 +8,7 @@ set names utf8; create user юзер_юзер@localhost; grant select on test.* to юзер_юзер@localhost; --exec $MYSQL --default-character-set=utf8 --user=юзер_юзер -e "select user()" -revoke all on test.* from юзер_юзер@localhost; +--disable_warnings drop user юзер_юзер@localhost; +--enable_warnings set names default; diff --git a/mysql-test/main/group_by.result b/mysql-test/main/group_by.result index 1a6a30919f792..57a3cf97e94eb 100644 --- a/mysql-test/main/group_by.result +++ b/mysql-test/main/group_by.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; SELECT 1 FROM (SELECT 1) as a GROUP BY SUM(1); ERROR HY000: Invalid use of group function CREATE TABLE t1 ( @@ -3089,10 +3088,8 @@ EXPLAIN } } DROP TABLE t1,t2; -# # End of 10.5 tests # -# # Test new group_min_max optimization # create table t1 (a int, b int, c int, key(a,b,c)); @@ -3123,3 +3120,37 @@ explain select a from t1 where a in (1,2,3) and c=1 group by a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 range a a 5 NULL 1161 Using where; Using index drop table t1; +# End of 11.4 tests +# +# MDEV-38709 ASAN heap-buffer-overflow in my_convert_using_func +# +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES +('LOXRI'),('willing'),('bright'),('behavior'),('RUQIW'),('z'),('RFRYY'), +('KQFQA'),('b'),('ZKUAX'),('l'),('z'),('t-shirt'),('o'),('o'),('c'),('MOUYN'), +('v'),('precise'),('QCOHK'),('c'),('any'),('hers'),('e'),('we'),('mood'), +('AVBWK'),('h'),('frequent'),('AUZDU'),('z'),('sculpture'),('passion'),('n'), +('b'),('sodium'),('j'),('power'),('y'),('CHJYX'),('YYULQ'),('h'),('HRMPR'), +('p'),('a'),('r'),('m'),('s'),('different'),('QABLI'),('s'),('p'),('train'), +('cause'),('MYEFD'),('fierce'),('r'),('l'),('x'),('monthly'),('x'),('t'), +('RQWBD'),('panic'),('HDRLD'),('m'),('j'),('r'),('convert'),('simple'),('y'), +('b'),('f'),('flip'),('l'),('desire'),('film'); +CREATE TABLE t2 (b varchar(1024)); +INSERT INTO t2 VALUES +('c'),('BPYFY'),('i'),('l'),('n'),('programming'),('r'),('then'),('t'), +('MVAUI'),('XQGSK'),('i'),('regret'),('m'),('XIDWZ'),('KORLB'),('agree'), +('relatively'),('frequency'),('certainly'); +SELECT a, b AS b1, b AS b2 FROM t1 JOIN t2 WHERE a IS NOT NULL GROUP BY a, b1, b2 LIMIT 1000,10; +a b1 b2 +v r r +v regret regret +v relatively relatively +v t t +v then then +v XIDWZ XIDWZ +v XQGSK XQGSK +we agree agree +we BPYFY BPYFY +we c c +DROP TABLE t1, t2; +# End of 11.8 tests diff --git a/mysql-test/main/group_by.test b/mysql-test/main/group_by.test index 15278780df901..dd8185bbf21c6 100644 --- a/mysql-test/main/group_by.test +++ b/mysql-test/main/group_by.test @@ -1,14 +1,9 @@ --source include/have_sequence.inc -# Initialise ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings - # # Simple test without tables --- error 1111 +--error ER_INVALID_GROUP_FUNC_USE SELECT 1 FROM (SELECT 1) as a GROUP BY SUM(1); # @@ -83,7 +78,7 @@ CREATE TABLE t1 ( INSERT INTO t1 VALUES (1,'1970-01-01','1997-10-17 00:00:00',2529,1,21000,11886,'check',0,'F',16200,6); ---error 1056 +--error ER_WRONG_GROUP_FIELD SELECT COUNT(P.URID),SUM(P.amount),P.method, MIN(PP.recdate+0) > 19980501000000 AS IsNew FROM t1 AS P JOIN t1 as PP WHERE P.URID = PP.URID GROUP BY method,IsNew; drop table t1; @@ -825,12 +820,12 @@ SET SQL_MODE = ''; # SET SQL_MODE = 'ONLY_FULL_GROUP_BY'; create table t1(f1 int, f2 int); ---error 1055 +--error ER_WRONG_FIELD_WITH_GROUP select * from t1 group by f1; ---error 1055 +--error ER_WRONG_FIELD_WITH_GROUP select * from t1 group by f2; select * from t1 group by f1, f2; ---error 1055 +--error ER_WRONG_FIELD_WITH_GROUP select t1.f1,t.* from t1, t1 t group by 1; drop table t1; SET SQL_MODE = ''; @@ -882,49 +877,49 @@ CREATE TABLE t2 SELECT * FROM t1; SELECT 1 FROM t1 ORDER BY COUNT(*); SELECT 1 FROM t1 ORDER BY COUNT(*) + 1; ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 ORDER BY COUNT(*) + a; SELECT 1 FROM t1 ORDER BY COUNT(*), 1; ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 ORDER BY COUNT(*), a; SELECT 1 FROM t1 ORDER BY SUM(a); SELECT 1 FROM t1 ORDER BY SUM(a + 1); SELECT 1 FROM t1 ORDER BY SUM(a) + 1; ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 ORDER BY SUM(a), b; --disable_service_connection ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT a FROM t1 ORDER BY COUNT(b); SELECT t1.a FROM t1 ORDER BY (SELECT SUM(t2.a) FROM t2); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 ORDER BY (SELECT SUM(t2.a), t2.a FROM t2); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 ORDER BY (SELECT SUM(t2.a) FROM t2 ORDER BY t2.a); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 ORDER BY (SELECT t2.a FROM t2 ORDER BY SUM(t2.b) LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 WHERE t1.a = (SELECT t2.a FROM t2 ORDER BY SUM(t2.b) LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a = (SELECT t2.a FROM t2 ORDER BY SUM(t2.a) LIMIT 1); SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a IN (SELECT t2.a FROM t2 ORDER BY SUM(t1.b)); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a IN (SELECT t2.a FROM t2 ORDER BY t2.a, SUM(t2.b)); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 GROUP BY t1.a HAVING t1.a > ANY (SELECT t2.a FROM t2 ORDER BY t2.a, SUM(t2.b)); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT t1.a FROM t1 WHERE t1.a = (SELECT t2.a FROM t2 ORDER BY SUM(t1.b)); @@ -935,13 +930,13 @@ SELECT 1 FROM t1 GROUP BY t1.a SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(t1.b + t2.b) FROM t2 ORDER BY SUM(t2.a) LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(SUM(t1.b) + 1) FROM t2 ORDER BY t2.a LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(SUM(t1.b) + t2.b) FROM t2 ORDER BY t2.a LIMIT 1); ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS SELECT 1 FROM t1 GROUP BY t1.a HAVING (SELECT AVG(t1.b + t2.b) FROM t2 ORDER BY t2.a LIMIT 1); @@ -981,7 +976,7 @@ from t1 as most_outer; --disable_service_connection ---error 1140 +--error ER_MIX_OF_GROUP_FUNC_AND_FIELDS select avg ( (select ( (select sum(outr.a + innr.a) from t1 as innr limit 1)) as tt @@ -2184,9 +2179,7 @@ explain format=json SELECT 1+0, MIN(t1.a) FROM t1,t2 WHERE t2.a = rand(); DROP TABLE t1,t2; ---echo # --echo # End of 10.5 tests ---echo # --echo # --echo # Test new group_min_max optimization @@ -2206,3 +2199,34 @@ explain select a,b,c from t1 where (a,b) in ((1,1),(2,2),(3,3)) and c=3 group by explain select a from t1 where a in (1,2,3) and b>1 group by a; explain select a from t1 where a in (1,2,3) and c=1 group by a; drop table t1; + +--echo # End of 11.4 tests + +--echo # +--echo # MDEV-38709 ASAN heap-buffer-overflow in my_convert_using_func +--echo # +CREATE TABLE t1 (a varchar(1024)); +INSERT INTO t1 VALUES +('LOXRI'),('willing'),('bright'),('behavior'),('RUQIW'),('z'),('RFRYY'), +('KQFQA'),('b'),('ZKUAX'),('l'),('z'),('t-shirt'),('o'),('o'),('c'),('MOUYN'), +('v'),('precise'),('QCOHK'),('c'),('any'),('hers'),('e'),('we'),('mood'), +('AVBWK'),('h'),('frequent'),('AUZDU'),('z'),('sculpture'),('passion'),('n'), +('b'),('sodium'),('j'),('power'),('y'),('CHJYX'),('YYULQ'),('h'),('HRMPR'), +('p'),('a'),('r'),('m'),('s'),('different'),('QABLI'),('s'),('p'),('train'), +('cause'),('MYEFD'),('fierce'),('r'),('l'),('x'),('monthly'),('x'),('t'), +('RQWBD'),('panic'),('HDRLD'),('m'),('j'),('r'),('convert'),('simple'),('y'), +('b'),('f'),('flip'),('l'),('desire'),('film'); + +CREATE TABLE t2 (b varchar(1024)); +INSERT INTO t2 VALUES +('c'),('BPYFY'),('i'),('l'),('n'),('programming'),('r'),('then'),('t'), +('MVAUI'),('XQGSK'),('i'),('regret'),('m'),('XIDWZ'),('KORLB'),('agree'), +('relatively'),('frequency'),('certainly'); + +SELECT a, b AS b1, b AS b2 FROM t1 JOIN t2 WHERE a IS NOT NULL GROUP BY a, b1, b2 LIMIT 1000,10; + +DROP TABLE t1, t2; + +--echo # End of 11.8 tests + + diff --git a/mysql-test/main/group_min_max.result b/mysql-test/main/group_min_max.result index 6859cce1b5c9c..b7b75fa0ce19f 100644 --- a/mysql-test/main/group_min_max.result +++ b/mysql-test/main/group_min_max.result @@ -2465,7 +2465,7 @@ EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE EXISTS (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t1_outer index NULL a 10 NULL 15 Using index -2 SUBQUERY t1 index NULL a 10 NULL 15 Using index +2 SUBQUERY t1 range a a 5 NULL 6 Using index for group-by EXPLAIN SELECT 1 FROM t1 AS t1_outer WHERE (SELECT max(b) FROM t1 GROUP BY a HAVING a < 2) > 12; id select_type table type possible_keys key key_len ref rows Extra diff --git a/mysql-test/main/group_min_max_innodb.result b/mysql-test/main/group_min_max_innodb.result index 4a6d98a8f3b50..87b718f53ed38 100644 --- a/mysql-test/main/group_min_max_innodb.result +++ b/mysql-test/main/group_min_max_innodb.result @@ -180,7 +180,7 @@ F 17 EXPLAIN SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 ) GROUP BY c1; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE t1 range k1 k1 5 NULL 2 Using where +1 SIMPLE t1 range k1 k1 5 NULL 2 Using where; Using index for group-by SELECT c1, max(i2) FROM t1 WHERE (c1 = 'C' OR c1 = 'F' ) AND ( i2 = 17 ) GROUP BY c1; c1 max(i2) @@ -438,6 +438,43 @@ disconnect con1; connection default; DROP TABLE t1; SET GLOBAL innodb_lru_scan_depth= @lru_depth.save; +# +# MDEV-38426: Clustered PK not used for Loose Index Scan optimization +# +create table t1 ( +col1 int not null, +col2 int not null, +col3 int, +primary key(col1, col2) +) engine=innodb; +insert into t1 select +A.seq, +B.seq, +A.seq +from +seq_1_to_10 A, +seq_1_to_1000 B; +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +# This must use Loose Scan: +explain select distinct col1 from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL PRIMARY 4 NULL 11 Using index for group-by +# This must use Loose Scan: +explain select col1 from t1 group by col1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL PRIMARY 4 NULL 11 Using index for group-by +# This must use Loose Scan: +explain select col1, min(col2) from t1 group by col1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range NULL PRIMARY 4 NULL 11 Using index for group-by +# This will not use Loose Index Scan as col3 is not in PK: +explain select col1, min(col2), col3 from t1 group by col1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL PRIMARY 8 NULL 10000 +drop table t1; set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/group_min_max_innodb.test b/mysql-test/main/group_min_max_innodb.test index 1bddd6ed4bb67..165580a7f8fe4 100644 --- a/mysql-test/main/group_min_max_innodb.test +++ b/mysql-test/main/group_min_max_innodb.test @@ -323,6 +323,40 @@ while ($run) DROP TABLE t1; SET GLOBAL innodb_lru_scan_depth= @lru_depth.save; +--echo # +--echo # MDEV-38426: Clustered PK not used for Loose Index Scan optimization +--echo # +--source include/have_sequence.inc + +create table t1 ( + col1 int not null, + col2 int not null, + col3 int, + primary key(col1, col2) +) engine=innodb; +insert into t1 select + A.seq, + B.seq, + A.seq +from + seq_1_to_10 A, + seq_1_to_1000 B; +analyze table t1; + +--echo # This must use Loose Scan: +explain select distinct col1 from t1; + +--echo # This must use Loose Scan: +explain select col1 from t1 group by col1; + +--echo # This must use Loose Scan: +explain select col1, min(col2) from t1 group by col1; + +--echo # This will not use Loose Index Scan as col3 is not in PK: +explain select col1, min(col2), col3 from t1 group by col1; + +drop table t1; + set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/having.result b/mysql-test/main/having.result index f38839f393e46..9dd63bfdd4ac7 100644 --- a/mysql-test/main/having.result +++ b/mysql-test/main/having.result @@ -1001,3 +1001,22 @@ DROP TABLE t1,t2; # # End of 10.5 tests # +# +# MDEV-35815: Crash in ASAN build due to accessing use-after-poison memory error +# +SET @save_optimizer_trace=@@optimizer_trace; +SET optimizer_trace= 'enabled=on'; +CREATE TABLE t1 (col1 varchar(10)); +INSERT INTO t1 VALUES ('a'), ('b'); +CREATE VIEW v1 AS SELECT concat(col1,'boo') AS view_col FROM t1; +PREPARE stmt FROM 'SELECT view_col AS fld FROM v1 GROUP BY fld HAVING 0 AND fld != 1'; +EXECUTE stmt; +fld +EXECUTE stmt; +fld +DROP TABLE t1; +DROP VIEW v1; +SET optimizer_trace= @save_optimizer_trace; +# +# End of 10.11 tests +# diff --git a/mysql-test/main/having.test b/mysql-test/main/having.test index 98b5ed851fbf7..4b00334d2c40c 100644 --- a/mysql-test/main/having.test +++ b/mysql-test/main/having.test @@ -1056,3 +1056,25 @@ DROP TABLE t1,t2; --echo # --echo # End of 10.5 tests --echo # + +--echo # +--echo # MDEV-35815: Crash in ASAN build due to accessing use-after-poison memory error +--echo # +SET @save_optimizer_trace=@@optimizer_trace; +SET optimizer_trace= 'enabled=on'; + +CREATE TABLE t1 (col1 varchar(10)); +INSERT INTO t1 VALUES ('a'), ('b'); +CREATE VIEW v1 AS SELECT concat(col1,'boo') AS view_col FROM t1; + +PREPARE stmt FROM 'SELECT view_col AS fld FROM v1 GROUP BY fld HAVING 0 AND fld != 1'; + +EXECUTE stmt; +EXECUTE stmt; + +DROP TABLE t1; +DROP VIEW v1; +SET optimizer_trace= @save_optimizer_trace; +--echo # +--echo # End of 10.11 tests +--echo # diff --git a/mysql-test/main/having_cond_pushdown.result b/mysql-test/main/having_cond_pushdown.result index ea6accdc56d86..4f02731164f14 100644 --- a/mysql-test/main/having_cond_pushdown.result +++ b/mysql-test/main/having_cond_pushdown.result @@ -6303,7 +6303,138 @@ INSERT INTO t1 VALUES ('foo'),('bar'); SELECT LOAD_FILE('') AS f, a FROM t1 GROUP BY f, a HAVING f = a; f a DROP TABLE t1; -End of 10.5 tests +# End of 10.5 tests +# +# MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +# +CREATE TABLE t (c INT); +insert into t values (1), (2), (3); +explain format=JSON SELECT * FROM t GROUP BY c HAVING c=c OR TIMESTAMPADD(SECOND, c, AVG(c) IS NULL IS NULL) AND c LIKE (SELECT 1); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.012403489, + "having_condition": "t.c = t.c or (/*always not null*/ 1 is null) + interval t.c second and t.c like 1", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100 + } + } + ] + } + } + } +} +SELECT * FROM t GROUP BY c HAVING c=c OR TIMESTAMPADD(SECOND, c, AVG(c) IS NULL IS NULL) AND c LIKE (SELECT 1); +c +1 +2 +3 +explain format=JSON SELECT c FROM t GROUP BY c HAVING c > 1 AND AVG(c) > 0; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.012403489, + "having_condition": "avg(t.c) > 0", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100, + "attached_condition": "t.c > 1" + } + } + ] + } + } + } +} +SELECT c FROM t GROUP BY c HAVING c > 1 AND AVG(c) > 0; +c +2 +3 +explain format=JSON SELECT c FROM t GROUP BY c HAVING c > 0 AND (c < 10 AND AVG(c) IS NOT NULL); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.012403489, + "having_condition": "avg(t.c) is not null", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100, + "attached_condition": "t.c > 0 and t.c < 10" + } + } + ] + } + } + } +} +SELECT c FROM t GROUP BY c HAVING c > 0 AND (c < 10 AND AVG(c) IS NOT NULL); +c +1 +2 +3 +explain format=JSON SELECT c FROM t GROUP BY c HAVING c = 1 OR AVG(c) > 2; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "cost": 0.012403489, + "having_condition": "t.c = 1 or avg(t.c) > 2", + "filesort": { + "sort_key": "t.c", + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t", + "access_type": "ALL", + "loops": 1, + "rows": 3, + "cost": 0.010504815, + "filtered": 100 + } + } + ] + } + } + } +} +SELECT c FROM t GROUP BY c HAVING c = 1 OR AVG(c) > 2; +c +1 +3 +DROP TABLE t; +# End of 10.6 tests # # MDEV-19269 Pushdown into IN subquery is not made on the second # execution of stmt @@ -6465,4 +6596,4 @@ EXPLAIN } } drop table t1, t2; -End of 10.11 tests +# End of 10.11 tests diff --git a/mysql-test/main/having_cond_pushdown.test b/mysql-test/main/having_cond_pushdown.test index faf6e51192163..0a20a32943d14 100644 --- a/mysql-test/main/having_cond_pushdown.test +++ b/mysql-test/main/having_cond_pushdown.test @@ -1750,7 +1750,36 @@ INSERT INTO t1 VALUES ('foo'),('bar'); SELECT LOAD_FILE('') AS f, a FROM t1 GROUP BY f, a HAVING f = a; DROP TABLE t1; ---echo End of 10.5 tests +--echo # End of 10.5 tests + +--echo # +--echo # MDEV-38487: Prevent aggregate functions cloning when pushing HAVING into WHERE +--echo # + +CREATE TABLE t (c INT); +insert into t values (1), (2), (3); +--disable_warnings +let $q= SELECT * FROM t GROUP BY c HAVING c=c OR TIMESTAMPADD(SECOND, c, AVG(c) IS NULL IS NULL) AND c LIKE (SELECT 1); +eval explain format=JSON $q; +eval $q; +--enable_warnings + +# Tests to verify all possible conditions are pushed except aggregate function +let $q= SELECT c FROM t GROUP BY c HAVING c > 1 AND AVG(c) > 0; +eval explain format=JSON $q; +eval $q; + +let $q= SELECT c FROM t GROUP BY c HAVING c > 0 AND (c < 10 AND AVG(c) IS NOT NULL); +eval explain format=JSON $q; +eval $q; + +let $q= SELECT c FROM t GROUP BY c HAVING c = 1 OR AVG(c) > 2; +eval explain format=JSON $q; +eval $q; + +DROP TABLE t; + +--echo # End of 10.6 tests --echo # --echo # MDEV-19269 Pushdown into IN subquery is not made on the second @@ -1778,4 +1807,4 @@ execute stmt; drop table t1, t2; ---echo End of 10.11 tests +--echo # End of 10.11 tests diff --git a/mysql-test/main/host_cache_size_functionality.test b/mysql-test/main/host_cache_size_functionality.test index 3f97787248c35..35220e62c141b 100644 --- a/mysql-test/main/host_cache_size_functionality.test +++ b/mysql-test/main/host_cache_size_functionality.test @@ -122,59 +122,4 @@ SELECT COUNT(@@GLOBAL.Host_Cache_Size); SELECT Host_Cache_Size = @@SESSION.Host_Cache_Size; --echo Expected error 'Unknown column Host_Cache_Size in field list' -#The below check has been commented out as the IP fetch is different in a P2P connection than BroadBand connection -#--echo '#---------------------WL6372_VAR_6_06----------------------#' -############################################################################### -# Checking the Host cache functionality # -############################################################################### - -#SET @@GLOBAL.Host_Cache_Size=2; -#--disable_warnings - -#--perl -#my $ip=`ifconfig | egrep "inet addr|inet" | sed -e 's/^.*inet addr://' -e 's/^.*inet//'| sed 's/ .*\$//'|egrep -i "broadcast|bcast"|head -1|awk '{print $1}'`; -#open (LOGFH, ">" . $ENV{'MYSQL_TMP_DIR'} . "/bind_ip"); -#print LOGFH "let \$bind_ip = $ip;\n"; -#close LOGFH; -#EOF - -#--source $MYSQL_TMP_DIR/bind_ip -#--remove_file $MYSQL_TMP_DIR/bind_ip - -#let $restart_file= $MYSQLTEST_VARDIR/tmp/mysqld.1.expect; -#--write_line wait $restart_file -#--shutdown_server -#--source include/wait_until_disconnected.inc -#-- write_line "restart:--bind-address=$bind_ip " $MYSQLTEST_VARDIR/tmp/mysqld.1.expect -#-- enable_reconnect -#-- source include/wait_until_connected_again.inc - -#connection default; -#--disable_warnings - -#create user binduser; -#grant all on *.* to binduser; - -#select count(IP) from performance_schema.host_cache; -#--echo 0 Expected - -#connect (con1,$bind_ip,binduser,,); -#select count(IP) from performance_schema.host_cache; -#--echo 1 Expected - -#disconnect con1; -#connection default; - -#--disable_warnings - -# The below check is hashed until the BUG14689561# is fixed -# -#flush hosts; - -#connect (con2,$bind_ip,binduser,,); -#select count(IP) from performance_schema.host_cache; -#--echo 1 Expected - -#disconnect con2; - SET @@GLOBAL.Host_Cache_Size=DEFAULT; diff --git a/mysql-test/main/index_intersect.result b/mysql-test/main/index_intersect.result index 50a013e7f13eb..50ebcba2ccd66 100644 --- a/mysql-test/main/index_intersect.result +++ b/mysql-test/main/index_intersect.result @@ -973,3 +973,69 @@ f1 f4 f5 DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION optimizer_switch='rowid_filter=default'; +# +# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on +# +CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d)); +INSERT INTO t1 +SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +set optimizer_switch='index_merge_sort_intersection=on'; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status Table is already up to date +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +drop table t1; +## MDEV-28878 case +CREATE TABLE t1 (f int); +INSERT INTO t1 VALUES (0),(4); +CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b)); +INSERT INTO t2 VALUES +(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'), +(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'), +(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m'); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +SET optimizer_switch='rowid_filter=on'; +SET optimizer_switch='index_merge_sort_intersection=off'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +DROP TABLE t1, t2; diff --git a/mysql-test/main/index_intersect.test b/mysql-test/main/index_intersect.test index 2726c84342d56..f55b224604104 100644 --- a/mysql-test/main/index_intersect.test +++ b/mysql-test/main/index_intersect.test @@ -476,3 +476,52 @@ DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION optimizer_switch='rowid_filter=default'; + +--echo # +--echo # MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on +--echo # +--source include/have_sequence.inc +CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d)); +INSERT INTO t1 + SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ; + +let $query= +select a, b, c from t1 where a=1000 and b=1001000; + +eval explain $query; +eval $query; + +set optimizer_switch='index_merge_sort_intersection=on'; + +eval explain $query; +eval $query; + +analyze table t1; + +eval explain $query; +eval $query; + +drop table t1; + +--echo ## MDEV-28878 case + +CREATE TABLE t1 (f int); +INSERT INTO t1 VALUES (0),(4); + +CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b)); +INSERT INTO t2 VALUES + (1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'), + (6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'), + (11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m'); + +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; + +SET optimizer_switch='rowid_filter=on'; # Default + +SET optimizer_switch='index_merge_sort_intersection=off'; # Default +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; + +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; + +DROP TABLE t1, t2; diff --git a/mysql-test/main/index_intersect_innodb.result b/mysql-test/main/index_intersect_innodb.result index 9ce05a97b9027..2cd6c9c913e4b 100644 --- a/mysql-test/main/index_intersect_innodb.result +++ b/mysql-test/main/index_intersect_innodb.result @@ -485,7 +485,7 @@ SELECT * FROM City WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 AND Country BETWEEN 'S' AND 'Z'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population 4,4 NULL # Using sort_intersect(PRIMARY,Population); Using where +1 SIMPLE City range PRIMARY,Population,Country PRIMARY 4 NULL # Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 @@ -979,6 +979,72 @@ f1 f4 f5 DROP TABLE t1; SET SESSION optimizer_switch='index_merge_sort_intersection=on'; SET SESSION optimizer_switch='rowid_filter=default'; +# +# MDEV-38327 wrong result with index_merge_sort_intersection and rowid_filter=on +# +CREATE TABLE t1 (c int, b int, a int , d int, PRIMARY KEY (c), KEY ib (b), KEY iad (a,d)); +INSERT INTO t1 +SELECT seq + 1000000, FLOOR(seq / 5) % 1350 + 1000000, FLOOR(seq / 5) % 1350 , seq % 10 FROM seq_1_to_7000 ; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +set optimizer_switch='index_merge_sort_intersection=on'; +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +analyze table t1; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +explain select a, b, c from t1 where a=1000 and b=1001000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index_merge ib,iad ib,iad 5,5 NULL 1 Using sort_intersect(ib,iad); Using where +select a, b, c from t1 where a=1000 and b=1001000; +a b c +1000 1001000 1005000 +1000 1001000 1005001 +1000 1001000 1005002 +1000 1001000 1005003 +1000 1001000 1005004 +drop table t1; +## MDEV-28878 case +CREATE TABLE t1 (f int); +INSERT INTO t1 VALUES (0),(4); +CREATE TABLE t2 (pk int, a int, b varchar(10), PRIMARY KEY (pk), KEY a (a), KEY b (b)); +INSERT INTO t2 VALUES +(1,2,'v'),(2,3,'p'),(3,4,'p'),(4,2,'y'),(5,7,'q'), +(6,4,'a'),(7,1,'d'),(8,5,'a'),(9,5,'z'),(10,1,'t'), +(11,1,'y'),(12,5,'o'),(13,4,'a'),(14,5,'s'),(15,5,'m'); +ANALYZE TABLE t1, t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +SET optimizer_switch='rowid_filter=on'; +SET optimizer_switch='index_merge_sort_intersection=off'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +SET optimizer_switch='index_merge_sort_intersection=on'; +SELECT * FROM t1 JOIN t2 ON t1.f = t2.a WHERE t2.b >= 'j' AND t2.a != 5; +f pk a b +4 3 4 p +DROP TABLE t1, t2; set global innodb_stats_persistent= @innodb_stats_persistent_save; set global innodb_stats_persistent_sample_pages= @innodb_stats_persistent_sample_pages_save; diff --git a/mysql-test/main/information_schema-big.result b/mysql-test/main/information_schema-big.result index cad4078deb565..4688a2d1f640d 100644 --- a/mysql-test/main/information_schema-big.result +++ b/mysql-test/main/information_schema-big.result @@ -62,6 +62,7 @@ TABLESPACES TABLESPACE_NAME TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA TABLE_STATISTICS TABLE_SCHEMA +TRIGGERED_UPDATE_COLUMNS TRIGGER_SCHEMA TRIGGERS TRIGGER_SCHEMA USERS USER USER_PRIVILEGES GRANTEE @@ -128,6 +129,7 @@ TABLESPACES TABLESPACE_NAME TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA TABLE_STATISTICS TABLE_SCHEMA +TRIGGERED_UPDATE_COLUMNS TRIGGER_SCHEMA TRIGGERS TRIGGER_SCHEMA USERS USER USER_PRIVILEGES GRANTEE diff --git a/mysql-test/main/information_schema-big_embedded.result b/mysql-test/main/information_schema-big_embedded.result index 839f84cd5ee4a..4b3ad78f997d9 100644 --- a/mysql-test/main/information_schema-big_embedded.result +++ b/mysql-test/main/information_schema-big_embedded.result @@ -61,6 +61,7 @@ TABLESPACES TABLESPACE_NAME TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA TABLE_STATISTICS TABLE_SCHEMA +TRIGGERED_UPDATE_COLUMNS TRIGGER_SCHEMA TRIGGERS TRIGGER_SCHEMA USERS USER USER_PRIVILEGES GRANTEE @@ -126,6 +127,7 @@ TABLESPACES TABLESPACE_NAME TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA TABLE_STATISTICS TABLE_SCHEMA +TRIGGERED_UPDATE_COLUMNS TRIGGER_SCHEMA TRIGGERS TRIGGER_SCHEMA USERS USER USER_PRIVILEGES GRANTEE diff --git a/mysql-test/main/information_schema.result b/mysql-test/main/information_schema.result index 8708f542fba33..547e5fea00af0 100644 --- a/mysql-test/main/information_schema.result +++ b/mysql-test/main/information_schema.result @@ -1,7 +1,5 @@ set global sql_mode=""; set local sql_mode=""; -DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5; -DROP VIEW IF EXISTS v1; show variables where variable_name like "skip_show_database"; Variable_name Value skip_show_database OFF @@ -97,6 +95,7 @@ TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERS USERS USER_PRIVILEGES @@ -146,6 +145,7 @@ TABLESPACES TABLESPACES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_STATISTICS TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERED_UPDATE_COLUMNS TRIGGERS TRIGGERS t1 t1 t2 t2 @@ -169,6 +169,7 @@ TABLESPACES TABLESPACES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_STATISTICS TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERED_UPDATE_COLUMNS TRIGGERS TRIGGERS t1 t1 t2 t2 @@ -192,6 +193,7 @@ TABLESPACES TABLESPACES TABLE_CONSTRAINTS TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_PRIVILEGES TABLE_STATISTICS TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERED_UPDATE_COLUMNS TRIGGERS TRIGGERS t1 t1 t2 t2 @@ -281,41 +283,41 @@ Charset Description Default collation Maxlen latin1 cp1252 West European latin1_swedish_ci 1 select * from information_schema.COLLATIONS where COLLATION_NAME like 'latin1%'; -COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN COMMENT -latin1_german1_ci latin1 5 # 1 cp1252 West European -latin1_swedish_ci latin1 8 Yes # 1 cp1252 West European -latin1_danish_ci latin1 15 # 1 cp1252 West European -latin1_german2_ci latin1 31 # 2 cp1252 West European -latin1_bin latin1 47 # 1 cp1252 West European -latin1_general_ci latin1 48 # 1 cp1252 West European -latin1_general_cs latin1 49 # 1 cp1252 West European -latin1_spanish_ci latin1 94 # 1 cp1252 West European -latin1_swedish_nopad_ci latin1 1032 # 1 -latin1_nopad_bin latin1 1071 # 1 +COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN PAD_ATTRIBUTE COMMENT +latin1_german1_ci latin1 5 # 1 PAD SPACE cp1252 West European +latin1_swedish_ci latin1 8 Yes # 1 PAD SPACE cp1252 West European +latin1_danish_ci latin1 15 # 1 PAD SPACE cp1252 West European +latin1_german2_ci latin1 31 # 2 PAD SPACE cp1252 West European +latin1_bin latin1 47 # 1 PAD SPACE cp1252 West European +latin1_general_ci latin1 48 # 1 PAD SPACE cp1252 West European +latin1_general_cs latin1 49 # 1 PAD SPACE cp1252 West European +latin1_spanish_ci latin1 94 # 1 PAD SPACE cp1252 West European +latin1_swedish_nopad_ci latin1 1032 # 1 NO PAD +latin1_nopad_bin latin1 1071 # 1 NO PAD SHOW COLLATION LIKE 'latin1%'; -Collation Charset Id Default Compiled Sortlen -latin1_german1_ci latin1 5 # 1 -latin1_swedish_ci latin1 8 Yes # 1 -latin1_danish_ci latin1 15 # 1 -latin1_german2_ci latin1 31 # 2 -latin1_bin latin1 47 # 1 -latin1_general_ci latin1 48 # 1 -latin1_general_cs latin1 49 # 1 -latin1_spanish_ci latin1 94 # 1 -latin1_swedish_nopad_ci latin1 1032 # 1 -latin1_nopad_bin latin1 1071 # 1 +Collation Charset Id Default Compiled Sortlen Pad_attribute +latin1_german1_ci latin1 5 # 1 PAD SPACE +latin1_swedish_ci latin1 8 Yes # 1 PAD SPACE +latin1_danish_ci latin1 15 # 1 PAD SPACE +latin1_german2_ci latin1 31 # 2 PAD SPACE +latin1_bin latin1 47 # 1 PAD SPACE +latin1_general_ci latin1 48 # 1 PAD SPACE +latin1_general_cs latin1 49 # 1 PAD SPACE +latin1_spanish_ci latin1 94 # 1 PAD SPACE +latin1_swedish_nopad_ci latin1 1032 # 1 NO PAD +latin1_nopad_bin latin1 1071 # 1 NO PAD SHOW COLLATION WHERE collation like 'latin1%'; -Collation Charset Id Default Compiled Sortlen -latin1_german1_ci latin1 5 # 1 -latin1_swedish_ci latin1 8 Yes # 1 -latin1_danish_ci latin1 15 # 1 -latin1_german2_ci latin1 31 # 2 -latin1_bin latin1 47 # 1 -latin1_general_ci latin1 48 # 1 -latin1_general_cs latin1 49 # 1 -latin1_spanish_ci latin1 94 # 1 -latin1_swedish_nopad_ci latin1 1032 # 1 -latin1_nopad_bin latin1 1071 # 1 +Collation Charset Id Default Compiled Sortlen Pad_attribute +latin1_german1_ci latin1 5 # 1 PAD SPACE +latin1_swedish_ci latin1 8 Yes # 1 PAD SPACE +latin1_danish_ci latin1 15 # 1 PAD SPACE +latin1_german2_ci latin1 31 # 2 PAD SPACE +latin1_bin latin1 47 # 1 PAD SPACE +latin1_general_ci latin1 48 # 1 PAD SPACE +latin1_general_cs latin1 49 # 1 PAD SPACE +latin1_spanish_ci latin1 94 # 1 PAD SPACE +latin1_swedish_nopad_ci latin1 1032 # 1 NO PAD +latin1_nopad_bin latin1 1071 # 1 NO PAD select * from information_schema.COLLATION_CHARACTER_SET_APPLICABILITY where COLLATION_NAME like 'latin1%'; COLLATION_NAME CHARACTER_SET_NAME FULL_COLLATION_NAME ID IS_DEFAULT @@ -701,6 +703,7 @@ proc collation_connection char(64) proc db_collation char(64) proc body_utf8 longblob proc aggregate enum('NONE','GROUP') +proc path text drop table t115; create procedure p108 () begin declare c cursor for select data_type from information_schema.columns; open c; open c; end;// @@ -736,6 +739,7 @@ TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERS create database information_schema; ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' @@ -747,6 +751,7 @@ TABLESPACES SYSTEM VIEW TABLE_CONSTRAINTS SYSTEM VIEW TABLE_PRIVILEGES SYSTEM VIEW TABLE_STATISTICS SYSTEM VIEW +TRIGGERED_UPDATE_COLUMNS SYSTEM VIEW TRIGGERS SYSTEM VIEW create table t1(a int); ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' @@ -761,6 +766,7 @@ TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERS select table_name from tables where table_name='user'; table_name @@ -895,6 +901,7 @@ information_schema EVENTS EVENT_DEFINITION information_schema OPTIMIZER_TRACE QUERY information_schema OPTIMIZER_TRACE TRACE information_schema PARAMETERS DTD_IDENTIFIER +information_schema PARAMETERS PARAMETER_DEFAULT information_schema PARTITIONS PARTITION_EXPRESSION information_schema PARTITIONS SUBPARTITION_EXPRESSION information_schema PARTITIONS PARTITION_DESCRIPTION @@ -1351,9 +1358,8 @@ CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH 9 27 drop table t1; use mysql; -INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL', -'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03', -'2006-03-02 18:40:03','','','utf8','utf8_general_ci','utf8_general_ci','n/a', 'NONE'); +INSERT INTO `proc` (db,type,body,definer,created,modified,character_set_client, collation_connection, db_collation, body_utf8,param_list,returns,comment) +VALUES ('test','PROCEDURE', 'BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03', '2006-03-02 18:40:03', 'utf8','utf8_general_ci','utf8_general_ci','n/a','','',''); select routine_name from information_schema.routines where ROUTINE_SCHEMA='test'; routine_name @@ -1660,7 +1666,7 @@ SELECT * FROM tables ta JOIN collations co ON ( co.collation_name = ta.table_catalog ) JOIN character_sets cs ON ( cs.character_set_name = ta.table_catalog ); -TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN COMMENT CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN +TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY COLLATION_NAME CHARACTER_SET_NAME ID IS_DEFAULT IS_COMPILED SORTLEN PAD_ATTRIBUTE COMMENT CHARACTER_SET_NAME DEFAULT_COLLATE_NAME DESCRIPTION MAXLEN DROP TABLE test.t1; SET max_heap_table_size = DEFAULT; USE test; @@ -2340,13 +2346,8 @@ connection default; disconnect con1; set global sql_mode=default; USE test; -# # End of 10.0 tests # -# -# Start of 10.1 tests -# -# # MDEV-13242 Wrong results for queries with row constructors and information_schema # CREATE TABLE tt1(c1 INT); @@ -2378,10 +2379,8 @@ SELECT SCHEMA_NAME from information_schema.schemata where schema_name='aaaaaaaaa SCHEMA_NAME SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a',193); SCHEMA_NAME -# # End of 10.1 tests # -# # MDEV-14836: Assertion `m_status == DA_ERROR' failed in # Diagnostics_area::sql_errno upon query from I_S with LIMIT ROWS EXAMINED # @@ -2422,10 +2421,8 @@ SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEM TABLE_SCHEMA TABLE_NAME a/~.b t1 DROP DATABASE `a/~.b`; -# # End of 10.2 Test # -# # MDEV-21201:No records produced in information_schema query, # depending on projection # @@ -2563,10 +2560,8 @@ SET SQL_MODE=DEFAULT; select progress from information_schema.processlist limit 1; progress 0.000 -# # End of 10.3 tests # -# # MDEV-MDEV-31064 Changes of the procedure are not immediatly seen in queries to I_S.parameter from other connections # CREATE PROCEDURE sp1(IN p1 INT, IN p2 INT) @@ -2585,13 +2580,8 @@ COUNT(*) disconnect con2; connection default; DROP PROCEDURE sp1; -# # End of 10.4 tests # -# -# Start of 10.5 tests -# -# # MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed # CREATE TABLE t1 (a int); @@ -2606,6 +2596,4 @@ created SET SESSION sql_mode=DEFAULT; DROP VIEW i; DROP TABLE t1; -# # End of 10.5 tests -# diff --git a/mysql-test/main/information_schema.test b/mysql-test/main/information_schema.test index d3c9803b18c27..e80331b4f3ec5 100644 --- a/mysql-test/main/information_schema.test +++ b/mysql-test/main/information_schema.test @@ -1,6 +1,7 @@ # This test uses grants, which can't get tested for embedded server --- source include/not_embedded.inc --- source include/have_perfschema.inc +--source include/not_embedded.inc +--source include/have_perfschema.inc +--source include/have_profiling.inc # check that CSV engine was compiled in, as the result of the test depends # on the presence of the log tables (which are CSV-based). @@ -8,13 +9,9 @@ # Without aria_used_for_temp_tables some I_S tables will be MyISAM, # while the test expects them to be Aria --- source include/have_aria_used_for_temp_tables.inc - --- source include/have_innodb.inc - -# Save the initial number of concurrent sessions ---source include/count_sessions.inc +--source include/have_aria_used_for_temp_tables.inc +--source include/have_innodb.inc --source include/default_optimizer_switch.inc --source include/default_charset.inc @@ -26,12 +23,6 @@ set local sql_mode=""; # Test for information_schema.schemata & # show databases ---disable_warnings -DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5; -DROP VIEW IF EXISTS v1; ---enable_warnings - - show variables where variable_name like "skip_show_database"; grant select, update, execute on test.* to mysqltest_2@localhost; grant select, update on test.* to mysqltest_1@localhost; @@ -872,9 +863,8 @@ drop table t1; # Bug#18177 any access to INFORMATION_SCHEMA.ROUTINES crashes # use mysql; -INSERT INTO `proc` VALUES ('test','','PROCEDURE','','SQL','CONTAINS_SQL', -'NO','DEFINER','','','BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03', -'2006-03-02 18:40:03','','','utf8','utf8_general_ci','utf8_general_ci','n/a', 'NONE'); +INSERT INTO `proc` (db,type,body,definer,created,modified,character_set_client, collation_connection, db_collation, body_utf8,param_list,returns,comment) +VALUES ('test','PROCEDURE', 'BEGIN\r\n \r\nEND','root@%','2006-03-02 18:40:03', '2006-03-02 18:40:03', 'utf8','utf8_general_ci','utf8_general_ci','n/a','','',''); select routine_name from information_schema.routines where ROUTINE_SCHEMA='test'; delete from proc where name=''; use test; @@ -1647,7 +1637,6 @@ connection con1; --echo # Reaping 'flush tables' reap; disconnect con1; ---source include/wait_until_disconnected.inc connection default; drop table t1; drop view v1; @@ -1886,22 +1875,11 @@ drop database db1; connection default; disconnect con1; -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - set global sql_mode=default; USE test; ---echo # --echo # End of 10.0 tests ---echo # - - ---echo # ---echo # Start of 10.1 tests ---echo # - --echo # --echo # MDEV-13242 Wrong results for queries with row constructors and information_schema @@ -1925,9 +1903,7 @@ SELECT SCHEMA_NAME from information_schema.schemata where schema_name='aaaaaaaaa SELECT SCHEMA_NAME from information_schema.schemata where schema_name=REPEAT('a',193); ---echo # --echo # End of 10.1 tests ---echo # --echo # --echo # MDEV-14836: Assertion `m_status == DA_ERROR' failed in @@ -1976,9 +1952,7 @@ CREATE TABLE `a/~.b`.t1 (a INT); SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA='a/~.b'; DROP DATABASE `a/~.b`; ---echo # --echo # End of 10.2 Test ---echo # --echo # --echo # MDEV-21201:No records produced in information_schema query, @@ -2114,9 +2088,7 @@ SET SQL_MODE=DEFAULT; --echo # select progress from information_schema.processlist limit 1; ---echo # --echo # End of 10.3 tests ---echo # --echo # --echo # MDEV-MDEV-31064 Changes of the procedure are not immediatly seen in queries to I_S.parameter from other connections @@ -2136,13 +2108,7 @@ SELECT COUNT(*) FROM information_schema.parameters WHERE SPECIFIC_NAME = 'sp1'; --connection default DROP PROCEDURE sp1; ---echo # --echo # End of 10.4 tests ---echo # - ---echo # ---echo # Start of 10.5 tests ---echo # --echo # --echo # MDEV-26507 Assertion `tmp != ((long long) 0x8000000000000000LL)' failed in TIME_from_longlong_datetime_packed @@ -2160,6 +2126,4 @@ SET SESSION sql_mode=DEFAULT; DROP VIEW i; DROP TABLE t1; ---echo # --echo # End of 10.5 tests ---echo # diff --git a/mysql-test/main/information_schema_all_engines.result b/mysql-test/main/information_schema_all_engines.result index 745d03234e8a2..d2063d6090a45 100644 --- a/mysql-test/main/information_schema_all_engines.result +++ b/mysql-test/main/information_schema_all_engines.result @@ -68,6 +68,7 @@ TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERS USERS USER_PRIVILEGES @@ -155,6 +156,7 @@ TABLESPACES TABLESPACE_NAME TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA TABLE_STATISTICS TABLE_SCHEMA +TRIGGERED_UPDATE_COLUMNS TRIGGER_SCHEMA TRIGGERS TRIGGER_SCHEMA USERS USER USER_PRIVILEGES GRANTEE @@ -242,6 +244,7 @@ TABLESPACES TABLESPACE_NAME TABLE_CONSTRAINTS CONSTRAINT_SCHEMA TABLE_PRIVILEGES TABLE_SCHEMA TABLE_STATISTICS TABLE_SCHEMA +TRIGGERED_UPDATE_COLUMNS TRIGGER_SCHEMA TRIGGERS TRIGGER_SCHEMA USERS USER USER_PRIVILEGES GRANTEE @@ -328,6 +331,7 @@ TABLESPACES information_schema.TABLESPACES 1 TABLE_CONSTRAINTS information_schema.TABLE_CONSTRAINTS 1 TABLE_PRIVILEGES information_schema.TABLE_PRIVILEGES 1 TABLE_STATISTICS information_schema.TABLE_STATISTICS 1 +TRIGGERED_UPDATE_COLUMNS information_schema.TRIGGERED_UPDATE_COLUMNS 1 TRIGGERS information_schema.TRIGGERS 1 USERS information_schema.USERS 1 USER_PRIVILEGES information_schema.USER_PRIVILEGES 1 @@ -405,6 +409,7 @@ Database: information_schema | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | | TABLE_STATISTICS | +| TRIGGERED_UPDATE_COLUMNS | | TRIGGERS | | USERS | | USER_PRIVILEGES | @@ -482,6 +487,7 @@ Database: INFORMATION_SCHEMA | TABLE_CONSTRAINTS | | TABLE_PRIVILEGES | | TABLE_STATISTICS | +| TRIGGERED_UPDATE_COLUMNS | | TRIGGERS | | USERS | | USER_PRIVILEGES | @@ -495,5 +501,5 @@ Wildcard: inf_rmation_schema | information_schema | SELECT table_schema, count(*) FROM information_schema.TABLES WHERE table_schema IN ('mysql', 'INFORMATION_SCHEMA', 'test', 'mysqltest') GROUP BY TABLE_SCHEMA; table_schema count(*) -information_schema 72 +information_schema 73 mysql 31 diff --git a/mysql-test/main/information_schema_db.result b/mysql-test/main/information_schema_db.result index 5a4c3c3ec3c99..00f19ec743bd9 100644 --- a/mysql-test/main/information_schema_db.result +++ b/mysql-test/main/information_schema_db.result @@ -7,6 +7,7 @@ TABLESPACES TABLE_CONSTRAINTS TABLE_PRIVILEGES TABLE_STATISTICS +TRIGGERED_UPDATE_COLUMNS TRIGGERS create database `inf%`; create database mbase; @@ -45,6 +46,7 @@ call mbase.p1(); call mbase.p1(); call mbase.p1(); connection default; +disconnect user1; use `inf%`; drop user mysqltest_1@localhost; drop table t1; @@ -62,7 +64,6 @@ drop function func2; drop database `inf%`; drop procedure mbase.p1; drop database mbase; -disconnect user1; # # Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views # @@ -213,11 +214,8 @@ connection default; use test; drop view testdb_1.v1, v2, testdb_1.v3, v4; drop database testdb_1; -connection testdb_1; disconnect testdb_1; -connection testdb_2; disconnect testdb_2; -connection default; drop user testdb_1@localhost; drop user testdb_2@localhost; # @@ -247,20 +245,20 @@ testdb_1 v1 show create view testdb_1.v1; ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table `testdb_1`.`v1` connection default; +disconnect user1; drop user mysqltest_1@localhost; drop database testdb_1; -connection user1; -disconnect user1; -connection default; set global sql_mode=default; # # MDEV-20549 SQL SECURITY DEFINER does not work for INFORMATION_SCHEMA tables # create user foo@localhost; grant select on test.* to foo@localhost; +connect foo,localhost,foo; +connection default; create procedure rootonly() select 1; -create sql security definer view v1d as select current_user(),user from information_schema.processlist where command!='daemon'; -create sql security invoker view v1i as select current_user(),user from information_schema.processlist where command!='daemon'; +create sql security definer view v1d as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user; +create sql security invoker view v1i as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user; create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%'; @@ -269,7 +267,7 @@ create sql security definer view v4d as select routine_name from information_sch create sql security invoker view v4i as select routine_name from information_schema.routines where routine_schema='test'; create sql security definer view v5d as select view_definition > '' from information_schema.views where table_name='v1d'; create sql security invoker view v5i as select view_definition > '' from information_schema.views where table_name='v1d'; -connect foo,localhost,foo; +connection foo; select * from v1d; current_user() user root@localhost root @@ -367,9 +365,9 @@ select table_name, constraint_name, constraint_type from information_schema.tabl table_name constraint_name constraint_type t3 e UNIQUE t3 CONSTRAINT_1 CHECK -t3 t3_ibfk_1 FOREIGN KEY -t3 t3_ibfk_2 FOREIGN KEY -t3 t3_ibfk_3 FOREIGN KEY +t3 1 FOREIGN KEY +t3 2 FOREIGN KEY +t3 3 FOREIGN KEY show index in t2; Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored show index in t3; @@ -379,9 +377,47 @@ disconnect con1; connection default; drop user u@localhost; drop database db; -# # End of 10.4 tests # +# MDEV-38209 REFERENCES permission on particular schema is sometimes ignored +# +create database db1; +CREATE TABLE db1.author ( +id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +name VARCHAR(100) NOT NULL +) ENGINE = InnoDB; +CREATE TABLE db1.book ( +id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, +title VARCHAR(200) NOT NULL, +author_id SMALLINT UNSIGNED NOT NULL, +CONSTRAINT `fk_book_author` + FOREIGN KEY (author_id) REFERENCES db1.author (id) +ON DELETE CASCADE +ON UPDATE RESTRICT +) ENGINE = InnoDB; +grant select on *.* to u@localhost; +grant select, references on db1.* to u@localhost; +connect u,localhost,u,,db1; +select user(); +user() +u@localhost +show grants; +Grants for u@localhost +GRANT SELECT ON *.* TO `u`@`localhost` +GRANT SELECT, REFERENCES ON `db1`.* TO `u`@`localhost` +select table_name,constraint_name from information_schema.referential_constraints; +table_name constraint_name +book fk_book_author +select table_name,constraint_name from information_schema.table_constraints; +table_name constraint_name +author PRIMARY +book PRIMARY +book fk_book_author +disconnect u; +connection default; +drop user u@localhost; +drop database db1; +# End of 10.11 tests # # MDEV-23729 INFORMATION_SCHEMA Table info. about user locked due to # max_password_errors @@ -477,6 +513,8 @@ USER PASSWORD_ERRORS PASSWORD_EXPIRATION_TIME # Delete user while some connection is still alive, then select. connection default; drop user nice_user; +Warnings: +Note 4227 Dropped users 'nice_user'@'%' have active connections. Use KILL CONNECTION if they should not be used anymore. connection con2; select * from information_schema.users; ERROR 0L000: The current user is invalid @@ -512,4 +550,4 @@ drop user u2@localhost; drop user u3@localhost; drop user u4@localhost; drop user u5@localhost; -# End of 10.0 tests +# End of 11.5 tests diff --git a/mysql-test/main/information_schema_db.test b/mysql-test/main/information_schema_db.test index a7ccf4b6feaf0..c7a7774b763a6 100644 --- a/mysql-test/main/information_schema_db.test +++ b/mysql-test/main/information_schema_db.test @@ -67,6 +67,7 @@ call mbase.p1(); --enable_result_log connection default; +disconnect user1; use `inf%`; drop user mysqltest_1@localhost; drop table t1; @@ -81,7 +82,6 @@ drop function func2; drop database `inf%`; drop procedure mbase.p1; drop database mbase; -disconnect user1; --echo # --echo # Bug#18282 INFORMATION_SCHEMA.TABLES provides inconsistent info about invalid views @@ -207,13 +207,8 @@ connection default; use test; drop view testdb_1.v1, v2, testdb_1.v3, v4; drop database testdb_1; -connection testdb_1; disconnect testdb_1; ---source include/wait_until_disconnected.inc -connection testdb_2; disconnect testdb_2; ---source include/wait_until_disconnected.inc -connection default; drop user testdb_1@localhost; drop user testdb_2@localhost; @@ -242,12 +237,9 @@ where table_name='v1'; show create view testdb_1.v1; connection default; +disconnect user1; drop user mysqltest_1@localhost; drop database testdb_1; -connection user1; -disconnect user1; ---source include/wait_until_disconnected.inc -connection default; set global sql_mode=default; @@ -257,9 +249,13 @@ set global sql_mode=default; create user foo@localhost; grant select on test.* to foo@localhost; +let $default_id= `select connection_id()`; +connect foo,localhost,foo; +let $foo_id= `select connection_id()`; +connection default; create procedure rootonly() select 1; -create sql security definer view v1d as select current_user(),user from information_schema.processlist where command!='daemon'; -create sql security invoker view v1i as select current_user(),user from information_schema.processlist where command!='daemon'; +evalp create sql security definer view v1d as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user; +evalp create sql security invoker view v1i as select current_user(),user from information_schema.processlist where id in($default_id, $foo_id) order by user; create sql security definer view v2d as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security invoker view v2i as select table_name from information_schema.tables where table_schema='mysql' and table_name like '%user%'; create sql security definer view v3d as select schema_name from information_schema.schemata where schema_name like '%mysql%'; @@ -268,7 +264,7 @@ create sql security definer view v4d as select routine_name from information_sch create sql security invoker view v4i as select routine_name from information_schema.routines where routine_schema='test'; create sql security definer view v5d as select view_definition > '' from information_schema.views where table_name='v1d'; create sql security invoker view v5i as select view_definition > '' from information_schema.views where table_name='v1d'; -connect foo,localhost,foo; +connection foo; select * from v1d; select * from v1i; select * from v2d; @@ -329,9 +325,45 @@ show index in t3; drop user u@localhost; drop database db; ---echo # --echo # End of 10.4 tests + --echo # +--echo # MDEV-38209 REFERENCES permission on particular schema is sometimes ignored +--echo # + +create database db1; +CREATE TABLE db1.author ( + id SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100) NOT NULL +) ENGINE = InnoDB; + +CREATE TABLE db1.book ( + id MEDIUMINT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY, + title VARCHAR(200) NOT NULL, + author_id SMALLINT UNSIGNED NOT NULL, + CONSTRAINT `fk_book_author` + FOREIGN KEY (author_id) REFERENCES db1.author (id) + ON DELETE CASCADE + ON UPDATE RESTRICT +) ENGINE = InnoDB; + +grant select on *.* to u@localhost; +grant select, references on db1.* to u@localhost; + +--connect u,localhost,u,,db1 +select user(); +show grants; +--sorted_result +select table_name,constraint_name from information_schema.referential_constraints; +--sorted_result +select table_name,constraint_name from information_schema.table_constraints; +--disconnect u + +--connection default +drop user u@localhost; +drop database db1; + +--echo # End of 10.11 tests --echo # --echo # MDEV-23729 INFORMATION_SCHEMA Table info. about user locked due to @@ -449,4 +481,4 @@ drop user u4@localhost; drop user u5@localhost; --enable_service_connection ---echo # End of 10.0 tests +--echo # End of 11.5 tests diff --git a/mysql-test/main/information_schema_inno.result b/mysql-test/main/information_schema_inno.result index c81631728f03a..520e9a4c8ce8b 100644 --- a/mysql-test/main/information_schema_inno.result +++ b/mysql-test/main/information_schema_inno.result @@ -7,22 +7,22 @@ FOREIGN KEY (id, t2_id) REFERENCES t2(t1_id, id) ON DELETE CASCADE) ENGINE=INNO select * from information_schema.TABLE_CONSTRAINTS where TABLE_SCHEMA= "test"; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE +def test 1 test t2 FOREIGN KEY +def test 1 test t3 FOREIGN KEY +def test 2 test t2 FOREIGN KEY def test PRIMARY test t1 PRIMARY KEY def test PRIMARY test t2 PRIMARY KEY def test PRIMARY test t3 PRIMARY KEY -def test t2_ibfk_1 test t2 FOREIGN KEY -def test t2_ibfk_2 test t2 FOREIGN KEY -def test t3_ibfk_1 test t3 FOREIGN KEY select * from information_schema.KEY_COLUMN_USAGE where TABLE_SCHEMA= "test"; CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME +def test 1 def test t2 t1_id 1 1 test t1 id +def test 1 def test t3 id 1 1 test t2 t1_id +def test 1 def test t3 t2_id 2 2 test t2 id +def test 2 def test t2 t1_id 1 1 test t1 id def test PRIMARY def test t1 id 1 NULL NULL NULL NULL def test PRIMARY def test t2 id 1 NULL NULL NULL NULL def test PRIMARY def test t3 id 1 NULL NULL NULL NULL -def test t2_ibfk_1 def test t2 t1_id 1 1 test t1 id -def test t2_ibfk_2 def test t2 t1_id 1 1 test t1 id -def test t3_ibfk_1 def test t3 id 1 1 test t2 t1_id -def test t3_ibfk_1 def test t3 t2_id 2 2 test t2 id drop table t3, t2, t1; CREATE TABLE t1(a1 INT NOT NULL, a2 INT NOT NULL, PRIMARY KEY(a1, a2)) ENGINE=INNODB; diff --git a/mysql-test/main/information_schema_parameters.result b/mysql-test/main/information_schema_parameters.result index e7a7b1b4658f2..7b4d83f9f9ab3 100644 --- a/mysql-test/main/information_schema_parameters.result +++ b/mysql-test/main/information_schema_parameters.result @@ -18,7 +18,8 @@ PARAMETERS CREATE TEMPORARY TABLE `PARAMETERS` ( `CHARACTER_SET_NAME` varchar(64), `COLLATION_NAME` varchar(64), `DTD_IDENTIFIER` longtext NOT NULL, - `ROUTINE_TYPE` varchar(9) NOT NULL + `ROUTINE_TYPE` varchar(9) NOT NULL, + `PARAMETER_DEFAULT` longtext ) DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci SELECT * FROM information_schema.columns WHERE table_schema = 'information_schema' @@ -408,6 +409,30 @@ IS_GENERATED NEVER GENERATION_EXPRESSION NULL IS_SYSTEM_TIME_PERIOD_START NO IS_SYSTEM_TIME_PERIOD_END NO +TABLE_CATALOG def +TABLE_SCHEMA information_schema +TABLE_NAME PARAMETERS +COLUMN_NAME PARAMETER_DEFAULT +ORDINAL_POSITION 17 +COLUMN_DEFAULT NULL +IS_NULLABLE YES +DATA_TYPE longtext +CHARACTER_MAXIMUM_LENGTH 4294967295 +CHARACTER_OCTET_LENGTH 4294967295 +NUMERIC_PRECISION NULL +NUMERIC_SCALE NULL +DATETIME_PRECISION NULL +CHARACTER_SET_NAME utf8mb3 +COLLATION_NAME utf8mb3_general_ci +COLUMN_TYPE longtext +COLUMN_KEY +EXTRA +PRIVILEGES # +COLUMN_COMMENT +IS_GENERATED NEVER +GENERATION_EXPRESSION NULL +IS_SYSTEM_TIME_PERIOD_START NO +IS_SYSTEM_TIME_PERIOD_END NO DESCRIBE INFORMATION_SCHEMA.PARAMETERS; Field Type Null Key Default Extra SPECIFIC_CATALOG varchar(512) NO NULL @@ -426,6 +451,7 @@ CHARACTER_SET_NAME varchar(64) YES NULL COLLATION_NAME varchar(64) YES NULL DTD_IDENTIFIER longtext NO NULL ROUTINE_TYPE varchar(9) NO NULL +PARAMETER_DEFAULT longtext YES NULL # ========== parameters.2 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -436,7 +462,7 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp RETURN CONCAT('Hello', ,s,'!')' at line 1 SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func1'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT # ========== parameters.3 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -445,13 +471,13 @@ CREATE FUNCTION test_func1 (s char(20)) RETURNS CHAR(50) RETURN CONCAT('Hello, ',s,'!'); SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func1'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func1 0 NULL NULL char 50 200 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(50) FUNCTION -def i_s_parameters_test test_func1 1 IN s char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func1 0 NULL NULL char 50 200 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(50) FUNCTION NULL +def i_s_parameters_test test_func1 1 IN s char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION NULL DROP FUNCTION test_func1; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func1'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT # ========== parameters.4 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -463,8 +489,8 @@ END; // SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'testproc'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test testproc 1 IN param1 int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test testproc 1 IN param1 int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE NULL # ========== parameters.5 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -472,8 +498,8 @@ USE i_s_parameters_test; CREATE PROCEDURE test_proc(INOUT P INT) SET @x=P*2; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_proc'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_proc 1 INOUT P int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_proc 1 INOUT P int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE NULL # ========== parameters.6 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -481,8 +507,8 @@ USE i_s_parameters_test; CREATE PROCEDURE test_proc(OUT p VARCHAR(10)) SET P='test'; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_proc'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_proc 1 OUT p varchar 10 40 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci varchar(10) PROCEDURE +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_proc 1 OUT p varchar 10 40 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci varchar(10) PROCEDURE NULL # ========== parameters.7 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -491,10 +517,10 @@ CREATE FUNCTION test_func1 (s char(20), t char(20)) RETURNS CHAR(40) RETURN CONCAT(s,t); SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func1'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func1 0 NULL NULL char 40 160 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(40) FUNCTION -def i_s_parameters_test test_func1 1 IN s char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION -def i_s_parameters_test test_func1 2 IN t char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func1 0 NULL NULL char 40 160 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(40) FUNCTION NULL +def i_s_parameters_test test_func1 1 IN s char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION NULL +def i_s_parameters_test test_func1 2 IN t char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION NULL # ========== parameters.8 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -503,9 +529,9 @@ CREATE FUNCTION test_func1 (s char(20)) RETURNS CHAR(50) RETURN CONCAT('Hello, ',s,'!'); SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func1'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func1 0 NULL NULL char 50 200 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(50) FUNCTION -def i_s_parameters_test test_func1 1 IN s char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func1 0 NULL NULL char 50 200 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(50) FUNCTION NULL +def i_s_parameters_test test_func1 1 IN s char 20 80 NULL NULL NULL utf8mb4 utf8mb4_uca1400_ai_ci char(20) FUNCTION NULL # ========== parameters.9 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -513,9 +539,9 @@ USE i_s_parameters_test; CREATE FUNCTION test_func2 (s int) RETURNS INT RETURN s*2; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func2'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func2 0 NULL NULL int NULL NULL 10 0 NULL NULL NULL int(11) FUNCTION -def i_s_parameters_test test_func2 1 IN s int NULL NULL 10 0 NULL NULL NULL int(11) FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func2 0 NULL NULL int NULL NULL 10 0 NULL NULL NULL int(11) FUNCTION NULL +def i_s_parameters_test test_func2 1 IN s int NULL NULL 10 0 NULL NULL NULL int(11) FUNCTION NULL # ========== parameters.10 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -524,9 +550,9 @@ CREATE FUNCTION test_func5 (s date) RETURNS TIMESTAMP RETURN CURRENT_TIMESTAMP; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func5'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func5 0 NULL NULL timestamp NULL NULL NULL NULL 0 NULL NULL timestamp FUNCTION -def i_s_parameters_test test_func5 1 IN s date NULL NULL NULL NULL NULL NULL NULL date FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func5 0 NULL NULL timestamp NULL NULL NULL NULL 0 NULL NULL timestamp FUNCTION NULL +def i_s_parameters_test test_func5 1 IN s date NULL NULL NULL NULL NULL NULL NULL date FUNCTION NULL # ========== parameters.11 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test; @@ -535,15 +561,15 @@ CREATE FUNCTION test_func5 (s date) RETURNS TIMESTAMP RETURN CURRENT_TIMESTAMP; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func5'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func5 0 NULL NULL timestamp NULL NULL NULL NULL 0 NULL NULL timestamp FUNCTION -def i_s_parameters_test test_func5 1 IN s date NULL NULL NULL NULL NULL NULL NULL date FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func5 0 NULL NULL timestamp NULL NULL NULL NULL 0 NULL NULL timestamp FUNCTION NULL +def i_s_parameters_test test_func5 1 IN s date NULL NULL NULL NULL NULL NULL NULL date FUNCTION NULL ALTER FUNCTION test_func5 COMMENT 'new comment added'; SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func5'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func5 0 NULL NULL timestamp NULL NULL NULL NULL 0 NULL NULL timestamp FUNCTION -def i_s_parameters_test test_func5 1 IN s date NULL NULL NULL NULL NULL NULL NULL date FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func5 0 NULL NULL timestamp NULL NULL NULL NULL 0 NULL NULL timestamp FUNCTION NULL +def i_s_parameters_test test_func5 1 IN s date NULL NULL NULL NULL NULL NULL NULL date FUNCTION NULL # ========== parameters.12 ========== DROP DATABASE IF EXISTS i_s_parameters_test; CREATE DATABASE i_s_parameters_test CHARACTER SET utf8; @@ -552,9 +578,9 @@ CREATE FUNCTION test_func5 (s CHAR(20)) RETURNS VARCHAR(30) RETURN CONCAT('XYZ, ' ,s); SELECT * FROM INFORMATION_SCHEMA.PARAMETERS WHERE SPECIFIC_SCHEMA = 'i_s_parameters_test' AND SPECIFIC_NAME = 'test_func5'; -SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE -def i_s_parameters_test test_func5 0 NULL NULL varchar 30 90 NULL NULL NULL utf8mb3 utf8mb3_uca1400_ai_ci varchar(30) FUNCTION -def i_s_parameters_test test_func5 1 IN s char 20 60 NULL NULL NULL utf8mb3 utf8mb3_uca1400_ai_ci char(20) FUNCTION +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def i_s_parameters_test test_func5 0 NULL NULL varchar 30 90 NULL NULL NULL utf8mb3 utf8mb3_uca1400_ai_ci varchar(30) FUNCTION NULL +def i_s_parameters_test test_func5 1 IN s char 20 60 NULL NULL NULL utf8mb3 utf8mb3_uca1400_ai_ci char(20) FUNCTION NULL DROP DATABASE i_s_parameters_test; USE test; # @@ -588,6 +614,7 @@ CHARACTER_SET_NAME NULL COLLATION_NAME NULL DTD_IDENTIFIER TYPE OF `t1`.`a` ROUTINE_TYPE PROCEDURE +PARAMETER_DEFAULT NULL -------- -------- SPECIFIC_CATALOG def SPECIFIC_SCHEMA test @@ -605,6 +632,7 @@ CHARACTER_SET_NAME NULL COLLATION_NAME NULL DTD_IDENTIFIER TYPE OF `test`.`t1`.`a` ROUTINE_TYPE PROCEDURE +PARAMETER_DEFAULT NULL -------- -------- SPECIFIC_CATALOG def SPECIFIC_SCHEMA test @@ -622,6 +650,7 @@ CHARACTER_SET_NAME NULL COLLATION_NAME NULL DTD_IDENTIFIER ROW TYPE OF `t1` ROUTINE_TYPE PROCEDURE +PARAMETER_DEFAULT NULL -------- -------- SPECIFIC_CATALOG def SPECIFIC_SCHEMA test @@ -639,6 +668,7 @@ CHARACTER_SET_NAME NULL COLLATION_NAME NULL DTD_IDENTIFIER ROW TYPE OF `test`.`t1` ROUTINE_TYPE PROCEDURE +PARAMETER_DEFAULT NULL -------- -------- SPECIFIC_CATALOG def SPECIFIC_SCHEMA test @@ -656,6 +686,7 @@ CHARACTER_SET_NAME NULL COLLATION_NAME NULL DTD_IDENTIFIER ROW ROUTINE_TYPE PROCEDURE +PARAMETER_DEFAULT NULL -------- -------- DROP PROCEDURE p1; # @@ -688,6 +719,7 @@ CHARACTER_SET_NAME utf8mb4 COLLATION_NAME utf8mb4_uca1400_ai_ci DTD_IDENTIFIER varchar(30) ROUTINE_TYPE FUNCTION +PARAMETER_DEFAULT NULL SPECIFIC_CATALOG def SPECIFIC_SCHEMA i_s_parameters_test SPECIFIC_NAME test_func5 @@ -704,6 +736,7 @@ CHARACTER_SET_NAME utf8mb4 COLLATION_NAME utf8mb4_uca1400_ai_ci DTD_IDENTIFIER char(20) ROUTINE_TYPE FUNCTION +PARAMETER_DEFAULT NULL SHOW STATUS LIKE 'handler_read%next'; Variable_name Value Handler_read_next count_routines @@ -742,6 +775,7 @@ CHARACTER_SET_NAME utf8mb4 COLLATION_NAME utf8mb4_uca1400_ai_ci DTD_IDENTIFIER varchar(30) ROUTINE_TYPE FUNCTION +PARAMETER_DEFAULT NULL SPECIFIC_CATALOG def SPECIFIC_SCHEMA i_s_parameters_test SPECIFIC_NAME test_func5 @@ -758,6 +792,7 @@ CHARACTER_SET_NAME utf8mb4 COLLATION_NAME utf8mb4_uca1400_ai_ci DTD_IDENTIFIER char(20) ROUTINE_TYPE FUNCTION +PARAMETER_DEFAULT NULL SHOW STATUS LIKE 'handler_read%next'; Variable_name Value Handler_read_next 1 @@ -783,6 +818,7 @@ CHARACTER_SET_NAME utf8mb4 COLLATION_NAME utf8mb4_uca1400_ai_ci DTD_IDENTIFIER varchar(30) ROUTINE_TYPE FUNCTION +PARAMETER_DEFAULT NULL SPECIFIC_CATALOG def SPECIFIC_SCHEMA i_s_parameters_test SPECIFIC_NAME test_func5 @@ -799,6 +835,7 @@ CHARACTER_SET_NAME utf8mb4 COLLATION_NAME utf8mb4_uca1400_ai_ci DTD_IDENTIFIER char(20) ROUTINE_TYPE FUNCTION +PARAMETER_DEFAULT NULL SHOW STATUS LIKE 'handler_read%next'; Variable_name Value Handler_read_next 1 @@ -829,6 +866,7 @@ CHARACTER_SET_NAME NULL COLLATION_NAME NULL DTD_IDENTIFIER int(11) ROUTINE_TYPE PROCEDURE +PARAMETER_DEFAULT NULL SHOW STATUS LIKE 'handler_read%next'; Variable_name Value Handler_read_next 1 diff --git a/mysql-test/main/information_schema_parameters.test b/mysql-test/main/information_schema_parameters.test index 2073730f5562b..2f0bc84b2ba13 100644 --- a/mysql-test/main/information_schema_parameters.test +++ b/mysql-test/main/information_schema_parameters.test @@ -27,6 +27,7 @@ # NUMERIC_PRECISION same as for COLUMNS # NUMERIC_SCALE same as for COLUMNS # DTD_IDENTIFIER same as for PARAMETERS +# PARAMETER_DEFAULT the parameter's default value ############################################################################### -- echo # ========== parameters.1 ========== USE INFORMATION_SCHEMA; diff --git a/mysql-test/main/information_schema_temp_table.test b/mysql-test/main/information_schema_temp_table.test index 6cce08cdc41ec..74461016e15b1 100644 --- a/mysql-test/main/information_schema_temp_table.test +++ b/mysql-test/main/information_schema_temp_table.test @@ -4,10 +4,11 @@ --echo # INNODB_TEMP_TABLE_INFO --echo # -# Save the initial number of concurrent sessions ---source include/count_sessions.inc --source include/have_innodb.inc +# service connection doesn't follow `use db` +--disable_service_connection + --echo # ------------------------------- --echo # Test shadowing of a base table --echo # ------------------------------- @@ -85,8 +86,10 @@ create sequence s1; create temporary table t1 (b int); create temporary sequence s1; create temporary sequence s2; +--disable_view_protocol select table_schema, table_name, table_type, temporary from information_schema.tables where table_schema = 'test' order by table_schema desc, table_name desc, table_type desc; +--enable_view_protocol drop table t1; drop table t1; @@ -107,9 +110,6 @@ drop table test.t_temp; drop database my_db; drop database some_db; -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - --echo # --echo # MDEV-28332: Alter on temporary table causes ER_TABLE_EXISTS_ERROR note --echo # @@ -215,9 +215,11 @@ CREATE TABLE t1 (a INT) ENGINE=MyISAM; insert into t1 values (1); CREATE TEMPORARY TABLE t2 (a INT) ENGINE=MERGE UNION=(t1); CREATE TABLE t3 (a INT) ENGINE=MERGE UNION=(t1); +--disable_view_protocol --sorted_result --replace_column 10 X 11 X 12 X 13 X 15 X 16 X 22 X SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'test'; +--enable_view_protocol DROP TABLE t1,t2,t3; --echo # diff --git a/mysql-test/main/init_connect.test b/mysql-test/main/init_connect.test index c210ea10850d8..cc144568c4460 100644 --- a/mysql-test/main/init_connect.test +++ b/mysql-test/main/init_connect.test @@ -5,11 +5,12 @@ # should work with embedded server after mysqltest is fixed --source include/not_embedded.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - --source include/add_anonymous_users.inc +# let's not use service connection here otherwise +# it'll be constantly reexecuting init-connect +--disable_service_connection + connect (con0,localhost,root,,); connection con0; select hex(@a); @@ -38,11 +39,13 @@ connection con0; set GLOBAL init_connect="adsfsdfsdfs"; connect (con5,localhost,user_1,,test); connection con5; +--disable_view_protocol # BUG#11755281/47032: ERROR 2006 / ERROR 2013 INSTEAD OF PROPER ERROR MESSAGE # We now throw a proper error message here: --replace_regex /connection .* to/connection to/ --error ER_NEW_ABORTING_CONNECTION select @a; +--enable_view_protocol # We got disconnected after receiving the above error message; any further # requests should fail with a notice that no one's listening to us. # --error CR_SERVER_GONE_ERROR,CR_SERVER_LOST @@ -259,7 +262,3 @@ set global init_connect="set @a='a\\0c'"; revoke all privileges, grant option from mysqltest1@localhost; drop user mysqltest1@localhost; drop table t1, t2; - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/innodb_ext_key,off.rdiff b/mysql-test/main/innodb_ext_key,off.rdiff index 8b24cc9a66350..4db9110f04943 100644 --- a/mysql-test/main/innodb_ext_key,off.rdiff +++ b/mysql-test/main/innodb_ext_key,off.rdiff @@ -5,7 +5,7 @@ select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 8 const,const 1 Using index -+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index ++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where flush status; select count(*) from lineitem where l_orderkey=130 and l_shipdate='1992-07-01'; count(*) @@ -14,7 +14,7 @@ Handler_read_key 1 Handler_read_last 0 -Handler_read_next 1 -+Handler_read_next 6 ++Handler_read_next 5 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 0 @@ -95,7 +95,7 @@ where l_shipdate='1992-07-01' and l_orderkey=130; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away -+1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity i_l_shipdate 4 const 6 Using where; Using index ++1 SIMPLE lineitem ref PRIMARY,i_l_shipdate,i_l_orderkey,i_l_orderkey_quantity PRIMARY 4 const 5 Using where flush status; select max(l_linenumber) from lineitem where l_shipdate='1992-07-01' and l_orderkey=130; @@ -104,7 +104,7 @@ Handler_read_key 1 Handler_read_last 0 -Handler_read_next 0 -+Handler_read_next 6 ++Handler_read_next 5 Handler_read_prev 0 Handler_read_retry 0 Handler_read_rnd 0 diff --git a/mysql-test/main/innodb_icp_debug.result b/mysql-test/main/innodb_icp_debug.result index 5a169650c8eea..1f8465350e92d 100644 --- a/mysql-test/main/innodb_icp_debug.result +++ b/mysql-test/main/innodb_icp_debug.result @@ -1,5 +1,4 @@ set default_storage_engine=innodb; -drop table if exists t0,t1,t2; create table t0(a int primary key); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1(a int primary key); diff --git a/mysql-test/main/innodb_mysql_lock.result b/mysql-test/main/innodb_mysql_lock.result index 6ca332018caa5..0f7f40d0de664 100644 --- a/mysql-test/main/innodb_mysql_lock.result +++ b/mysql-test/main/innodb_mysql_lock.result @@ -5,7 +5,6 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting # # Bug #22876 Four-way deadlock # -DROP TABLE IF EXISTS t1; connect con1,localhost,root,,; connect con2,localhost,root,,; connect con3,localhost,root,,; diff --git a/mysql-test/main/innodb_mysql_lock.test b/mysql-test/main/innodb_mysql_lock.test index e61b2fde055bb..b0ce24fadcaa9 100644 --- a/mysql-test/main/innodb_mysql_lock.test +++ b/mysql-test/main/innodb_mysql_lock.test @@ -5,9 +5,6 @@ call mtr.add_suppression("InnoDB: Transaction was aborted due to "); --enable_query_log -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc - set @old_innodb_lock_wait_timeout=@@global.innodb_lock_wait_timeout; set global innodb_lock_wait_timeout=300; set session innodb_lock_wait_timeout=300; @@ -18,10 +15,6 @@ call mtr.add_suppression("Deadlock found when trying to get lock; try restarting --echo # Bug #22876 Four-way deadlock --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connect (con3,localhost,root,,); @@ -259,10 +252,4 @@ COMMIT; DROP TABLE t1; disconnect con1; - -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc - set global innodb_lock_wait_timeout=@old_innodb_lock_wait_timeout; - diff --git a/mysql-test/main/innodb_mysql_lock2.result b/mysql-test/main/innodb_mysql_lock2.result index a03e1d842b217..3a57c3b8c2a93 100644 --- a/mysql-test/main/innodb_mysql_lock2.result +++ b/mysql-test/main/innodb_mysql_lock2.result @@ -1,3 +1,4 @@ +CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); # # Test how do we handle locking in various cases when # we read data from InnoDB tables. @@ -223,10 +224,8 @@ Success: 'show keys from t1' doesn't take row locks on 't1'. # written to the binary log as a whole (it is written # statement-by-statement) and thanks to MVCC we can always get # versions of rows prior to the update that has locked them. -# But in practice InnoDB does locking reads for all statements -# other than SELECT (unless READ UNCOMMITTED or READ COMMITTED). connection default; -Success: 'call p1((select i + 5 from t1 where i = 1))' takes shared row locks on 't1'. +Success: 'call p1((select i + 5 from t1 where i = 1))' doesn't take row locks on 't1'. # # 2.2 CREATE TABLE with a subquery. # @@ -254,10 +253,9 @@ Success: 'delete t2 from t3, t2 where k = j and j in (select i from t1)' takes s # # 2.5 DO with a subquery. # -# In theory should not take row locks as it is not logged. -# In practice InnoDB takes shared row locks. +# Should not take row locks as it is not logged. connection default; -Success: 'do (select i from t1 where i = 1)' takes shared row locks on 't1'. +Success: 'do (select i from t1 where i = 1)' doesn't take row locks on 't1'. # # 2.6 INSERT with a subquery. # @@ -296,21 +294,19 @@ Success: 'select * from t2 where j in (select i from t1)' doesn't take row locks # # 2.10 SET with a subquery. # -# In theory should not require locking as it is not written -# to the binary log. In practice InnoDB acquires shared row -# locks. +# Should not require locking as it is not written +# to the binary log. connection default; -Success: 'set @a:= (select i from t1 where i = 1)' takes shared row locks on 't1'. +Success: 'set @a:= (select i from t1 where i = 1)' doesn't take row locks on 't1'. # # 2.11 SHOW with a subquery. # -# Similarly to the previous case, in theory should not require locking -# as it is not written to the binary log. In practice InnoDB -# acquires shared row locks. +# Similarly to the previous case, should not require locking +# as it is not written to the binary log. connection default; -Success: 'show tables from test where Tables_in_test = 't2' and (select i from t1 where i = 1)' takes shared row locks on 't1'. +Success: 'show tables from test where Tables_in_test = 't2' and (select i from t1 where i = 1)' doesn't take row locks on 't1'. connection default; -Success: 'show columns from t2 where (select i from t1 where i = 1)' takes shared row locks on 't1'. +Success: 'show columns from t2 where (select i from t1 where i = 1)' doesn't take row locks on 't1'. # # 2.12 UPDATE with a subquery. # @@ -366,14 +362,10 @@ Success: 'update v2 set j= j-10 where j = 3' takes shared row locks on 't1'. # There is no need to take row locks on the table # being selected from in SF as the call to such function # won't get into the binary log. -# -# However in practice innodb takes strong lock on tables -# being selected from within SF, when SF is called from -# non SELECT statements like 'set' statement below. connection default; Success: 'select f1()' doesn't take row locks on 't1'. connection default; -Success: 'set @a:= f1()' takes shared row locks on 't1'. +Success: 'set @a:= f1()' doesn't take row locks on 't1'. # # 4.2 INSERT (or other statement which modifies data) with # a stored function which does not modify data and uses @@ -404,18 +396,14 @@ Success: 'set @a:= f2()' takes shared row locks on 't1'. # # Call to this function won't get to the # binary log and thus no locking is needed. -# -# However in practice innodb takes strong lock on tables -# being selected from within SF, when SF is called from -# non SELECT statements like 'set' statement below. connection default; Success: 'select f3()' doesn't take row locks on 't1'. connection default; -Success: 'set @a:= f3()' takes shared row locks on 't1'. +Success: 'set @a:= f3()' doesn't take row locks on 't1'. connection default; Success: 'select f4()' doesn't take row locks on 't1'. connection default; -Success: 'set @a:= f4()' takes shared row locks on 't1'. +Success: 'set @a:= f4()' doesn't take row locks on 't1'. # # 4.5. INSERT (or other statement which modifies data) with # a stored function which does not modify data and reads @@ -448,18 +436,14 @@ Success: 'set @a:= f5()' takes shared row locks on 't1'. # # Calls to such functions won't get into # the binary log and thus don't need row locks. -# -# However in practice innodb takes strong lock on tables -# being selected from within SF, when SF is called from -# non SELECT statements like 'set' statement below. connection default; Success: 'select f6()' doesn't take row locks on 't1'. connection default; -Success: 'set @a:= f6()' takes shared row locks on 't1'. +Success: 'set @a:= f6()' doesn't take row locks on 't1'. connection default; Success: 'select f7()' doesn't take row locks on 't1'. connection default; -Success: 'set @a:= f7()' takes shared row locks on 't1'. +Success: 'set @a:= f7()' doesn't take row locks on 't1'. # # 4.8 INSERT which uses stored function which # doesn't modify data and reads a table @@ -700,3 +684,4 @@ connection default; disconnect con1; # Clean-up. drop tables t1, t2; +# End of 5.5 tests diff --git a/mysql-test/main/innodb_mysql_lock2.test b/mysql-test/main/innodb_mysql_lock2.test index b35c23ce659d8..691892ad44a6f 100644 --- a/mysql-test/main/innodb_mysql_lock2.test +++ b/mysql-test/main/innodb_mysql_lock2.test @@ -9,12 +9,8 @@ --source include/have_binlog_format_mixed_or_statement.inc # Original test case for bug#51263 needs partitioning. --source include/have_partition.inc -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc ---disable_query_log CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); ---enable_query_log --echo # --echo # Test how do we handle locking in various cases when @@ -262,11 +258,9 @@ let $statement= show keys from t1; --echo # written to the binary log as a whole (it is written --echo # statement-by-statement) and thanks to MVCC we can always get --echo # versions of rows prior to the update that has locked them. ---echo # But in practice InnoDB does locking reads for all statements ---echo # other than SELECT (unless READ UNCOMMITTED or READ COMMITTED). let $statement= call p1((select i + 5 from t1 where i = 1)); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 2.2 CREATE TABLE with a subquery. @@ -302,11 +296,10 @@ let $wait_statement= $statement; --echo # --echo # 2.5 DO with a subquery. --echo # ---echo # In theory should not take row locks as it is not logged. ---echo # In practice InnoDB takes shared row locks. +--echo # Should not take row locks as it is not logged. let $statement= do (select i from t1 where i = 1); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 2.6 INSERT with a subquery. @@ -355,25 +348,23 @@ let $statement= select * from t2 where j in (select i from t1); --echo # --echo # 2.10 SET with a subquery. --echo # ---echo # In theory should not require locking as it is not written ---echo # to the binary log. In practice InnoDB acquires shared row ---echo # locks. +--echo # Should not require locking as it is not written +--echo # to the binary log. let $statement= set @a:= (select i from t1 where i = 1); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 2.11 SHOW with a subquery. --echo # ---echo # Similarly to the previous case, in theory should not require locking ---echo # as it is not written to the binary log. In practice InnoDB ---echo # acquires shared row locks. +--echo # Similarly to the previous case, should not require locking +--echo # as it is not written to the binary log. let $statement= show tables from test where Tables_in_test = 't2' and (select i from t1 where i = 1); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc let $statement= show columns from t2 where (select i from t1 where i = 1); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 2.12 UPDATE with a subquery. @@ -444,16 +435,12 @@ let $wait_statement= $statement; --echo # There is no need to take row locks on the table --echo # being selected from in SF as the call to such function --echo # won't get into the binary log. ---echo # ---echo # However in practice innodb takes strong lock on tables ---echo # being selected from within SF, when SF is called from ---echo # non SELECT statements like 'set' statement below. let $statement= select f1(); let $wait_statement= select i from t1 where i = 1 into j; --source include/check_no_row_lock.inc let $statement= set @a:= f1(); let $wait_statement= select i from t1 where i = 1 into j; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 4.2 INSERT (or other statement which modifies data) with @@ -490,22 +477,18 @@ let $wait_statement= select i from t1 where i = 1 into k; --echo # --echo # Call to this function won't get to the --echo # binary log and thus no locking is needed. ---echo # ---echo # However in practice innodb takes strong lock on tables ---echo # being selected from within SF, when SF is called from ---echo # non SELECT statements like 'set' statement below. let $statement= select f3(); let $wait_statement= $statement; --source include/check_no_row_lock.inc let $statement= set @a:= f3(); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc let $statement= select f4(); let $wait_statement= $statement; --source include/check_no_row_lock.inc let $statement= set @a:= f4(); let $wait_statement= $statement; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 4.5. INSERT (or other statement which modifies data) with @@ -545,22 +528,18 @@ let $wait_statement= insert into t2 values ((select i from t1 where i = 1) + 5); --echo # --echo # Calls to such functions won't get into --echo # the binary log and thus don't need row locks. ---echo # ---echo # However in practice innodb takes strong lock on tables ---echo # being selected from within SF, when SF is called from ---echo # non SELECT statements like 'set' statement below. let $statement= select f6(); let $wait_statement= select i from v1 where i = 1 into k; --source include/check_no_row_lock.inc let $statement= set @a:= f6(); let $wait_statement= select i from v1 where i = 1 into k; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc let $statement= select f7(); let $wait_statement= select j from v2 where j = 1 into k; --source include/check_no_row_lock.inc let $statement= set @a:= f7(); let $wait_statement= select j from v2 where j = 1 into k; ---source include/check_shared_row_lock.inc +--source include/check_no_row_lock.inc --echo # --echo # 4.8 INSERT which uses stored function which @@ -864,7 +843,4 @@ disconnect con1; --echo # Clean-up. drop tables t1, t2; - -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc +--echo # End of 5.5 tests diff --git a/mysql-test/main/innodb_mysql_sync.result b/mysql-test/main/innodb_mysql_sync.result index 0b703b1d60089..b37cf4ad6deab 100644 --- a/mysql-test/main/innodb_mysql_sync.result +++ b/mysql-test/main/innodb_mysql_sync.result @@ -29,7 +29,6 @@ SET DEBUG_SYNC='RESET'; # Bug#47459 Assertion in Diagnostics_area::set_eof_status on # OPTIMIZE TABLE # -DROP TABLE IF EXISTS t1; connect con1, localhost, root; connection default; CREATE TABLE t1(a INT) ENGINE= InnoDB; @@ -55,7 +54,6 @@ SET DEBUG_SYNC= "RESET"; # # Bug#53757 assert in mysql_truncate_by_delete # -DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1(a INT) Engine=InnoDB; CREATE TABLE t2(id INT); INSERT INTO t1 VALUES (1), (2); @@ -78,7 +76,6 @@ SET DEBUG_SYNC= "RESET"; # Bug#58933 Assertion `thd- >is_error()' fails on shutdown with ongoing # OPTIMIZE TABLE # -DROP TABLE IF EXISTS t1; CREATE TABLE t1 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1), (2); connect con1,localhost,root; @@ -105,8 +102,6 @@ disconnect con1; # Bug#42230 during add index, cannot do queries on storage engines # that implement add_index # -DROP DATABASE IF EXISTS db1; -DROP TABLE IF EXISTS t1; connect con1,localhost,root; connect con2,localhost,root; # Test 1: Secondary index, should not block reads (original test case). @@ -190,7 +185,6 @@ DROP TABLE t1; # Bug#11853126 RE-ENABLE CONCURRENT READS WHILE CREATING SECONDARY INDEX # IN INNODB # -DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; INSERT INTO t1 VALUES (1, 12345), (2, 23456); connect con1,localhost,root; @@ -211,8 +205,6 @@ disconnect con1; # # Bug#13417754 ASSERT IN ROW_DROP_DATABASE_FOR_MYSQL DURING DROP SCHEMA # -DROP TABLE IF EXISTS t1; -DROP DATABASE IF EXISTS db1; CREATE TABLE t1(a int) engine=InnoDB; CREATE DATABASE db1; connect con1, localhost, root; @@ -243,7 +235,6 @@ disconnect con2; # # Multi thread tests. # See alter_table.test for single thread tests. -DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT PRIMARY KEY, b INT) engine=InnoDB; INSERT INTO t1 VALUES (1,1), (2,2); SET DEBUG_SYNC= 'RESET'; diff --git a/mysql-test/main/innodb_mysql_sync.test b/mysql-test/main/innodb_mysql_sync.test index 1cd64affd380c..21dc6a31b5a51 100644 --- a/mysql-test/main/innodb_mysql_sync.test +++ b/mysql-test/main/innodb_mysql_sync.test @@ -5,9 +5,7 @@ --source include/have_partition.inc --source include/have_debug.inc --source include/have_debug_sync.inc -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc - +--source include/no_view_protocol.inc --echo # --echo # Bug 42074 concurrent optimize table and @@ -43,10 +41,6 @@ SET DEBUG_SYNC='RESET'; --echo # OPTIMIZE TABLE --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - connect (con1, localhost, root); connection default; @@ -75,10 +69,6 @@ SET DEBUG_SYNC= "RESET"; --echo # Bug#53757 assert in mysql_truncate_by_delete --echo # ---disable_warnings -DROP TABLE IF EXISTS t1, t2; ---enable_warnings - CREATE TABLE t1(a INT) Engine=InnoDB; CREATE TABLE t2(id INT); INSERT INTO t1 VALUES (1), (2); @@ -96,7 +86,6 @@ KILL @id; SET DEBUG_SYNC= "now SIGNAL killed"; DROP TABLE t1, t2; disconnect con1; ---source include/wait_until_count_sessions.inc SET DEBUG_SYNC= "RESET"; @@ -105,10 +94,6 @@ SET DEBUG_SYNC= "RESET"; --echo # OPTIMIZE TABLE --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1), (2); @@ -139,11 +124,6 @@ disconnect con1; --echo # that implement add_index --echo # ---disable_warnings -DROP DATABASE IF EXISTS db1; -DROP TABLE IF EXISTS t1; ---enable_warnings - connect(con1,localhost,root); connect(con2,localhost,root); @@ -257,10 +237,6 @@ DROP TABLE t1; --echo # IN INNODB --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1(a INT NOT NULL, b INT NOT NULL) engine=innodb; INSERT INTO t1 VALUES (1, 12345), (2, 23456); @@ -280,11 +256,6 @@ disconnect con1; --echo # Bug#13417754 ASSERT IN ROW_DROP_DATABASE_FOR_MYSQL DURING DROP SCHEMA --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; -DROP DATABASE IF EXISTS db1; ---enable_warnings - CREATE TABLE t1(a int) engine=InnoDB; CREATE DATABASE db1; @@ -333,10 +304,6 @@ disconnect con2; --echo # Multi thread tests. --echo # See alter_table.test for single thread tests. ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1(a INT PRIMARY KEY, b INT) engine=InnoDB; INSERT INTO t1 VALUES (1,1), (2,2); SET DEBUG_SYNC= 'RESET'; @@ -698,8 +665,3 @@ SET DEBUG_SYNC= 'now WAIT_FOR rebuild'; SET DEBUG_SYNC= 'RESET'; DROP TABLE t1; - - -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/insert_innodb.result b/mysql-test/main/insert_innodb.result index 174a749a504ff..0ce0a625de71b 100644 --- a/mysql-test/main/insert_innodb.result +++ b/mysql-test/main/insert_innodb.result @@ -10,7 +10,7 @@ INSERT INTO t2 VALUES(0); # Without fix, an error is reported. INSERT IGNORE INTO t2 VALUES(1); Warnings: -Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +Warning 1452 Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) UPDATE IGNORE t2 SET fld2=20 WHERE fld2=0; UPDATE IGNORE t1 SET fld1=20 WHERE fld1=0; # Test for multi update. @@ -18,15 +18,15 @@ UPDATE IGNORE t1, t2 SET t2.fld2= t2.fld2 + 3; UPDATE IGNORE t1, t2 SET t1.fld1= t1.fld1 + 3; # Reports an error since IGNORE is not used. INSERT INTO t2 VALUES(1); -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) UPDATE t2 SET fld2=20 WHERE fld2=0; -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) UPDATE t1 SET fld1=20 WHERE fld1=0; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) UPDATE t1, t2 SET t2.fld2= t2.fld2 + 3; -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) UPDATE t1, t2 SET t1.fld1= t1.fld1 + 3; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `1` FOREIGN KEY (`fld2`) REFERENCES `t1` (`fld1`)) DROP TABLE t2, t1; # # BUG#22037930: INSERT IGNORE FAILS TO IGNORE FOREIGN diff --git a/mysql-test/main/insert_notembedded.result b/mysql-test/main/insert_notembedded.result index 5df69cc8ffedb..d7beca6d049c5 100644 --- a/mysql-test/main/insert_notembedded.result +++ b/mysql-test/main/insert_notembedded.result @@ -121,3 +121,48 @@ connection default; DROP DATABASE meow; set local sql_mode=default; set global sql_mode=default; +# +# MDEV-37950: INSERT ... RETURNING exposes columns for which +# the user lacks SELECT privilege +# +CREATE USER regular; +GRANT INSERT ON *.* TO regular; +GRANT DELETE ON *.* TO regular; +CREATE DATABASE test1; +DROP TABLE IF EXISTS test1.t_trigger_test1; +Warnings: +Note 1051 Unknown table 'test1.t_trigger_test1' +CREATE TABLE test1.t_trigger_test1 ( +id INT AUTO_INCREMENT PRIMARY KEY, +name VARCHAR(50), +note VARCHAR(100) +); +CREATE TRIGGER test1.trg_before_insert +BEFORE INSERT ON test1.t_trigger_test1 +FOR EACH ROW +BEGIN +SET NEW.name = CONCAT('BEFORE_', NEW.name); +END | +change_user regular,,; +INSERT INTO test1.t_trigger_test1 (name) VALUES ('Alice') RETURNING *; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +INSERT INTO test1.t_trigger_test1 (name) VALUES ('Alice') RETURNING id, name, note; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +# same for DELETE because delete with "WHERE" still requires to +# read from the table, which basically means having select privileges +DELETE FROM test1.t_trigger_test1 WHERE id=1; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +DELETE FROM test1.t_trigger_test1 WHERE id=1 RETURNING id; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +DELETE FROM test1.t_trigger_test1 WHERE id=1 RETURNING *; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +DELETE FROM test1.t_trigger_test1 RETURNING *; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +DELETE FROM test1.t_trigger_test1 RETURNING id; +ERROR 42000: SELECT command denied to user 'regular'@'localhost' for column 'id' in table 't_trigger_test1' +DELETE FROM test1.t_trigger_test1; +change_user root,,; +DROP TRIGGER test1.trg_before_insert; +DROP TABLE test1.t_trigger_test1; +DROP USER regular; +DROP DATABASE test1; diff --git a/mysql-test/main/insert_notembedded.test b/mysql-test/main/insert_notembedded.test index 2769aee8d8a61..09f5b18531d8a 100644 --- a/mysql-test/main/insert_notembedded.test +++ b/mysql-test/main/insert_notembedded.test @@ -158,3 +158,60 @@ DROP DATABASE meow; set local sql_mode=default; set global sql_mode=default; + +--echo # +--echo # MDEV-37950: INSERT ... RETURNING exposes columns for which +--echo # the user lacks SELECT privilege +--echo # +CREATE USER regular; +GRANT INSERT ON *.* TO regular; +GRANT DELETE ON *.* TO regular; + +CREATE DATABASE test1; +DROP TABLE IF EXISTS test1.t_trigger_test1; +CREATE TABLE test1.t_trigger_test1 ( + id INT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(50), + note VARCHAR(100) +); +DELIMITER |; +CREATE TRIGGER test1.trg_before_insert +BEFORE INSERT ON test1.t_trigger_test1 +FOR EACH ROW +BEGIN + SET NEW.name = CONCAT('BEFORE_', NEW.name); +END | +DELIMITER ;| + +change_user regular; + +--error ER_COLUMNACCESS_DENIED_ERROR +INSERT INTO test1.t_trigger_test1 (name) VALUES ('Alice') RETURNING *; +--error ER_COLUMNACCESS_DENIED_ERROR +INSERT INTO test1.t_trigger_test1 (name) VALUES ('Alice') RETURNING id, name, note; + +--echo # same for DELETE because delete with "WHERE" still requires to +--echo # read from the table, which basically means having select privileges + +--error ER_COLUMNACCESS_DENIED_ERROR +DELETE FROM test1.t_trigger_test1 WHERE id=1; + +--error ER_COLUMNACCESS_DENIED_ERROR +DELETE FROM test1.t_trigger_test1 WHERE id=1 RETURNING id; + +--error ER_COLUMNACCESS_DENIED_ERROR +DELETE FROM test1.t_trigger_test1 WHERE id=1 RETURNING *; + +--error ER_COLUMNACCESS_DENIED_ERROR +DELETE FROM test1.t_trigger_test1 RETURNING *; + +--error ER_COLUMNACCESS_DENIED_ERROR +DELETE FROM test1.t_trigger_test1 RETURNING id; + +DELETE FROM test1.t_trigger_test1; + +change_user root; +DROP TRIGGER test1.trg_before_insert; +DROP TABLE test1.t_trigger_test1; +DROP USER regular; +DROP DATABASE test1; diff --git a/mysql-test/main/insert_update.result b/mysql-test/main/insert_update.result index 3549aba9446a7..bfb89449368a5 100644 --- a/mysql-test/main/insert_update.result +++ b/mysql-test/main/insert_update.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1, t2; CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B)); INSERT t1 VALUES (1,2,10), (3,4,20); INSERT t1 VALUES (5,6,30) ON DUPLICATE KEY UPDATE c=c+100; @@ -451,6 +450,26 @@ pk val ts 5 val1 2000-10-20 03:00:00 drop table t1; set timestamp=default; -# # End of 10.4 tests # +# MDEV-38096 Server crashes after INSERT.. ON duplicate KEY UPDATE i = DEFAULT; +# +create sequence s; +create table t1 (i varchar(10) default nextval(s), j text, key(i)); +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; +create table t1 (i varchar(10) default nextval(s), j text, key(i)) engine=innodb; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; +create table t1 (i varchar(10) default nextval(s), j varchar(10), key(i)) engine=myisam; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; +create table t1 (j text default 5, i varchar(10) as (j), key(i)); +insert into t1 set j = (value (j)) on duplicate key update i = default; +insert into t1 set j = (value (j)) on duplicate key update i = default; +drop table t1; +drop sequence s; +# End of 10.11 tests diff --git a/mysql-test/main/insert_update.test b/mysql-test/main/insert_update.test index ab4fd51286d20..27c4cf2430592 100644 --- a/mysql-test/main/insert_update.test +++ b/mysql-test/main/insert_update.test @@ -1,6 +1,4 @@ ---disable_warnings -DROP TABLE IF EXISTS t1, t2; ---enable_warnings +source include/have_innodb.inc; CREATE TABLE t1 (a INT, b INT, c INT, UNIQUE (A), UNIQUE(B)); INSERT t1 VALUES (1,2,10), (3,4,20); @@ -335,6 +333,31 @@ select * from t1; drop table t1; set timestamp=default; ---echo # --echo # End of 10.4 tests + +--echo # +--echo # MDEV-38096 Server crashes after INSERT.. ON duplicate KEY UPDATE i = DEFAULT; --echo # +create sequence s; +create table t1 (i varchar(10) default nextval(s), j text, key(i)); +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; + +create table t1 (i varchar(10) default nextval(s), j text, key(i)) engine=innodb; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; + +create table t1 (i varchar(10) default nextval(s), j varchar(10), key(i)) engine=myisam; +insert into t1 set i = (value (j)) on duplicate key update i = default; +insert into t1 set i = (value (j)) on duplicate key update i = default; +drop table t1; + +create table t1 (j text default 5, i varchar(10) as (j), key(i)); +insert into t1 set j = (value (j)) on duplicate key update i = default; +insert into t1 set j = (value (j)) on duplicate key update i = default; +drop table t1; +drop sequence s; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/intersect_all.result b/mysql-test/main/intersect_all.result index 194b4cb9bcb48..81a57414426a4 100644 --- a/mysql-test/main/intersect_all.result +++ b/mysql-test/main/intersect_all.result @@ -1094,23 +1094,31 @@ NULL UNION RESULT ALL NULL NULL NULL NULL NULL set sql_mode= 'oracle'; explain SELECT * from t3 union select * from u3 intersect all select * from i3; id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t3 system NULL NULL NULL NULL 0 Const row not found -2 UNION u3 system NULL NULL NULL NULL 0 Const row not found -3 INTERSECT i3 system NULL NULL NULL NULL 0 Const row not found -NULL UNIT RESULT ALL NULL NULL NULL NULL NULL -select * from t3 union select * from u3 intersect select * from i3; +1 PRIMARY ALL NULL NULL NULL NULL 2 +4 DERIVED ALL NULL NULL NULL NULL 2 +2 DERIVED NULL NULL NULL NULL NULL NULL NULL no matching row in const table +3 UNION NULL NULL NULL NULL NULL NULL NULL no matching row in const table +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +5 INTERSECT NULL NULL NULL NULL NULL NULL NULL no matching row in const table +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +select x from t3 union select x from u3 intersect select x from i3; x -SELECT * from t3 union select * from u3 intersect all select * from i3; +SELECT x from t3 union select x from u3 intersect all select x from i3; x insert into t3 values (0); insert into i3 values (0); -Select * from t3 union select * from u3 intersect select * from i3; +Select x from t3 union select x from u3 intersect select x from i3; x 0 -SELECT * FROM t3 UNION SELECT * FROM u3 INTERSECT ALL SELECT * FROM i3; +SELECT x FROM t3 UNION SELECT x FROM u3 INTERSECT ALL SELECT x FROM i3; +x +0 +create view v as select * from t3 union select * from u3 intersect select * from i3; +select * from v; x 0 drop tables t3, u3, i3; +drop view v; # First line of these results is column names, not the result # (pay attention to "affected rows") values (1, 2) union all values (1, 2); @@ -1136,10 +1144,47 @@ values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3 1 2 4 3 affected rows: 2 +set sql_mode= default; create table t1 (a int, b int); create table t2 like t1; insert t1 values (1, 2), (1, 2), (1, 2), (2, 3), (2, 3), (3, 4), (3, 4); insert t2 values (1, 2), (1, 2), (2, 3), (2, 3), (2, 3), (2, 3), (4, 5); +select * from t1 intersect all select * from t2; +a b +1 2 +2 3 +1 2 +2 3 +select * from t1 intersect all select * from t2 union values (1, 2); +a b +1 2 +2 3 +select * from t1 intersect all (select * from t2 union values (1, 2)); +a b +1 2 +2 3 +(select * from t1 intersect all select * from t2) union values (1, 2); +a b +1 2 +2 3 +create view v1 as select * from t1 intersect all select * from t2 union values (1, 2); +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` intersect all select `t2`.`a` AS `a`,`t2`.`b` AS `b` from `t2` union values (1,2) latin1 latin1_swedish_ci +select * from v1; +a b +1 2 +2 3 +create view v2 as select * from t1 union values (1, 2) intersect all select * from t2; +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` union select `__5`.`1` AS `1`,`__5`.`2` AS `2` from (values (1,2) intersect all select `t2`.`a` AS `a`,`t2`.`b` AS `b` from `t2`) `__5` latin1 latin1_swedish_ci +select * from v2; +a b +1 2 +2 3 +3 4 +set sql_mode= 'oracle'; select * from t1 intersect select * from t2; a b 1 2 @@ -1169,8 +1214,6 @@ select * from t1 intersect all select * from t2 union values (1, 2); a b 1 2 2 3 -1 2 -2 3 select * from t1 intersect all (select * from t2 union values (1, 2)); a b 1 2 @@ -1181,9 +1224,209 @@ a b 2 3 explain select * from t1 intersect all select * from t2 union values (1, 2); id select_type table type possible_keys key key_len ref rows Extra -1 PRIMARY t1 ALL NULL NULL NULL NULL 7 -2 INTERSECT t2 ALL NULL NULL NULL NULL 7 -3 UNION NULL NULL NULL NULL NULL NULL NULL No tables used -NULL UNIT RESULT ALL NULL NULL NULL NULL NULL +1 PRIMARY ALL NULL NULL NULL NULL 8 +4 DERIVED ALL NULL NULL NULL NULL 7 +2 DERIVED t1 ALL NULL NULL NULL NULL 7 +3 INTERSECT t2 ALL NULL NULL NULL NULL 7 +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +5 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +NULL UNION RESULT ALL NULL NULL NULL NULL NULL +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select "__6"."a" AS "a","__6"."b" AS "b" from (select "__4"."a" AS "a","__4"."b" AS "b" from (select "t1"."a" AS "a","t1"."b" AS "b" from "t1" intersect all select "t2"."a" AS "a","t2"."b" AS "b" from "t2") "__4" union values (1,2)) "__6" latin1 latin1_swedish_ci +select * from v1; +a b +1 2 +2 3 +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE VIEW "v2" AS select "__7"."a" AS "a","__7"."b" AS "b" from (select "t1"."a" AS "a","t1"."b" AS "b" from "t1" union select "__5"."1" AS "1","__5"."2" AS "2" from (select "__6"."1" AS "1","__6"."2" AS "2" from (values (1,2) intersect all select "t2"."a" AS "a","t2"."b" AS "b" from "t2") "__6") "__5") "__7" latin1 latin1_swedish_ci +select * from v2; +a b +1 2 +2 3 +3 4 +create view v3 as select * from t1 union values (1, 2) intersect all select * from t2; +show create view v3; +View Create View character_set_client collation_connection +v3 CREATE VIEW "v3" AS select "__6"."a" AS "a","__6"."b" AS "b" from (select "__8"."a" AS "a","__8"."b" AS "b" from (select "__4"."a" AS "a","__4"."b" AS "b" from (select "__6"."a" AS "a","__6"."b" AS "b" from (select "t1"."a" AS "a","t1"."b" AS "b" from "t1" union values (1,2)) "__6") "__4" intersect all select "t2"."a" AS "a","t2"."b" AS "b" from "t2") "__8") "__6" latin1 latin1_swedish_ci +select * from v3; +a b +1 2 +2 3 drop tables t1, t2; +drop view v1, v2, v3; +create table t3 (x int); +create table u3 (x int); +create table i3 (x int); +create view v4 as SELECT * from t3 union select * from u3 intersect all select * from i3; +select * from v4; +x +drop tables t3, u3, i3; +drop view v4; +set sql_mode= default; +# +# MDEV-37325 Incorrect results for INTERSECT ALL in ORACLE mode +# +create table t1 (a int, b int); +create table t2 like t1; +insert t1 values (1, 2), (1, 2), (1, 2), (1, 2); +insert t2 values (1, 2), (1, 2); +select * from t1 except all select * from t2 intersect all values (1, 2); +a b +1 2 +1 2 +1 2 +explain select * from t1 except all select * from t2 intersect all values (1, 2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 4 +4 EXCEPT ALL NULL NULL NULL NULL 2 +2 DERIVED t2 ALL NULL NULL NULL NULL 2 +3 INTERSECT NULL NULL NULL NULL NULL NULL NULL No tables used +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL +Explain select * from (select * from (select * from t1 except all select * from t2) __3 intersect all values (1,2)) __5; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +2 DERIVED ALL NULL NULL NULL NULL 4 +3 DERIVED t1 ALL NULL NULL NULL NULL 4 +4 EXCEPT t2 ALL NULL NULL NULL NULL 2 +NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL +5 INTERSECT NULL NULL NULL NULL NULL NULL NULL No tables used +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +create view v1 as select * from t1 except all select * from t2 intersect all values (1, 2); +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` except all select `__5`.`a` AS `a`,`__5`.`b` AS `b` from (select `t2`.`a` AS `a`,`t2`.`b` AS `b` from `t2` intersect all values (1,2)) `__5` latin1 latin1_swedish_ci +select * from v1; +a b +1 2 +1 2 +1 2 +drop view v1; +create view v1 as ((select * from t1 except all select * from t2) intersect all values (1, 2)); +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `__5`.`a` AS `a`,`__5`.`b` AS `b` from (select `t1`.`a` AS `a`,`t1`.`b` AS `b` from `t1` except all select `t2`.`a` AS `a`,`t2`.`b` AS `b` from `t2`) `__5` intersect all values (1,2) latin1 latin1_swedish_ci +select * from v1; +a b +1 2 +drop view v1; +explain select * from ((select * from t1 except all select * from t2) intersect all values (1, 2)) v; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +5 DERIVED ALL NULL NULL NULL NULL 4 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 +3 EXCEPT t2 ALL NULL NULL NULL NULL 2 +NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL +4 INTERSECT NULL NULL NULL NULL NULL NULL NULL No tables used +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +# Oracle: first UNION, then INTERSECT ALL +set sql_mode= 'oracle'; +create view v2 as select * from t1 except all select * from t2 intersect all values (1, 2); +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE VIEW "v2" AS select "__6"."a" AS "a","__6"."b" AS "b" from (select "__8"."a" AS "a","__8"."b" AS "b" from (select "__4"."a" AS "a","__4"."b" AS "b" from (select "__6"."a" AS "a","__6"."b" AS "b" from (select "t1"."a" AS "a","t1"."b" AS "b" from "t1" except all select "t2"."a" AS "a","t2"."b" AS "b" from "t2") "__6") "__4" intersect all values (1,2)) "__8") "__6" latin1 latin1_swedish_ci +select * from v2; +a b +1 2 +drop view v2; +EXPLAIN select * from t1 except all select * from t2 intersect all values (1, 2); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY ALL NULL NULL NULL NULL 2 +4 DERIVED ALL NULL NULL NULL NULL 4 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 +3 EXCEPT t2 ALL NULL NULL NULL NULL 2 +NULL EXCEPT RESULT ALL NULL NULL NULL NULL NULL +5 INTERSECT NULL NULL NULL NULL NULL NULL NULL No tables used +NULL INTERSECT RESULT ALL NULL NULL NULL NULL NULL +select * from t2 union all select * from t2; +a b +1 2 +1 2 +1 2 +1 2 +select * from t1 except all select * from t2 intersect all values (1, 2) union values (2, 3); +a b +1 2 +2 3 +select * from t2 union all select * from t2 except all select * from t2 intersect all values (1, 2) union values (2, 3); +a b +1 2 +2 3 +select * from t1 except all select * from t2 union values (2, 3); +a b +1 2 +2 3 +# Default: first INTERSECT ALL, then UNION +select * from t1 union values (1, 2) intersect all select * from t2; +a b +1 2 +select * from t1 union (values (1, 2) intersect all select * from t2); +a b +1 2 +set sql_mode= default; +select * from t1 union values (1, 2) intersect all select * from t2; +a b +1 2 +select * from t1 union (values (1, 2) intersect all select * from t2); +a b +1 2 +set sql_mode= 'oracle'; +create or replace table t2 like t1; +insert t2 values (1, 2), (2, 3); +create table t3 select * from t1 except all select * from t2; +select * from t3; +a b +1 2 +1 2 +1 2 +select * from t3 intersect all select * from t1; +a b +1 2 +1 2 +1 2 +show create table t2; +Table Create Table +t2 CREATE TABLE "t2" ( + "a" int(11) DEFAULT NULL, + "b" int(11) DEFAULT NULL +) +select * from t2 order by a desc; +a b +2 3 +1 2 +select * from t1 except all select * from t2; +a b +1 2 +1 2 +1 2 +select * from t1 except all select * from t2 union all values (0, 1); +a b +1 2 +1 2 +1 2 +0 1 +select * from t1 except all select * from t2 union all values (0, 1) order by a limit 2; +a b +0 1 +1 2 +select * from t1 except all select * from t2 intersect all select * from t1; +a b +1 2 +1 2 +1 2 +select * from t1 except all select * from t2 intersect all select * from t1 union all select * from t2; +a b +1 2 +1 2 +1 2 +1 2 +2 3 +select * from t1 except all select * from t2 intersect all select * from t1 union all select * from t2 order by a desc limit 3; +a b +2 3 +1 2 +1 2 +drop tables t1, t2, t3; set sql_mode= default; diff --git a/mysql-test/main/intersect_all.test b/mysql-test/main/intersect_all.test index b318914fe8cab..6ac8df4be14b4 100644 --- a/mysql-test/main/intersect_all.test +++ b/mysql-test/main/intersect_all.test @@ -338,13 +338,22 @@ create table i3 (x int); explain SELECT * from t3 union select * from u3 intersect all select * from i3; set sql_mode= 'oracle'; explain SELECT * from t3 union select * from u3 intersect all select * from i3; +# TODO: there is a bug in --view protocol, it displays column name as '*' instead of 'x' +--replace_result * x select * from t3 union select * from u3 intersect select * from i3; +--replace_result * x SELECT * from t3 union select * from u3 intersect all select * from i3; insert into t3 values (0); insert into i3 values (0); +--replace_result * x Select * from t3 union select * from u3 intersect select * from i3; +--replace_result * x SELECT * FROM t3 UNION SELECT * FROM u3 INTERSECT ALL SELECT * FROM i3; +# CREATE VIEW still works good +create view v as select * from t3 union select * from u3 intersect select * from i3; +select * from v; drop tables t3, u3, i3; +drop view v; --enable_info --echo # First line of these results is column names, not the result @@ -374,10 +383,26 @@ values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3 values (1, 2) union all values (1, 2) union values (4, 3) union all values (4, 3) union all values (1, 2) union values (1, 2); --disable_info +set sql_mode= default; create table t1 (a int, b int); create table t2 like t1; insert t1 values (1, 2), (1, 2), (1, 2), (2, 3), (2, 3), (3, 4), (3, 4); insert t2 values (1, 2), (1, 2), (2, 3), (2, 3), (2, 3), (2, 3), (4, 5); + +select * from t1 intersect all select * from t2; +select * from t1 intersect all select * from t2 union values (1, 2); +select * from t1 intersect all (select * from t2 union values (1, 2)); +(select * from t1 intersect all select * from t2) union values (1, 2); + +create view v1 as select * from t1 intersect all select * from t2 union values (1, 2); +show create view v1; +select * from v1; + +create view v2 as select * from t1 union values (1, 2) intersect all select * from t2; +show create view v2; +select * from v2; + +set sql_mode= 'oracle'; select * from t1 intersect select * from t2; select * from t1 intersect all select * from t2; --echo # Default: first INTERSECT ALL, then UNION @@ -392,5 +417,85 @@ select * from t1 intersect all select * from t2 union values (1, 2); select * from t1 intersect all (select * from t2 union values (1, 2)); (select * from t1 intersect all select * from t2) union values (1, 2); explain select * from t1 intersect all select * from t2 union values (1, 2); + +show create view v1; +select * from v1; + +show create view v2; +select * from v2; + +create view v3 as select * from t1 union values (1, 2) intersect all select * from t2; +show create view v3; +select * from v3; + drop tables t1, t2; +drop view v1, v2, v3; + +create table t3 (x int); +create table u3 (x int); +create table i3 (x int); +create view v4 as SELECT * from t3 union select * from u3 intersect all select * from i3; +select * from v4; +drop tables t3, u3, i3; +drop view v4; +set sql_mode= default; + +--echo # +--echo # MDEV-37325 Incorrect results for INTERSECT ALL in ORACLE mode +--echo # +create table t1 (a int, b int); +create table t2 like t1; +insert t1 values (1, 2), (1, 2), (1, 2), (1, 2); +insert t2 values (1, 2), (1, 2); +select * from t1 except all select * from t2 intersect all values (1, 2); +explain select * from t1 except all select * from t2 intersect all values (1, 2); +Explain select * from (select * from (select * from t1 except all select * from t2) __3 intersect all values (1,2)) __5; + +create view v1 as select * from t1 except all select * from t2 intersect all values (1, 2); +show create view v1; +select * from v1; +drop view v1; + +create view v1 as ((select * from t1 except all select * from t2) intersect all values (1, 2)); +show create view v1; +select * from v1; +drop view v1; + +explain select * from ((select * from t1 except all select * from t2) intersect all values (1, 2)) v; + +--echo # Oracle: first UNION, then INTERSECT ALL +set sql_mode= 'oracle'; +create view v2 as select * from t1 except all select * from t2 intersect all values (1, 2); +show create view v2; +select * from v2; +drop view v2; + +EXPLAIN select * from t1 except all select * from t2 intersect all values (1, 2); + +select * from t2 union all select * from t2; +select * from t1 except all select * from t2 intersect all values (1, 2) union values (2, 3); +select * from t2 union all select * from t2 except all select * from t2 intersect all values (1, 2) union values (2, 3); +select * from t1 except all select * from t2 union values (2, 3); +--echo # Default: first INTERSECT ALL, then UNION +select * from t1 union values (1, 2) intersect all select * from t2; +select * from t1 union (values (1, 2) intersect all select * from t2); +set sql_mode= default; +select * from t1 union values (1, 2) intersect all select * from t2; +select * from t1 union (values (1, 2) intersect all select * from t2); + +set sql_mode= 'oracle'; +create or replace table t2 like t1; +insert t2 values (1, 2), (2, 3); +create table t3 select * from t1 except all select * from t2; +select * from t3; +select * from t3 intersect all select * from t1; +show create table t2; +select * from t2 order by a desc; +select * from t1 except all select * from t2; +select * from t1 except all select * from t2 union all values (0, 1); +select * from t1 except all select * from t2 union all values (0, 1) order by a limit 2; +select * from t1 except all select * from t2 intersect all select * from t1; +select * from t1 except all select * from t2 intersect all select * from t1 union all select * from t2; +select * from t1 except all select * from t2 intersect all select * from t1 union all select * from t2 order by a desc limit 3; +drop tables t1, t2, t3; set sql_mode= default; diff --git a/mysql-test/main/invisible_field_grant_completely.test b/mysql-test/main/invisible_field_grant_completely.test index b27071ada5672..df05af9a06923 100644 --- a/mysql-test/main/invisible_field_grant_completely.test +++ b/mysql-test/main/invisible_field_grant_completely.test @@ -45,7 +45,6 @@ select * from t1; select invisible from t1; disconnect con1; ---source include/wait_until_disconnected.inc --echo --echo #Final Cleanup connection default; diff --git a/mysql-test/main/invisible_field_grant_system.test b/mysql-test/main/invisible_field_grant_system.test index 04ea5f14be130..c65cc7ab2812c 100644 --- a/mysql-test/main/invisible_field_grant_system.test +++ b/mysql-test/main/invisible_field_grant_system.test @@ -41,11 +41,9 @@ select * from t1; select count(row_start) from t1; disconnect con1; ---source include/wait_until_disconnected.inc --echo --echo #Cleanup ---source include/wait_until_disconnected.inc connection default; drop user user_1; drop database d; diff --git a/mysql-test/main/ipv4_as_ipv6.test b/mysql-test/main/ipv4_as_ipv6.test index 2a3ab6647fff7..2ab42f62c4333 100644 --- a/mysql-test/main/ipv4_as_ipv6.test +++ b/mysql-test/main/ipv4_as_ipv6.test @@ -5,9 +5,6 @@ # Can't be tested with embedded server --source include/not_embedded.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - echo =============Test of '127.0.0.1' (IPv4) ===========================; let $IPv6= 127.0.0.1; --source include/ipv6_clients.inc @@ -55,6 +52,3 @@ let $IPv6= ::1; --error 2002,2006 connect (con1, $IPv6, root, , test, $MASTER_MYPORT,); --enable_query_log - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/ipv6.test b/mysql-test/main/ipv6.test index 24ab09b7083ae..1619cba4b3725 100644 --- a/mysql-test/main/ipv6.test +++ b/mysql-test/main/ipv6.test @@ -5,9 +5,6 @@ # Can't be tested with embedded server --source include/not_embedded.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - echo =============Test of '::1' ========================================; let $IPv6= ::1; --source include/ipv6_clients.inc @@ -27,6 +24,3 @@ echo =============Test of '0:0:0:0:0:0:0:1' ============================; let $IPv6= 0:0:0:0:0:0:0:1; --source include/ipv6_clients.inc --source include/ipv6.inc - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/join_nested.result b/mysql-test/main/join_nested.result index 88d95bc61ecd2..7a5e56658a455 100644 --- a/mysql-test/main/join_nested.result +++ b/mysql-test/main/join_nested.result @@ -2062,4 +2062,67 @@ LEFT JOIN (t1 a LEFT JOIN t1 b ON t1.i = b.i) ON c.i = t1.i); 1 1 DROP TABLE t1; +# +# MDEV-35206: Assertion in JOIN::dbug_verify_sj_inner_tables +# +SET @save_optimizer_join_limit_pref_ratio= @@optimizer_join_limit_pref_ratio; +SET @save_optimizer_search_depth= @@optimizer_search_depth; +CREATE TABLE t1 (c1 VARCHAR(64) DEFAULT NULL, c2 VARCHAR(8) DEFAULT NULL); +INSERT INTO t1 (c1) values ('one'); +INSERT INTO t1 (c2) values ('2'); +SET optimizer_join_limit_pref_ratio=10; +SET optimizer_search_depth=1; +SELECT +c1 +FROM +t1 +WHERE +c2 IN (SELECT c2 +FROM t1 +WHERE c1 IN (SELECT c1 +FROM t1 +WHERE c1 IN (NULL) +) +) +ORDER BY c1 LIMIT 1; +c1 +DROP TABLE t1; +# +# similar issue with join::cur_embedding_map +# +CREATE TABLE t10 (a int, b int, index(b)); +INSERT INTO t10 SELECT seq, seq FROM seq_1_to_10; +CREATE TABLE t11(a int, b int); +CREATE TABLE t12(a int, b int, index(b)); +INSERT INTO t11 select seq, seq FROM seq_1_to_20; +INSERT INTO t12 select seq, seq FROM seq_1_to_40; +CREATE TABLE t13(a int, b int); +CREATE TABLE t14(a int, b int, index(b)); +INSERT INTO t13 select seq, seq FROM seq_1_to_20; +INSERT INTO t14 select seq, seq FROM seq_1_to_40; +ANALYZE TABLE t10, t11, t12; +Table Op Msg_type Msg_text +test.t10 analyze status Engine-independent statistics collected +test.t10 analyze status Table is already up to date +test.t11 analyze status Engine-independent statistics collected +test.t11 analyze status OK +test.t12 analyze status Engine-independent statistics collected +test.t12 analyze status Table is already up to date +EXPLAIN SELECT * +FROM +t10 LEFT JOIN +( +t11 JOIN t12 ON t11.b=t12.b +left join (t13 join t14 on t13.b=t14.b) on t13.a=t11.a +) ON t10.a=t11.a +ORDER BY t10.b LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t10 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort +1 SIMPLE t11 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t12 ref b b 5 test.t11.b 1 +1 SIMPLE t13 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t14 ref b b 5 test.t13.b 1 +DROP TABLE t10, t11, t12, t13, t14; +SET optimizer_join_limit_pref_ratio= @save_optimizer_join_limit_pref_ratio; +SET optimizer_search_depth= @save_optimizer_search_depth; # end of 10.11 tests diff --git a/mysql-test/main/join_nested.test b/mysql-test/main/join_nested.test index 99ea7bd1faab9..1e045af4a1f02 100644 --- a/mysql-test/main/join_nested.test +++ b/mysql-test/main/join_nested.test @@ -2,6 +2,7 @@ --disable_warnings DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9; --enable_warnings +--source include/have_sequence.inc SET @save_optimizer_switch=@@optimizer_switch; SET optimizer_switch=ifnull(@optimizer_switch_for_join_nested_test,'outer_join_with_cache=off'); @@ -1471,4 +1472,69 @@ SELECT 1 FROM t1 WHERE i IN LEFT JOIN (t1 a LEFT JOIN t1 b ON t1.i = b.i) ON c.i = t1.i); DROP TABLE t1; + +--echo # +--echo # MDEV-35206: Assertion in JOIN::dbug_verify_sj_inner_tables +--echo # + +SET @save_optimizer_join_limit_pref_ratio= @@optimizer_join_limit_pref_ratio; +SET @save_optimizer_search_depth= @@optimizer_search_depth; + +CREATE TABLE t1 (c1 VARCHAR(64) DEFAULT NULL, c2 VARCHAR(8) DEFAULT NULL); +INSERT INTO t1 (c1) values ('one'); +INSERT INTO t1 (c2) values ('2'); + +SET optimizer_join_limit_pref_ratio=10; +SET optimizer_search_depth=1; + +SELECT + c1 +FROM + t1 +WHERE + c2 IN (SELECT c2 + FROM t1 + WHERE c1 IN (SELECT c1 + FROM t1 + WHERE c1 IN (NULL) + ) + ) +ORDER BY c1 LIMIT 1; + +DROP TABLE t1; + +--echo # +--echo # similar issue with join::cur_embedding_map +--echo # +CREATE TABLE t10 (a int, b int, index(b)); +INSERT INTO t10 SELECT seq, seq FROM seq_1_to_10; + +CREATE TABLE t11(a int, b int); +CREATE TABLE t12(a int, b int, index(b)); + +INSERT INTO t11 select seq, seq FROM seq_1_to_20; +INSERT INTO t12 select seq, seq FROM seq_1_to_40; + +CREATE TABLE t13(a int, b int); +CREATE TABLE t14(a int, b int, index(b)); + +INSERT INTO t13 select seq, seq FROM seq_1_to_20; +INSERT INTO t14 select seq, seq FROM seq_1_to_40; + +ANALYZE TABLE t10, t11, t12; + +EXPLAIN SELECT * +FROM + t10 LEFT JOIN + ( + t11 JOIN t12 ON t11.b=t12.b + left join (t13 join t14 on t13.b=t14.b) on t13.a=t11.a + ) ON t10.a=t11.a +ORDER BY t10.b LIMIT 1; + +DROP TABLE t10, t11, t12, t13, t14; + +SET optimizer_join_limit_pref_ratio= @save_optimizer_join_limit_pref_ratio; +SET optimizer_search_depth= @save_optimizer_search_depth; + --echo # end of 10.11 tests diff --git a/mysql-test/main/join_nested_jcl6.result b/mysql-test/main/join_nested_jcl6.result index 04658dcda1051..92efe098d0191 100644 --- a/mysql-test/main/join_nested_jcl6.result +++ b/mysql-test/main/join_nested_jcl6.result @@ -2071,6 +2071,69 @@ LEFT JOIN (t1 a LEFT JOIN t1 b ON t1.i = b.i) ON c.i = t1.i); 1 1 DROP TABLE t1; +# +# MDEV-35206: Assertion in JOIN::dbug_verify_sj_inner_tables +# +SET @save_optimizer_join_limit_pref_ratio= @@optimizer_join_limit_pref_ratio; +SET @save_optimizer_search_depth= @@optimizer_search_depth; +CREATE TABLE t1 (c1 VARCHAR(64) DEFAULT NULL, c2 VARCHAR(8) DEFAULT NULL); +INSERT INTO t1 (c1) values ('one'); +INSERT INTO t1 (c2) values ('2'); +SET optimizer_join_limit_pref_ratio=10; +SET optimizer_search_depth=1; +SELECT +c1 +FROM +t1 +WHERE +c2 IN (SELECT c2 +FROM t1 +WHERE c1 IN (SELECT c1 +FROM t1 +WHERE c1 IN (NULL) +) +) +ORDER BY c1 LIMIT 1; +c1 +DROP TABLE t1; +# +# similar issue with join::cur_embedding_map +# +CREATE TABLE t10 (a int, b int, index(b)); +INSERT INTO t10 SELECT seq, seq FROM seq_1_to_10; +CREATE TABLE t11(a int, b int); +CREATE TABLE t12(a int, b int, index(b)); +INSERT INTO t11 select seq, seq FROM seq_1_to_20; +INSERT INTO t12 select seq, seq FROM seq_1_to_40; +CREATE TABLE t13(a int, b int); +CREATE TABLE t14(a int, b int, index(b)); +INSERT INTO t13 select seq, seq FROM seq_1_to_20; +INSERT INTO t14 select seq, seq FROM seq_1_to_40; +ANALYZE TABLE t10, t11, t12; +Table Op Msg_type Msg_text +test.t10 analyze status Engine-independent statistics collected +test.t10 analyze status Table is already up to date +test.t11 analyze status Engine-independent statistics collected +test.t11 analyze status OK +test.t12 analyze status Engine-independent statistics collected +test.t12 analyze status Table is already up to date +EXPLAIN SELECT * +FROM +t10 LEFT JOIN +( +t11 JOIN t12 ON t11.b=t12.b +left join (t13 join t14 on t13.b=t14.b) on t13.a=t11.a +) ON t10.a=t11.a +ORDER BY t10.b LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t10 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort +1 SIMPLE t11 hash_ALL NULL #hash#$hj 5 test.t10.a 20 Using where; Using join buffer (flat, BNLH join) +1 SIMPLE t12 ref b b 5 test.t11.b 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +1 SIMPLE t13 hash_ALL NULL #hash#$hj 5 test.t10.a 20 Using where; Using join buffer (incremental, BNLH join) +1 SIMPLE t14 ref b b 5 test.t13.b 1 Using join buffer (incremental, BKA join); Key-ordered Rowid-ordered scan +DROP TABLE t10, t11, t12, t13, t14; +SET optimizer_join_limit_pref_ratio= @save_optimizer_join_limit_pref_ratio; +SET optimizer_search_depth= @save_optimizer_search_depth; # end of 10.11 tests CREATE TABLE t5 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b)); CREATE TABLE t6 (a int, b int, c int, PRIMARY KEY(a), KEY b_i (b)); diff --git a/mysql-test/main/join_optimizer.result b/mysql-test/main/join_optimizer.result index a1404d40a9d63..4c335f83f0c96 100644 --- a/mysql-test/main/join_optimizer.result +++ b/mysql-test/main/join_optimizer.result @@ -1,4 +1,3 @@ -drop table if exists t0,t1,t2,t3; # # BUG#38049 incorrect rows estimations with references from preceding table # @@ -56,4 +55,12 @@ explain select * from t1 where col1=1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ref idx1 idx1 5 const 1 Using index drop table t1; -End of 10.5 tests +# End of 10.5 tests +# +# MDEV-38168 Lots of joins can crash the server +# +create table t1 (x int) engine=innodb; +$many_joins; +ERROR HY000: Too many tables; MariaDB can only use 61 tables in a join +drop table t1; +# End of 10.11 tests diff --git a/mysql-test/main/join_optimizer.test b/mysql-test/main/join_optimizer.test index 5cd61baa1cc47..3b8c6a4b4846b 100644 --- a/mysql-test/main/join_optimizer.test +++ b/mysql-test/main/join_optimizer.test @@ -1,7 +1,3 @@ ---disable_warnings -drop table if exists t0,t1,t2,t3; ---enable_warnings - --source include/have_innodb.inc --echo # @@ -68,4 +64,20 @@ explain select * from t1 where col1=1; drop table t1; ---echo End of 10.5 tests +--echo # End of 10.5 tests + +--echo # +--echo # MDEV-38168 Lots of joins can crash the server +--echo # +create table t1 (x int) engine=innodb; +let $many_joins=SELECT * FROM t1; +let $b=8192; +while ($b) { + let $many_joins=$many_joins JOIN t1 x$b; + dec $b; +} +--error ER_TOO_MANY_TABLES +evalp $many_joins; +drop table t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/join_outer.result b/mysql-test/main/join_outer.result index b535f7574bde8..815714417604a 100644 --- a/mysql-test/main/join_outer.result +++ b/mysql-test/main/join_outer.result @@ -2911,4 +2911,22 @@ Z 1 Y 1 X 1 drop view v0, v1, v2, v3; drop table t1, t2, t3; # end of 10.3 tests +# +# MDEV-37653 Unexpected result of prepared statement when use boolean value as parameters +# +create table t0(c0 real); +create table t1 like t0; +insert into t1 values (1); +insert into t0 values (1); +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is true); +c0 c0 +1 NULL +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is false); +c0 c0 +1 NULL +select t1.c0, t0.c0 from t1 left join t0 on false where (false or ((t0.c0 is true) in (false))); +c0 c0 +1 NULL +drop table t0, t1; +# end of 10.11 tests SET optimizer_switch=@org_optimizer_switch; diff --git a/mysql-test/main/join_outer.test b/mysql-test/main/join_outer.test index 87dfdb2570fdf..6686d3e939ec9 100644 --- a/mysql-test/main/join_outer.test +++ b/mysql-test/main/join_outer.test @@ -2434,4 +2434,18 @@ drop table t1, t2, t3; --echo # end of 10.3 tests +--echo # +--echo # MDEV-37653 Unexpected result of prepared statement when use boolean value as parameters +--echo # +create table t0(c0 real); +create table t1 like t0; +insert into t1 values (1); +insert into t0 values (1); +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is true); +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is false); +select t1.c0, t0.c0 from t1 left join t0 on false where (false or ((t0.c0 is true) in (false))); +drop table t0, t1; + +--echo # end of 10.11 tests + SET optimizer_switch=@org_optimizer_switch; diff --git a/mysql-test/main/join_outer_jcl6.result b/mysql-test/main/join_outer_jcl6.result index 38223c904b540..a14fa7807678e 100644 --- a/mysql-test/main/join_outer_jcl6.result +++ b/mysql-test/main/join_outer_jcl6.result @@ -2918,4 +2918,22 @@ Z 1 Y 1 X 1 drop view v0, v1, v2, v3; drop table t1, t2, t3; # end of 10.3 tests +# +# MDEV-37653 Unexpected result of prepared statement when use boolean value as parameters +# +create table t0(c0 real); +create table t1 like t0; +insert into t1 values (1); +insert into t0 values (1); +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is true); +c0 c0 +1 NULL +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is false); +c0 c0 +1 NULL +select t1.c0, t0.c0 from t1 left join t0 on false where (false or ((t0.c0 is true) in (false))); +c0 c0 +1 NULL +drop table t0, t1; +# end of 10.11 tests SET optimizer_switch=@org_optimizer_switch; diff --git a/mysql-test/main/join_outer_reorder.result b/mysql-test/main/join_outer_reorder.result new file mode 100644 index 0000000000000..02adad767ad33 --- /dev/null +++ b/mysql-test/main/join_outer_reorder.result @@ -0,0 +1,6233 @@ +set @join_outer_reorder_tmp=@@optimizer_switch; +set optimizer_switch='reorder_outer_joins=on'; +create table t1 (a int); +insert into t1 select seq from seq_1_to_10000; +create table t2 ( +a int, +b int, +index(a) +); +insert into t2 +select +A.seq, +B.seq +from +seq_1_to_1000 A, +seq_1_to_10 B; +create table t3 ( +a int, +b int, +index(a) +); +insert into t3 +select +A.seq, +A.seq +from +seq_1_to_1000 A; +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status Table is already up to date +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status Table is already up to date +set optimizer_trace=1; +explain +select * +from +t1 +left join t3 on t3.a=t1.a +left join t2 on t2.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 +1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where +1 SIMPLE t2 ref a a 5 test.t1.a 10 Using where +# This will show that t2 and t3 only depend on t1: +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; +DEPS +[ + [ + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": + [] + }, + { + "table": "t3", + "row_may_be_null": true, + "map_bit": 1, + "depends_on_map_bits": + ["0"] + }, + { + "table": "t2", + "row_may_be_null": true, + "map_bit": 2, + "depends_on_map_bits": + ["0"] + } + ] +] +# This will have same join order like previous EXPLAIN +# as the optimizer considers the queries identical +explain +select * +from +t1 +left join t2 on t2.a=t1.a +left join t3 on t3.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 +1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where +1 SIMPLE t2 ref a a 5 test.t1.a 10 Using where +# This will show that t2 and t3 only depend on t1: +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; +DEPS +[ + [ + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": + [] + }, + { + "table": "t2", + "row_may_be_null": true, + "map_bit": 1, + "depends_on_map_bits": + ["0"] + }, + { + "table": "t3", + "row_may_be_null": true, + "map_bit": 2, + "depends_on_map_bits": + ["0"] + } + ] +] +# Make t3's ON expression depend on t2: +explain +select * +from +t1 +left join t2 on t2.a=t1.a +left join t3 on t3.a=t1.a and t3.b=t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 +1 SIMPLE t2 ref a a 5 test.t1.a 10 Using where +1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; +DEPS +[ + [ + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": + [] + }, + { + "table": "t2", + "row_may_be_null": true, + "map_bit": 1, + "depends_on_map_bits": + ["0"] + }, + { + "table": "t3", + "row_may_be_null": true, + "map_bit": 2, + "depends_on_map_bits": + [ + "0", + "1" + ] + } + ] +] +# +# Now, try a nested join: +# +create table t4 ( +a int, +b int +); +insert into t4 values (1,1); +explain +select * +from +t1 +left join (t2 join t4 as t4_2 on t2.b=t4_2.b) on t2.a=t1.a +left join (t3 join t4 as t4_3 on t3.b=t4_3.b) on t3.a=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 +1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where +1 SIMPLE t4_3 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE t4_2 ALL NULL NULL NULL NULL 1 Using where +1 SIMPLE t2 ref a a 5 test.t1.a 10 Using where +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; +DEPS +[ + [ + { + "table": "t1", + "row_may_be_null": false, + "map_bit": 0, + "depends_on_map_bits": + [] + }, + { + "table": "t2", + "row_may_be_null": true, + "map_bit": 1, + "depends_on_map_bits": + ["0"] + }, + { + "table": "t4_2", + "row_may_be_null": true, + "map_bit": 2, + "depends_on_map_bits": + ["0"] + }, + { + "table": "t3", + "row_may_be_null": true, + "map_bit": 3, + "depends_on_map_bits": + ["0"] + }, + { + "table": "t4_3", + "row_may_be_null": true, + "map_bit": 4, + "depends_on_map_bits": + ["0"] + } + ] +] +drop table t1,t2,t3,t4; +DROP TABLE IF EXISTS t0,t1,t2,t3,t4,t5,t6,t7,t8,t9; +SET @save_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=ifnull(@optimizer_switch_for_join_nested_test,'outer_join_with_cache=off'); +set join_cache_level=1; +CREATE TABLE t0 (a int, b int, c int); +CREATE TABLE t1 (a int, b int, c int); +CREATE TABLE t2 (a int, b int, c int); +CREATE TABLE t3 (a int, b int, c int); +CREATE TABLE t4 (a int, b int, c int); +CREATE TABLE t5 (a int, b int, c int); +CREATE TABLE t6 (a int, b int, c int); +CREATE TABLE t7 (a int, b int, c int); +CREATE TABLE t8 (a int, b int, c int); +CREATE TABLE t9 (a int, b int, c int); +INSERT INTO t0 VALUES (1,1,0), (1,2,0), (2,2,0); +INSERT INTO t1 VALUES (1,3,0), (2,2,0), (3,2,0); +INSERT INTO t2 VALUES (3,3,0), (4,2,0), (5,3,0); +INSERT INTO t3 VALUES (1,2,0), (2,2,0); +INSERT INTO t4 VALUES (3,2,0), (4,2,0); +INSERT INTO t5 VALUES (3,1,0), (2,2,0), (3,3,0); +INSERT INTO t6 VALUES (3,2,0), (6,2,0), (6,1,0); +INSERT INTO t7 VALUES (1,1,0), (2,2,0); +INSERT INTO t8 VALUES (0,2,0), (1,2,0); +INSERT INTO t9 VALUES (1,1,0), (1,2,0), (3,3,0); +SELECT t2.a,t2.b +FROM t2; +a b +3 3 +4 2 +5 3 +SELECT t3.a,t3.b +FROM t3; +a b +1 2 +2 2 +SELECT t4.a,t4.b +FROM t4; +a b +3 2 +4 2 +SELECT t3.a,t3.b,t4.a,t4.b +FROM t3,t4; +a b a b +1 2 3 2 +2 2 3 2 +1 2 4 2 +2 2 4 2 +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t2.b=t4.b; +a b a b a b +3 3 NULL NULL NULL NULL +4 2 1 2 3 2 +4 2 1 2 4 2 +4 2 2 2 3 2 +4 2 2 2 4 2 +5 3 NULL NULL NULL NULL +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b; +a b a b a b +3 3 NULL NULL NULL NULL +4 2 1 2 3 2 +4 2 1 2 4 2 +5 3 NULL NULL NULL NULL +EXPLAIN EXTENDED +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t2.b=t4.b +WHERE t3.a=1 OR t3.c IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t4`.`b` = `test`.`t2`.`b`) where `test`.`t3`.`a` = 1 or `test`.`t3`.`c` is null +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t2.b=t4.b +WHERE t3.a=1 OR t3.c IS NULL; +a b a b a b +3 3 NULL NULL NULL NULL +4 2 1 2 3 2 +4 2 1 2 4 2 +5 3 NULL NULL NULL NULL +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t2.b=t4.b +WHERE t3.a>1 OR t3.c IS NULL; +a b a b a b +3 3 NULL NULL NULL NULL +4 2 2 2 3 2 +4 2 2 2 4 2 +5 3 NULL NULL NULL NULL +SELECT t5.a,t5.b +FROM t5; +a b +3 1 +2 2 +3 3 +SELECT t3.a,t3.b,t4.a,t4.b,t5.a,t5.b +FROM t3,t4,t5; +a b a b a b +1 2 3 2 3 1 +2 2 3 2 3 1 +1 2 4 2 3 1 +2 2 4 2 3 1 +1 2 3 2 2 2 +2 2 3 2 2 2 +1 2 4 2 2 2 +2 2 4 2 2 2 +1 2 3 2 3 3 +2 2 3 2 3 3 +1 2 4 2 3 3 +2 2 4 2 3 3 +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b +FROM t2 +LEFT JOIN +(t3, t4, t5) +ON t2.b=t4.b; +a b a b a b a b +3 3 NULL NULL NULL NULL NULL NULL +4 2 1 2 3 2 3 1 +4 2 1 2 3 2 2 2 +4 2 1 2 3 2 3 3 +4 2 1 2 4 2 3 1 +4 2 1 2 4 2 2 2 +4 2 1 2 4 2 3 3 +4 2 2 2 3 2 3 1 +4 2 2 2 3 2 2 2 +4 2 2 2 3 2 3 3 +4 2 2 2 4 2 3 1 +4 2 2 2 4 2 2 2 +4 2 2 2 4 2 3 3 +5 3 NULL NULL NULL NULL NULL NULL +EXPLAIN EXTENDED +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b +FROM t2 +LEFT JOIN +(t3, t4, t5) +ON t2.b=t4.b +WHERE t3.a>1 OR t3.c IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on(`test`.`t4`.`b` = `test`.`t2`.`b`) where `test`.`t3`.`a` > 1 or `test`.`t3`.`c` is null +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b +FROM t2 +LEFT JOIN +(t3, t4, t5) +ON t2.b=t4.b +WHERE t3.a>1 OR t3.c IS NULL; +a b a b a b a b +3 3 NULL NULL NULL NULL NULL NULL +4 2 2 2 3 2 3 1 +4 2 2 2 3 2 2 2 +4 2 2 2 3 2 3 3 +4 2 2 2 4 2 3 1 +4 2 2 2 4 2 2 2 +4 2 2 2 4 2 3 3 +5 3 NULL NULL NULL NULL NULL NULL +EXPLAIN EXTENDED +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b +FROM t2 +LEFT JOIN +(t3, t4, t5) +ON t2.b=t4.b +WHERE (t3.a>1 OR t3.c IS NULL) AND +(t5.a<3 OR t5.c IS NULL); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b` from `test`.`t2` left join (`test`.`t3` join `test`.`t4` join `test`.`t5`) on(`test`.`t4`.`b` = `test`.`t2`.`b`) where (`test`.`t3`.`a` > 1 or `test`.`t3`.`c` is null) and (`test`.`t5`.`a` < 3 or `test`.`t5`.`c` is null) +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b,t5.a,t5.b +FROM t2 +LEFT JOIN +(t3, t4, t5) +ON t2.b=t4.b +WHERE (t3.a>1 OR t3.c IS NULL) AND +(t5.a<3 OR t5.c IS NULL); +a b a b a b a b +3 3 NULL NULL NULL NULL NULL NULL +4 2 2 2 3 2 2 2 +4 2 2 2 4 2 2 2 +5 3 NULL NULL NULL NULL NULL NULL +SELECT t6.a,t6.b +FROM t6; +a b +3 2 +6 2 +6 1 +SELECT t7.a,t7.b +FROM t7; +a b +1 1 +2 2 +SELECT t6.a,t6.b,t7.a,t7.b +FROM t6,t7; +a b a b +3 2 1 1 +3 2 2 2 +6 2 1 1 +6 2 2 2 +6 1 1 1 +6 1 2 2 +SELECT t8.a,t8.b +FROM t8; +a b +0 2 +1 2 +EXPLAIN EXTENDED +SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM (t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t7`.`b` and `test`.`t6`.`b` < 10) where 1 +SELECT t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM (t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10; +a b a b a b +3 2 1 1 NULL NULL +3 2 2 2 0 2 +3 2 2 2 1 2 +6 2 1 1 NULL NULL +6 2 2 2 0 2 +6 2 2 2 1 2 +6 1 1 1 NULL NULL +6 1 2 2 0 2 +6 1 2 2 1 2 +SELECT t5.a,t5.b +FROM t5; +a b +3 1 +2 2 +3 3 +SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b; +a b a b a b a b +3 1 3 2 1 1 NULL NULL +3 1 6 2 1 1 NULL NULL +2 2 3 2 2 2 0 2 +2 2 3 2 2 2 1 2 +2 2 6 2 2 2 0 2 +2 2 6 2 2 2 1 2 +3 3 NULL NULL NULL NULL NULL NULL +SELECT t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b AND +(t8.a < 1 OR t8.c IS NULL); +a b a b a b a b +3 1 3 2 1 1 NULL NULL +3 1 6 2 1 1 NULL NULL +2 2 3 2 2 2 0 2 +2 2 6 2 2 2 0 2 +3 3 NULL NULL NULL NULL NULL NULL +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b; +a b a b a b +3 3 NULL NULL NULL NULL +4 2 1 2 3 2 +4 2 1 2 4 2 +5 3 NULL NULL NULL NULL +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b; +a b a b a b a b a b a b a b +3 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +3 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL +4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL +5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +3 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +3 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +3 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +3 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +4 2 1 2 3 2 2 2 3 2 2 2 0 2 +4 2 1 2 3 2 2 2 3 2 2 2 1 2 +4 2 1 2 3 2 2 2 6 2 2 2 0 2 +4 2 1 2 3 2 2 2 6 2 2 2 1 2 +4 2 1 2 4 2 2 2 3 2 2 2 0 2 +4 2 1 2 4 2 2 2 3 2 2 2 1 2 +4 2 1 2 4 2 2 2 6 2 2 2 0 2 +4 2 1 2 4 2 2 2 6 2 2 2 1 2 +5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +3 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +WHERE t2.a > 3 AND +(t6.a < 6 OR t6.c IS NULL); +a b a b a b a b a b a b a b +4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +4 2 1 2 3 2 2 2 3 2 2 2 0 2 +4 2 1 2 3 2 2 2 3 2 2 2 1 2 +4 2 1 2 4 2 2 2 3 2 2 2 0 2 +4 2 1 2 4 2 2 2 3 2 2 2 1 2 +5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +SELECT t1.a,t1.b +FROM t1; +a b +1 3 +2 2 +3 2 +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2); +a b a b a b a b a b a b a b a b +1 3 3 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +1 3 3 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +1 3 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +1 3 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +1 3 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +1 3 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +1 3 3 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +1 3 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +1 3 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL +1 3 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +1 3 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +1 3 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL +1 3 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +1 3 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +1 3 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +1 3 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL +3 2 3 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +3 2 3 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +3 2 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +3 2 3 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +3 2 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +3 2 3 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +3 2 3 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +3 2 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL +3 2 4 2 1 2 3 2 2 2 3 2 2 2 0 2 +3 2 4 2 1 2 3 2 2 2 3 2 2 2 1 2 +3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 +3 2 4 2 1 2 3 2 2 2 6 2 2 2 1 2 +3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +3 2 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL +3 2 4 2 1 2 4 2 2 2 3 2 2 2 0 2 +3 2 4 2 1 2 4 2 2 2 3 2 2 2 1 2 +3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 +3 2 4 2 1 2 4 2 2 2 6 2 2 2 1 2 +3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +3 2 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2) +WHERE (t2.a >= 4 OR t2.c IS NULL); +a b a b a b a b a b a b a b a b +1 3 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +1 3 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL +1 3 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +1 3 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +1 3 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL +1 3 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +1 3 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +1 3 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +1 3 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +1 3 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +1 3 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL +3 2 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL +3 2 4 2 1 2 3 2 2 2 3 2 2 2 0 2 +3 2 4 2 1 2 3 2 2 2 3 2 2 2 1 2 +3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 +3 2 4 2 1 2 3 2 2 2 6 2 2 2 1 2 +3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +3 2 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL +3 2 4 2 1 2 4 2 2 2 3 2 2 2 0 2 +3 2 4 2 1 2 4 2 2 2 3 2 2 2 1 2 +3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 +3 2 4 2 1 2 4 2 2 2 6 2 2 2 1 2 +3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +3 2 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +SELECT t0.a,t0.b +FROM t0; +a b +1 1 +1 2 +2 2 +EXPLAIN EXTENDED +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2) +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b`) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2) +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL); +a b a b a b a b a b a b a b a b a b +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL +1 2 3 2 4 2 1 2 3 2 3 1 3 2 1 1 NULL NULL +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL +1 2 3 2 4 2 1 2 3 2 2 2 3 2 2 2 0 2 +1 2 3 2 4 2 1 2 3 2 2 2 3 2 2 2 1 2 +1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 +1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 1 2 +1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL +1 2 3 2 4 2 1 2 4 2 3 1 3 2 1 1 NULL NULL +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL +1 2 3 2 4 2 1 2 4 2 2 2 3 2 2 2 0 2 +1 2 3 2 4 2 1 2 4 2 2 2 3 2 2 2 1 2 +1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 +1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 1 2 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 3 2 1 1 NULL NULL +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL +1 2 3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 0 2 +1 2 3 2 5 3 NULL NULL NULL NULL 2 2 3 2 2 2 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 +1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL +EXPLAIN EXTENDED +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2), +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b`) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null) +SELECT t9.a,t9.b +FROM t9; +a b +1 1 +1 2 +3 3 +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2), +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +a b a b a b a b a b a b a b a b a b a b +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1 +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 +1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1 +1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 2 +SELECT t1.a,t1.b +FROM t1; +a b +1 3 +2 2 +3 2 +SELECT t2.a,t2.b +FROM t2; +a b +3 3 +4 2 +5 3 +SELECT t3.a,t3.b +FROM t3; +a b +1 2 +2 2 +SELECT t2.a,t2.b,t3.a,t3.b +FROM t2 +LEFT JOIN +t3 +ON t2.b=t3.b; +a b a b +3 3 NULL NULL +4 2 1 2 +4 2 2 2 +5 3 NULL NULL +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b +FROM t1, t2 +LEFT JOIN +t3 +ON t2.b=t3.b +WHERE t1.a <= 2; +a b a b a b +1 3 3 3 NULL NULL +2 2 3 3 NULL NULL +1 3 4 2 1 2 +1 3 4 2 2 2 +2 2 4 2 1 2 +2 2 4 2 2 2 +1 3 5 3 NULL NULL +2 2 5 3 NULL NULL +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b +FROM t1, t3 +RIGHT JOIN +t2 +ON t2.b=t3.b +WHERE t1.a <= 2; +a b a b a b +1 3 3 3 NULL NULL +2 2 3 3 NULL NULL +1 3 4 2 1 2 +1 3 4 2 2 2 +2 2 4 2 1 2 +2 2 4 2 2 2 +1 3 5 3 NULL NULL +2 2 5 3 NULL NULL +SELECT t3.a,t3.b,t4.a,t4.b +FROM t3,t4; +a b a b +1 2 3 2 +2 2 3 2 +1 2 4 2 +2 2 4 2 +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b; +a b a b a b +3 3 NULL NULL NULL NULL +4 2 1 2 3 2 +4 2 1 2 4 2 +5 3 NULL NULL NULL NULL +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t1, t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b +WHERE t1.a <= 2; +a b a b a b a b +1 3 3 3 NULL NULL NULL NULL +2 2 3 3 NULL NULL NULL NULL +1 3 4 2 1 2 3 2 +1 3 4 2 1 2 4 2 +2 2 4 2 1 2 3 2 +2 2 4 2 1 2 4 2 +1 3 5 3 NULL NULL NULL NULL +2 2 5 3 NULL NULL NULL NULL +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t1, (t3, t4) +RIGHT JOIN +t2 +ON t3.a=1 AND t2.b=t4.b +WHERE t1.a <= 2; +a b a b a b a b +1 3 3 3 NULL NULL NULL NULL +2 2 3 3 NULL NULL NULL NULL +1 3 4 2 1 2 3 2 +1 3 4 2 1 2 4 2 +2 2 4 2 1 2 3 2 +2 2 4 2 1 2 4 2 +1 3 5 3 NULL NULL NULL NULL +2 2 5 3 NULL NULL NULL NULL +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t1, (t3, t4) +RIGHT JOIN +t2 +ON t3.a=1 AND t2.b=t4.b +WHERE t1.a <= 2; +a b a b a b a b +1 3 3 3 NULL NULL NULL NULL +2 2 3 3 NULL NULL NULL NULL +1 3 4 2 1 2 3 2 +1 3 4 2 1 2 4 2 +2 2 4 2 1 2 3 2 +2 2 4 2 1 2 4 2 +1 3 5 3 NULL NULL NULL NULL +2 2 5 3 NULL NULL NULL NULL +EXPLAIN EXTENDED +SELECT t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM t1, (t3, t4) +RIGHT JOIN +t2 +ON t3.a=1 AND t2.b=t4.b +WHERE t1.a <= 2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t1` join `test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b`) where `test`.`t1`.`a` <= 2 +INSERT INTO t2 VALUES (-1,9,0), (-3,10,0), (-2,8,0), (-4,11,0), (-5,15,0); +CREATE INDEX idx_b ON t2(b); +EXPLAIN EXTENDED +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM (t3,t4) +LEFT JOIN +(t1,t2) +ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ref idx_b idx_b 5 test.t3.b 1 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +Warnings: +Note 1003 select `test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b` from `test`.`t3` join `test`.`t4` left join (`test`.`t1` join `test`.`t2`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t3`.`b` and `test`.`t2`.`b` = `test`.`t3`.`b` and `test`.`t2`.`a` > 0 and `test`.`t3`.`b` is not null) where 1 +SELECT t2.a,t2.b,t3.a,t3.b,t4.a,t4.b +FROM (t3,t4) +LEFT JOIN +(t1,t2) +ON t3.a=1 AND t3.b=t2.b AND t2.b=t4.b AND t2.a>0; +a b a b a b +4 2 1 2 3 2 +4 2 1 2 3 2 +4 2 1 2 3 2 +NULL NULL 2 2 3 2 +4 2 1 2 4 2 +4 2 1 2 4 2 +4 2 1 2 4 2 +NULL NULL 2 2 4 2 +EXPLAIN EXTENDED +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b AND t2.a>0, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2), +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t4`.`b` = `test`.`t3`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t9`.`b` = `test`.`t8`.`b` or `test`.`t8`.`c` is null) +INSERT INTO t4 VALUES (-3,12,0), (-4,13,0), (-1,11,0), (-3,11,0), (-5,15,0); +INSERT INTO t5 VALUES (-3,11,0), (-2,12,0), (-3,13,0), (-4,12,0); +CREATE INDEX idx_b ON t4(b); +CREATE INDEX idx_b ON t5(b); +EXPLAIN EXTENDED +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0 +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2), +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t8 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +INSERT INTO t8 VALUES (-3,12,0), (-1,14,0), (-5,15,0), (-1,11,0), (-4,13,0); +CREATE INDEX idx_b ON t8(b); +EXPLAIN EXTENDED +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b AND t2.a>0 AND t4.a>0, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 AND t8.a>=0 +) +ON t6.b >= 2 AND t5.b=t7.b AND t5.a>0 +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2), +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`a` > 0 and `test`.`t4`.`a` > 0 and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t8`.`a` >= 0 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2 and `test`.`t5`.`a` > 0)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +INSERT INTO t1 VALUES (-1,133,0), (-2,12,0), (-3,11,0), (-5,15,0); +CREATE INDEX idx_b ON t1(b); +CREATE INDEX idx_a ON t0(a); +EXPLAIN EXTENDED +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2) AND t1.a>0, +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t0 ref idx_a idx_a 5 const 2 100.00 Using where +1 SIMPLE t1 ref idx_b idx_b 5 test.t0.b 1 100.00 +1 SIMPLE t9 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t5 ALL idx_b NULL NULL NULL 7 100.00 Using where +1 SIMPLE t7 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t6 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t8 ref idx_b idx_b 5 test.t5.b 1 100.00 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 8 100.00 Using where +1 SIMPLE t4 ref idx_b idx_b 5 test.t2.b 1 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t0`.`a` AS `a`,`test`.`t0`.`b` AS `b`,`test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t5`.`a` AS `a`,`test`.`t5`.`b` AS `b`,`test`.`t6`.`a` AS `a`,`test`.`t6`.`b` AS `b`,`test`.`t7`.`a` AS `a`,`test`.`t7`.`b` AS `b`,`test`.`t8`.`a` AS `a`,`test`.`t8`.`b` AS `b`,`test`.`t9`.`a` AS `a`,`test`.`t9`.`b` AS `b` from `test`.`t0` join `test`.`t1` left join (`test`.`t2` left join (`test`.`t3` join `test`.`t4`) on(`test`.`t3`.`a` = 1 and `test`.`t4`.`b` = `test`.`t2`.`b` and `test`.`t2`.`b` is not null) join `test`.`t5` left join (`test`.`t6` join `test`.`t7` left join `test`.`t8` on(`test`.`t8`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` < 10 and `test`.`t5`.`b` is not null)) on(`test`.`t7`.`b` = `test`.`t5`.`b` and `test`.`t6`.`b` >= 2)) on((`test`.`t3`.`b` = 2 or `test`.`t3`.`c` is null) and (`test`.`t6`.`b` = 2 or `test`.`t6`.`c` is null) and (`test`.`t5`.`b` = `test`.`t0`.`b` or `test`.`t3`.`c` is null or `test`.`t6`.`c` is null or `test`.`t8`.`c` is null) and `test`.`t1`.`a` <> 2 and `test`.`t1`.`a` > 0) join `test`.`t9` where `test`.`t0`.`a` = 1 and `test`.`t1`.`b` = `test`.`t0`.`b` and `test`.`t9`.`a` = 1 and (`test`.`t2`.`a` >= 4 or `test`.`t2`.`c` is null) and (`test`.`t3`.`a` < 5 or `test`.`t3`.`c` is null) and (`test`.`t3`.`b` = `test`.`t4`.`b` or `test`.`t3`.`c` is null or `test`.`t4`.`c` is null) and (`test`.`t5`.`a` >= 2 or `test`.`t5`.`c` is null) and (`test`.`t6`.`a` >= 4 or `test`.`t6`.`c` is null) and (`test`.`t7`.`a` <= 2 or `test`.`t7`.`c` is null) and (`test`.`t8`.`a` < 1 or `test`.`t8`.`c` is null) and (`test`.`t8`.`b` = `test`.`t9`.`b` or `test`.`t8`.`c` is null) +SELECT t0.a,t0.b,t1.a,t1.b,t2.a,t2.b,t3.a,t3.b,t4.a,t4.b, +t5.a,t5.b,t6.a,t6.b,t7.a,t7.b,t8.a,t8.b,t9.a,t9.b +FROM t0,t1 +LEFT JOIN +( +t2 +LEFT JOIN +(t3, t4) +ON t3.a=1 AND t2.b=t4.b, +t5 +LEFT JOIN +( +(t6, t7) +LEFT JOIN +t8 +ON t7.b=t8.b AND t6.b < 10 +) +ON t6.b >= 2 AND t5.b=t7.b +) +ON (t3.b=2 OR t3.c IS NULL) AND (t6.b=2 OR t6.c IS NULL) AND +(t1.b=t5.b OR t3.c IS NULL OR t6.c IS NULL or t8.c IS NULL) AND +(t1.a != 2) AND t1.a>0, +t9 +WHERE t0.a=1 AND +t0.b=t1.b AND +(t2.a >= 4 OR t2.c IS NULL) AND +(t3.a < 5 OR t3.c IS NULL) AND +(t3.b=t4.b OR t3.c IS NULL OR t4.c IS NULL) AND +(t5.a >=2 OR t5.c IS NULL) AND +(t6.a >=4 OR t6.c IS NULL) AND +(t7.a <= 2 OR t7.c IS NULL) AND +(t8.a < 1 OR t8.c IS NULL) AND +(t8.b=t9.b OR t8.c IS NULL) AND +(t9.a=1); +a b a b a b a b a b a b a b a b a b a b +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 1 +1 2 2 2 NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 4 2 1 2 3 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 3 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 +1 2 3 2 4 2 1 2 3 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 4 2 1 2 4 2 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 1 +1 2 3 2 4 2 1 2 4 2 3 3 NULL NULL NULL NULL NULL NULL 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 2 2 6 2 2 2 0 2 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 1 +1 2 3 2 5 3 NULL NULL NULL NULL 3 1 6 2 1 1 NULL NULL 1 2 +1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 1 +1 2 3 2 5 3 NULL NULL NULL NULL 3 3 NULL NULL NULL NULL NULL NULL 1 2 +SELECT t2.a,t2.b +FROM t2; +a b +3 3 +4 2 +5 3 +-1 9 +-3 10 +-2 8 +-4 11 +-5 15 +SELECT t3.a,t3.b +FROM t3; +a b +1 2 +2 2 +SELECT t2.a,t2.b,t3.a,t3.b +FROM t2 LEFT JOIN t3 ON t2.b=t3.b +WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL); +a b a b +4 2 1 2 +4 2 2 2 +5 3 NULL NULL +SELECT t2.a,t2.b,t3.a,t3.b +FROM t2 LEFT JOIN t3 ON t2.b=t3.b +WHERE t2.a = 4 OR (t2.a > 4 AND t3.a IS NULL); +a b a b +4 2 1 2 +4 2 2 2 +5 3 NULL NULL +ALTER TABLE t3 +CHANGE COLUMN a a1 int, +CHANGE COLUMN c c1 int; +SELECT t2.a,t2.b,t3.a1,t3.b +FROM t2 LEFT JOIN t3 ON t2.b=t3.b +WHERE t2.a = 4 OR (t2.a > 4 AND t3.a1 IS NULL); +a b a1 b +4 2 1 2 +4 2 2 2 +5 3 NULL NULL +SELECT t2.a,t2.b,t3.a1,t3.b +FROM t2 NATURAL LEFT JOIN t3 +WHERE t2.a = 4 OR (t2.a > 4 AND t3.a1 IS NULL); +a b a1 b +4 2 1 2 +4 2 2 2 +5 3 NULL NULL +DROP TABLE t0,t1,t2,t3,t4,t5,t6,t7,t8,t9; +CREATE TABLE t1 (a int); +CREATE TABLE t2 (a int); +CREATE TABLE t3 (a int); +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (2); +INSERT INTO t3 VALUES (2); +INSERT INTO t1 VALUES (2); +SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t2.a=t3.a) ON t1.a=t3.a; +a a a +1 NULL NULL +2 2 2 +SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a; +a a a +1 NULL NULL +2 2 2 +DELETE FROM t1 WHERE a=2; +SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a; +a a a +1 NULL NULL +DELETE FROM t2; +SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON t2.a=t3.a ON t1.a=t3.a; +a a a +1 NULL NULL +DROP TABLE t1,t2,t3; +CREATE TABLE t1(a int, key (a)); +CREATE TABLE t2(b int, key (b)); +CREATE TABLE t3(c int, key (c)); +INSERT INTO t1 VALUES (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(10), (11), (12), (13), (14), (15), (16), (17), (18), (19); +INSERT INTO t2 VALUES (NULL), (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(10), (11), (12), (13), (14), (15), (16), (17), (18), (19); +INSERT INTO t3 VALUES (0), (1), (2), (3), (4), (5); +EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON c < 3 and b = c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 21 Using index +1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index +1 SIMPLE t3 ref c c 5 test.t2.b 1 Using index +EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 index NULL a 5 NULL 21 Using index +1 SIMPLE t2 range b b 5 NULL 3 Using where; Using index +1 SIMPLE t3 ref c c 5 test.t2.b 1 Using index +SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; +a b c +NULL 0 0 +NULL 1 1 +NULL 2 2 +0 0 0 +0 1 1 +0 2 2 +1 0 0 +1 1 1 +1 2 2 +2 0 0 +2 1 1 +2 2 2 +3 0 0 +3 1 1 +3 2 2 +4 0 0 +4 1 1 +4 2 2 +5 0 0 +5 1 1 +5 2 2 +6 0 0 +6 1 1 +6 2 2 +7 0 0 +7 1 1 +7 2 2 +8 0 0 +8 1 1 +8 2 2 +9 0 0 +9 1 1 +9 2 2 +10 0 0 +10 1 1 +10 2 2 +11 0 0 +11 1 1 +11 2 2 +12 0 0 +12 1 1 +12 2 2 +13 0 0 +13 1 1 +13 2 2 +14 0 0 +14 1 1 +14 2 2 +15 0 0 +15 1 1 +15 2 2 +16 0 0 +16 1 1 +16 2 2 +17 0 0 +17 1 1 +17 2 2 +18 0 0 +18 1 1 +18 2 2 +19 0 0 +19 1 1 +19 2 2 +DELETE FROM t3; +EXPLAIN SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 const c NULL NULL NULL 0 Impossible ON condition +1 SIMPLE t2 const b NULL NULL NULL 0 Impossible ON condition +1 SIMPLE t1 index NULL a 5 NULL 21 Using index +SELECT a, b, c FROM t1 LEFT JOIN (t2, t3) ON b < 3 and b = c; +a b c +NULL NULL NULL +0 NULL NULL +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +5 NULL NULL +6 NULL NULL +7 NULL NULL +8 NULL NULL +9 NULL NULL +10 NULL NULL +11 NULL NULL +12 NULL NULL +13 NULL NULL +14 NULL NULL +15 NULL NULL +16 NULL NULL +17 NULL NULL +18 NULL NULL +19 NULL NULL +DROP TABLE t1,t2,t3; +CREATE TABLE t1 (c11 int); +CREATE TABLE t2 (c21 int); +CREATE TABLE t3 (c31 int); +INSERT INTO t1 VALUES (4), (5); +SELECT * FROM t1 LEFT JOIN t2 ON c11=c21; +c11 c21 +4 NULL +5 NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON c11=c21; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 system NULL NULL NULL NULL 0 Const row not found +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21; +c11 c21 c31 +4 NULL NULL +5 NULL NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON c21=c31) ON c11=c21; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ALL NULL NULL NULL NULL 0 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 0 Using where +DROP TABLE t1,t2,t3; +CREATE TABLE t1 (goods int(12) NOT NULL, price varchar(128) NOT NULL); +INSERT INTO t1 VALUES (23, 2340), (26, 9900); +CREATE TABLE t2 (goods int(12), name varchar(50), shop char(2)); +INSERT INTO t2 VALUES (23, 'as300', 'fr'), (26, 'as600', 'fr'); +create table t3 (groupid int(12) NOT NULL, goodsid int(12) NOT NULL); +INSERT INTO t3 VALUES (3,23), (6,26); +CREATE TABLE t4 (groupid int(12)); +INSERT INTO t4 VALUES (1), (2), (3), (4), (5), (6); +SELECT * FROM +(SELECT DISTINCT gl.groupid, gp.price +FROM t4 gl +LEFT JOIN +(t3 g INNER JOIN t2 p ON g.goodsid = p.goods +INNER JOIN t1 gp ON p.goods = gp.goods) +ON gl.groupid = g.groupid and p.shop = 'fr') t; +groupid price +1 NULL +2 NULL +3 2340 +4 NULL +5 NULL +6 9900 +CREATE VIEW v1 AS +SELECT g.groupid groupid, p.goods goods, +p.name name, p.shop shop, +gp.price price +FROM t3 g INNER JOIN t2 p ON g.goodsid = p.goods +INNER JOIN t1 gp on p.goods = gp.goods; +CREATE VIEW v2 AS +SELECT DISTINCT g.groupid, fr.price +FROM t4 g +LEFT JOIN +v1 fr on g.groupid = fr.groupid and fr.shop = 'fr'; +SELECT * FROM v2; +groupid price +1 NULL +2 NULL +3 2340 +4 NULL +5 NULL +6 9900 +SELECT * FROM +(SELECT DISTINCT g.groupid, fr.price +FROM t4 g +LEFT JOIN +v1 fr on g.groupid = fr.groupid and fr.shop = 'fr') t; +groupid price +1 NULL +2 NULL +3 2340 +4 NULL +5 NULL +6 9900 +DROP VIEW v1,v2; +DROP TABLE t1,t2,t3,t4; +CREATE TABLE t1(a int); +CREATE TABLE t2(b int); +CREATE TABLE t3(c int, d int); +CREATE TABLE t4(d int); +CREATE TABLE t5(e int, f int); +CREATE TABLE t6(f int); +CREATE VIEW v1 AS +SELECT e FROM t5 JOIN t6 ON t5.e=t6.f; +CREATE VIEW v2 AS +SELECT e FROM t5 NATURAL JOIN t6; +SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d); +a +SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c JOIN t4 USING(d); +ERROR 42S22: Unknown column 't1.x' in 'SELECT' +SELECT t1.a FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4; +a +SELECT t1.x FROM t1 JOIN t2 ON a=b JOIN t3 ON a=c NATURAL JOIN t4; +ERROR 42S22: Unknown column 't1.x' in 'SELECT' +SELECT v1.e FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +e +SELECT v1.x FROM v1 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +ERROR 42S22: Unknown column 'v1.x' in 'SELECT' +SELECT v2.e FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +e +SELECT v2.x FROM v2 JOIN t2 ON e=b JOIN t3 ON e=c JOIN t4 USING(d); +ERROR 42S22: Unknown column 'v2.x' in 'SELECT' +DROP VIEW v1, v2; +DROP TABLE t1, t2, t3, t4, t5, t6; +create table t1 (id1 int(11) not null); +insert into t1 values (1),(2); +create table t2 (id2 int(11) not null); +insert into t2 values (1),(2),(3),(4); +create table t3 (id3 char(16) not null); +insert into t3 values ('100'); +create table t4 (id2 int(11) not null, id3 char(16)); +create table t5 (id1 int(11) not null, key (id1)); +insert into t5 values (1),(2),(1); +create view v1 as +select t4.id3 from t4 join t2 on t4.id2 = t2.id2; +select t1.id1 from t1 inner join (t3 left join v1 on t3.id3 = v1.id3); +id1 +1 +2 +drop view v1; +drop table t1, t2, t3, t4, t5; +create table t0 (a int); +insert into t0 values (0),(1),(2),(3); +create table t1(a int); +insert into t1 select A.a + 10*(B.a) from t0 A, t0 B; +create table t2 (a int, b int); +insert into t2 values (1,1), (2,2), (3,3); +create table t3(a int, b int, filler char(200), key(a)); +insert into t3 select a,a,'filler' from t1; +insert into t3 select a,a,'filler' from t1; +create table t4 like t3; +insert into t4 select * from t3; +insert into t4 select * from t3; +create table t5 like t4; +insert into t5 select * from t4; +insert into t5 select * from t4; +create table t6 like t5; +insert into t6 select * from t5; +insert into t6 select * from t5; +create table t7 like t6; +insert into t7 select * from t6; +insert into t7 select * from t6; +explain select * from t4 join +t2 left join (t3 join t5 on t5.a=t3.b) on t3.a=t2.b where t4.a<=>t3.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL X +1 SIMPLE t3 ref a a 5 test.t2.b X Using where +1 SIMPLE t5 ref a a 5 test.t3.b X +1 SIMPLE t4 ref a a 5 test.t3.b X Using index condition +explain select * from (t4 join t6 on t6.a=t4.b) right join t3 on t4.a=t3.b +join t2 left join (t5 join t7 on t7.a=t5.b) on t5.a=t2.b where t3.a<=>t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL X +1 SIMPLE t3 ref a a 5 test.t2.b X Using index condition +1 SIMPLE t4 ref a a 5 test.t3.b X Using where +1 SIMPLE t6 ref a a 5 test.t4.b X +1 SIMPLE t5 ref a a 5 test.t2.b X Using where +1 SIMPLE t7 ref a a 5 test.t5.b X +explain select * from t2 left join +(t3 left join (t4 join t6 on t6.a=t4.b) on t4.a=t3.b +join t5 on t5.a=t3.b) on t3.a=t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL X +1 SIMPLE t3 ref a a 5 test.t2.b X Using where +1 SIMPLE t4 ref a a 5 test.t3.b X Using where +1 SIMPLE t6 ref a a 5 test.t4.b X +1 SIMPLE t5 ref a a 5 test.t3.b X +drop table t0, t1, t2, t3, t4, t5, t6, t7; +create table t1 (a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, filler char(100), key(a)); +insert into t2 select A.a + 10*B.a, '' from t1 A, t1 B; +create table t3 like t2; +insert into t3 select * from t2; +explain select * from t1 left join +(t2 left join t3 on (t2.a = t3.a)) +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 10 +1 SIMPLE t2 ref a a 5 test.t1.a 1 Using where +1 SIMPLE t3 ref a a 5 test.t1.a 1 Using where +drop table t1, t2, t3; +CREATE TABLE t1 (id int NOT NULL PRIMARY KEY, type varchar(10)); +CREATE TABLE t2 (pid int NOT NULL PRIMARY KEY, type varchar(10)); +CREATE TABLE t3 (cid int NOT NULL PRIMARY KEY, +id int NOT NULL, +pid int NOT NULL); +INSERT INTO t1 VALUES (1, 'A'), (3, 'C'); +INSERT INTO t2 VALUES (1, 'A'), (3, 'C'); +INSERT INTO t3 VALUES (1, 1, 1), (3, 3, 3); +SELECT * FROM t1 p LEFT JOIN (t3 JOIN t1) +ON (t1.id=t3.id AND t1.type='B' AND p.id=t3.id) +LEFT JOIN t2 ON (t3.pid=t2.pid) +WHERE p.id=1; +id type cid id pid id type pid type +1 A NULL NULL NULL NULL NULL NULL NULL +CREATE VIEW v1 AS +SELECT t3.* FROM t3 JOIN t1 ON t1.id=t3.id AND t1.type='B'; +SELECT * FROM t1 p LEFT JOIN v1 ON p.id=v1.id +LEFT JOIN t2 ON v1.pid=t2.pid +WHERE p.id=1; +id type cid id pid pid type +1 A NULL NULL NULL NULL NULL +DROP VIEW v1; +DROP TABLE t1,t2,t3; +CREATE TABLE t1 (id1 int PRIMARY KEY, id2 int); +CREATE TABLE t2 (id1 int PRIMARY KEY, id2 int); +CREATE TABLE t3 (id1 int PRIMARY KEY, id2 int); +CREATE TABLE t4 (id1 int PRIMARY KEY, id2 int); +CREATE TABLE t5 (id1 int PRIMARY KEY, id2 int); +SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa +FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1 +LEFT OUTER JOIN +(t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1) +ON t3.id2 IS NOT NULL +WHERE t1.id1=2; +id ngroupbynsa +PREPARE stmt FROM +"SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa + FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1 + LEFT OUTER JOIN + (t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1) + ON t3.id2 IS NOT NULL + WHERE t1.id1=2"; +EXECUTE stmt; +id ngroupbynsa +EXECUTE stmt; +id ngroupbynsa +EXECUTE stmt; +id ngroupbynsa +EXECUTE stmt; +id ngroupbynsa +INSERT INTO t1 VALUES (1,1), (2,1), (3,2); +INSERT INTO t2 VALUES (2,1), (3,2), (4,3); +INSERT INTO t3 VALUES (1,1), (3,2), (2,NULL); +INSERT INTO t4 VALUES (1,1), (2,1), (3,3); +INSERT INTO t5 VALUES (1,1), (2,2), (3,3), (4,3); +EXECUTE stmt; +id ngroupbynsa +2 1 +2 1 +EXECUTE stmt; +id ngroupbynsa +2 1 +2 1 +EXECUTE stmt; +id ngroupbynsa +2 1 +2 1 +EXECUTE stmt; +id ngroupbynsa +2 1 +2 1 +SELECT t1.id1 AS id, t5.id1 AS ngroupbynsa +FROM t1 INNER JOIN t2 ON t2.id2 = t1.id1 +LEFT OUTER JOIN +(t3 INNER JOIN t4 ON t4.id1 = t3.id2 INNER JOIN t5 ON t4.id2 = t5.id1) +ON t3.id2 IS NOT NULL +WHERE t1.id1=2; +id ngroupbynsa +2 1 +2 1 +DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 ( +id int NOT NULL PRIMARY KEY, +ct int DEFAULT NULL, +pc int DEFAULT NULL, +INDEX idx_ct (ct), +INDEX idx_pc (pc) +); +INSERT INTO t1 VALUES +(1,NULL,NULL),(2,NULL,NULL),(3,NULL,NULL),(4,NULL,NULL),(5,NULL,NULL); +CREATE TABLE t2 ( +id int NOT NULL PRIMARY KEY, +sr int NOT NULL, +nm varchar(255) NOT NULL, +INDEX idx_sr (sr) +); +INSERT INTO t2 VALUES +(2441905,4308,'LesAbymes'),(2441906,4308,'Anse-Bertrand'); +CREATE TABLE t3 ( +id int NOT NULL PRIMARY KEY, +ct int NOT NULL, +ln int NOT NULL, +INDEX idx_ct (ct), +INDEX idx_ln (ln) +); +CREATE TABLE t4 ( +id int NOT NULL PRIMARY KEY, +nm varchar(255) NOT NULL +); +INSERT INTO t4 VALUES (4308,'Guadeloupe'),(4309,'Martinique'); +SELECT t1.* +FROM t1 LEFT JOIN +(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id +WHERE t1.id='5'; +id ct pc +5 NULL NULL +SELECT t1.*, t4.nm +FROM t1 LEFT JOIN +(t2 LEFT JOIN t3 ON t3.ct=t2.id AND t3.ln='5') ON t1.ct=t2.id +LEFT JOIN t4 ON t2.sr=t4.id +WHERE t1.id='5'; +id ct pc nm +5 NULL NULL NULL +DROP TABLE t1,t2,t3,t4; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT); +CREATE TABLE t3 (a INT, c INT); +CREATE TABLE t4 (a INT, c INT); +CREATE TABLE t5 (a INT, c INT); +SELECT b FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +b +SELECT c FROM t1 JOIN (t2 LEFT JOIN t3 USING (a) LEFT JOIN t4 USING (a) +LEFT JOIN t5 USING (a)) USING (a); +ERROR 23000: Column 'c' in SELECT is ambiguous +SELECT b FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a) +JOIN t5 USING (a)) USING (a); +b +SELECT c FROM t1 JOIN (t2 JOIN t3 USING (a) JOIN t4 USING (a) +JOIN t5 USING (a)) USING (a); +ERROR 23000: Column 'c' in SELECT is ambiguous +DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 (a INT, b INT); +CREATE TABLE t2 (a INT, b INT); +CREATE TABLE t3 (a INT, b INT); +INSERT INTO t1 VALUES (1,1); +INSERT INTO t2 VALUES (1,1); +INSERT INTO t3 VALUES (1,1); +SELECT * FROM t1 JOIN (t2 JOIN t3 USING (b)) USING (a); +ERROR 23000: Column 'a' in FROM is ambiguous +DROP TABLE t1,t2,t3; +CREATE TABLE t1 ( +carrier char(2) default NULL, +id int NOT NULL auto_increment PRIMARY KEY +); +INSERT INTO t1 VALUES +('CO',235371754),('CO',235376554),('CO',235376884),('CO',235377874), +('CO',231060394),('CO',231059224),('CO',231059314),('CO',231060484), +('CO',231060274),('CO',231060124),('CO',231060244),('CO',231058594), +('CO',231058924),('CO',231058504),('CO',231059344),('CO',231060424), +('CO',231059554),('CO',231060304),('CO',231059644),('CO',231059464), +('CO',231059764),('CO',231058294),('CO',231058624),('CO',231058864), +('CO',231059374),('CO',231059584),('CO',231059734),('CO',231059014), +('CO',231059854),('CO',231059494),('CO',231059794),('CO',231058534), +('CO',231058324),('CO',231058684),('CO',231059524),('CO',231059974); +CREATE TABLE t2 ( +scan_date date default NULL, +package_id int default NULL, +INDEX scan_date(scan_date), +INDEX package_id(package_id) +); +INSERT INTO t2 VALUES +('2008-12-29',231062944),('2008-12-29',231065764),('2008-12-29',231066124), +('2008-12-29',231060094),('2008-12-29',231061054),('2008-12-29',231065644), +('2008-12-29',231064384),('2008-12-29',231064444),('2008-12-29',231073774), +('2008-12-29',231058594),('2008-12-29',231059374),('2008-12-29',231066004), +('2008-12-29',231068494),('2008-12-29',231070174),('2008-12-29',231071884), +('2008-12-29',231063274),('2008-12-29',231063754),('2008-12-29',231064144), +('2008-12-29',231069424),('2008-12-29',231073714),('2008-12-29',231058414), +('2008-12-29',231060994),('2008-12-29',231069154),('2008-12-29',231068614), +('2008-12-29',231071464),('2008-12-29',231074014),('2008-12-29',231059614), +('2008-12-29',231059074),('2008-12-29',231059464),('2008-12-29',231069094), +('2008-12-29',231067294),('2008-12-29',231070144),('2008-12-29',231073804), +('2008-12-29',231072634),('2008-12-29',231058294),('2008-12-29',231065344), +('2008-12-29',231066094),('2008-12-29',231069034),('2008-12-29',231058594), +('2008-12-29',231059854),('2008-12-29',231059884),('2008-12-29',231059914), +('2008-12-29',231063664),('2008-12-29',231063814),('2008-12-29',231063904); +CREATE TABLE t3 ( +package_id int default NULL, +INDEX package_id(package_id) +); +INSERT INTO t3 VALUES +(231058294),(231058324),(231058354),(231058384),(231058414),(231058444), +(231058474),(231058504),(231058534),(231058564),(231058594),(231058624), +(231058684),(231058744),(231058804),(231058864),(231058924),(231058954), +(231059014),(231059074),(231059104),(231059134),(231059164),(231059194), +(231059224),(231059254),(231059284),(231059314),(231059344),(231059374), +(231059404),(231059434),(231059464),(231059494),(231059524),(231059554), +(231059584),(231059614),(231059644),(231059674),(231059704),(231059734), +(231059764),(231059794),(231059824),(231059854),(231059884),(231059914), +(231059944),(231059974),(231060004),(231060034),(231060064),(231060094), +(231060124),(231060154),(231060184),(231060214),(231060244),(231060274), +(231060304),(231060334),(231060364),(231060394),(231060424),(231060454), +(231060484),(231060514),(231060544),(231060574),(231060604),(231060634), +(231060664),(231060694),(231060724),(231060754),(231060784),(231060814), +(231060844),(231060874),(231060904),(231060934),(231060964),(231060994), +(231061024),(231061054),(231061084),(231061144),(231061174),(231061204), +(231061234),(231061294),(231061354),(231061384),(231061414),(231061474), +(231061564),(231061594),(231061624),(231061684),(231061714),(231061774), +(231061804),(231061894),(231061984),(231062074),(231062134),(231062224), +(231062254),(231062314),(231062374),(231062434),(231062494),(231062554), +(231062584),(231062614),(231062644),(231062704),(231062734),(231062794), +(231062854),(231062884),(231062944),(231063004),(231063034),(231063064), +(231063124),(231063154),(231063184),(231063214),(231063274),(231063334), +(231063394),(231063424),(231063454),(231063514),(231063574),(231063664); +CREATE TABLE t4 ( +carrier char(2) NOT NULL default '' PRIMARY KEY, +id int(11) default NULL, +INDEX id(id) +); +INSERT INTO t4 VALUES +('99',6),('SK',456),('UA',486),('AI',1081),('OS',1111),('VS',1510); +CREATE TABLE t5 ( +carrier_id int default NULL, +INDEX carrier_id(carrier_id) +); +INSERT INTO t5 VALUES +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6), +(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(6),(456),(456),(456), +(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456),(456), +(456),(486),(1081),(1111),(1111),(1111),(1111),(1510); +SELECT COUNT(*) +FROM((t2 JOIN t1 ON t2.package_id = t1.id) +JOIN t3 ON t3.package_id = t1.id); +COUNT(*) +6 +EXPLAIN +SELECT COUNT(*) +FROM ((t2 JOIN t1 ON t2.package_id = t1.id) +JOIN t3 ON t3.package_id = t1.id) +LEFT JOIN +(t5 JOIN t4 ON t5.carrier_id = t4.id) +ON t4.carrier = t1.carrier; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index package_id package_id 5 NULL 45 Using where; Using index +1 SIMPLE t3 ref package_id package_id 5 test.t2.package_id 1 Using index +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.package_id 1 +1 SIMPLE t4 eq_ref PRIMARY,id PRIMARY 8 test.t1.carrier 1 Using where +1 SIMPLE t5 ref carrier_id carrier_id 5 test.t4.id 22 Using index +SELECT COUNT(*) +FROM ((t2 JOIN t1 ON t2.package_id = t1.id) +JOIN t3 ON t3.package_id = t1.id) +LEFT JOIN +(t5 JOIN t4 ON t5.carrier_id = t4.id) +ON t4.carrier = t1.carrier; +COUNT(*) +6 +DROP TABLE t1,t2,t3,t4,t5; +CREATE TABLE t1 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int DEFAULT NULL, +KEY idx(a) +); +CREATE TABLE t2 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int DEFAULT NULL, +KEY idx(a) +); +CREATE TABLE t3 ( +pk int NOT NULL AUTO_INCREMENT PRIMARY KEY, +a int DEFAULT NULL, +KEY idx(a) +); +INSERT INTO t1 VALUES +(1,2), (2,7), (3,5), (4,7), (5,5), (6,NULL), (7,NULL), (8,9); +INSERT INTO t2 VALUES +(1,NULL), (4,2), (5,2), (3,4), (2,8); +INSERT INTO t3 VALUES +(1,9), (2,2), (3,5), (4,2), (5,7), (6,0), (7,5); +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a +FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a; +pk a pk a pk a +1 2 4 2 2 2 +1 2 4 2 4 2 +1 2 5 2 2 2 +1 2 5 2 4 2 +2 7 NULL NULL NULL NULL +3 5 NULL NULL NULL NULL +4 7 NULL NULL NULL NULL +5 5 NULL NULL NULL NULL +6 NULL NULL NULL NULL NULL +7 NULL NULL NULL NULL NULL +8 9 NULL NULL NULL NULL +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a +FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a +WHERE t2.pk IS NULL; +pk a pk a pk a +2 7 NULL NULL NULL NULL +3 5 NULL NULL NULL NULL +4 7 NULL NULL NULL NULL +5 5 NULL NULL NULL NULL +6 NULL NULL NULL NULL NULL +7 NULL NULL NULL NULL NULL +8 9 NULL NULL NULL NULL +SELECT t1.pk, t1.a, t2.pk, t2.a,t3.pk, t3.a +FROM t1 LEFT JOIN (t2 LEFT JOIN t3 ON t3.a=t2.a) ON t2.a=t1.a +WHERE t3.pk IS NULL; +pk a pk a pk a +2 7 NULL NULL NULL NULL +3 5 NULL NULL NULL NULL +4 7 NULL NULL NULL NULL +5 5 NULL NULL NULL NULL +6 NULL NULL NULL NULL NULL +7 NULL NULL NULL NULL NULL +8 9 NULL NULL NULL NULL +DROP TABLE t1, t2, t3; +CREATE TABLE t1 (a int NOT NULL ); +INSERT INTO t1 VALUES (9), (9); +CREATE TABLE t2 (a int NOT NULL ); +INSERT INTO t2 VALUES (9); +CREATE TABLE t3 (a int NOT NULL, b int); +INSERT INTO t3 VALUES (19,9); +CREATE TABLE t4 (b int) ; +SELECT * FROM t1 LEFT JOIN +((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b) +ON t1.a=t2.a; +a a a b b +9 9 19 9 NULL +9 9 19 9 NULL +SELECT * FROM t1 LEFT JOIN +((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b) +ON t1.a=t2.a +WHERE t3.a IS NULL; +a a a b b +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN +((t2 LEFT JOIN t3 ON t2.a=t3.b) LEFT JOIN t4 ON t3.a=t4.b) +ON t1.a=t2.a +WHERE t3.a IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 1 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 1 100.00 Using where; Not exists +1 SIMPLE t4 ALL NULL NULL NULL NULL 0 0.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t4`.`b` AS `b` from `test`.`t1` left join (`test`.`t2` left join `test`.`t3` on(`test`.`t3`.`b` = `test`.`t1`.`a`) left join `test`.`t4` on(`test`.`t4`.`b` = `test`.`t3`.`a`)) on(`test`.`t2`.`a` = `test`.`t1`.`a`) where `test`.`t3`.`a` is null +DROP TABLE t1,t2,t3,t4; +SET optimizer_switch=@save_optimizer_switch; +End of 5.0 tests +# +# MDEV-621: LP:693329 - Assertion `!is_interleave_error' failed on low optimizer_search_depth +# +set @tmp_mdev621= @@optimizer_search_depth; +SET SESSION optimizer_search_depth = 4; +CREATE TABLE t1 (f1 int,f2 int,f3 int,f4 int) ; +INSERT IGNORE INTO t1 VALUES (0,0,2,0),(NULL,0,2,0); +CREATE TABLE t2 (f1 int) ; +CREATE TABLE t3 (f3 int,PRIMARY KEY (f3)) ; +CREATE TABLE t4 (f5 int) ; +CREATE TABLE t5 (f2 int) ; +SELECT alias2.f4 FROM t1 AS alias1 +LEFT JOIN t1 AS alias2 +LEFT JOIN t2 AS alias3 +LEFT JOIN t3 AS alias4 ON alias3.f1 = alias4.f3 +ON alias2.f1 +LEFT JOIN t4 AS alias5 +JOIN t5 ON alias5.f5 +ON alias2.f3 ON alias1.f2; +f4 +NULL +NULL +DROP TABLE t1,t2,t3,t4,t5; +# +# MDEV-7992: Nested left joins + 'not exists' optimization +# +CREATE TABLE t1( +K1 INT PRIMARY KEY, +Name VARCHAR(15) +); +INSERT INTO t1 VALUES +(1,'T1Row1'), (2,'T1Row2'); +CREATE TABLE t2( +K2 INT PRIMARY KEY, +K1r INT, +rowTimestamp DATETIME, +Event VARCHAR(15) +); +INSERT INTO t2 VALUES +(1, 1, '2015-04-13 10:42:11' ,'T1Row1Event1'), +(2, 1, '2015-04-13 10:42:12' ,'T1Row1Event2'), +(3, 1, '2015-04-13 10:42:12' ,'T1Row1Event3'); +SELECT t1a.*, t2a.*, +t2i.K2 AS K2B, t2i.K1r AS K1rB, +t2i.rowTimestamp AS rowTimestampB, t2i.Event AS EventB +FROM +t1 t1a JOIN t2 t2a ON t2a.K1r = t1a.K1 +LEFT JOIN +( t1 t1i LEFT JOIN t2 t2i ON t2i.K1r = t1i.K1) +ON (t1i.K1 = 1) AND +(((t2i.K1r = t1a.K1 AND t2i.rowTimestamp > t2a.rowTimestamp ) OR +(t2i.rowTimestamp = t2a.rowTimestamp AND t2i.K2 > t2a.K2)) +OR (t2i.K2 IS NULL)) +WHERE +t2a.K1r = 1 AND t2i.K2 IS NULL; +K1 Name K2 K1r rowTimestamp Event K2B K1rB rowTimestampB EventB +1 T1Row1 3 1 2015-04-13 10:42:12 T1Row1Event3 NULL NULL NULL NULL +EXPLAIN EXTENDED SELECT t1a.*, t2a.*, +t2i.K2 AS K2B, t2i.K1r AS K1rB, +t2i.rowTimestamp AS rowTimestampB, t2i.Event AS EventB +FROM +t1 t1a JOIN t2 t2a ON t2a.K1r = t1a.K1 +LEFT JOIN +( t1 t1i LEFT JOIN t2 t2i ON t2i.K1r = t1i.K1) +ON (t1i.K1 = 1) AND +(((t2i.K1r = t1a.K1 AND t2i.rowTimestamp > t2a.rowTimestamp ) OR +(t2i.rowTimestamp = t2a.rowTimestamp AND t2i.K2 > t2a.K2)) +OR (t2i.K2 IS NULL)) +WHERE +t2a.K1r = 1 AND t2i.K2 IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1a const PRIMARY PRIMARY 4 const 1 100.00 +1 SIMPLE t2a ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1i const PRIMARY PRIMARY 4 const 1 100.00 Using index +1 SIMPLE t2i ALL NULL NULL NULL NULL 3 100.00 Using where; Not exists +Warnings: +Note 1003 select 1 AS `K1`,'T1Row1' AS `Name`,`test`.`t2a`.`K2` AS `K2`,`test`.`t2a`.`K1r` AS `K1r`,`test`.`t2a`.`rowTimestamp` AS `rowTimestamp`,`test`.`t2a`.`Event` AS `Event`,`test`.`t2i`.`K2` AS `K2B`,`test`.`t2i`.`K1r` AS `K1rB`,`test`.`t2i`.`rowTimestamp` AS `rowTimestampB`,`test`.`t2i`.`Event` AS `EventB` from `test`.`t1` `t1a` join `test`.`t2` `t2a` left join (`test`.`t1` `t1i` left join `test`.`t2` `t2i` on(`test`.`t2i`.`K1r` = 1)) on(`test`.`t1i`.`K1` = 1 and (`test`.`t2i`.`K1r` = 1 and `test`.`t2i`.`rowTimestamp` > `test`.`t2a`.`rowTimestamp` or `test`.`t2i`.`rowTimestamp` = `test`.`t2a`.`rowTimestamp` and `test`.`t2i`.`K2` > `test`.`t2a`.`K2` or `test`.`t2i`.`K2` is null)) where `test`.`t2a`.`K1r` = 1 and `test`.`t2i`.`K2` is null +CREATE VIEW v1 AS +SELECT t2i.* +FROM t1 as t1i LEFT JOIN t2 as t2i ON t2i.K1r = t1i.K1 +WHERE t1i.K1 = 1 ; +SELECT +t1a.*, t2a.*, t2b.K2 as K2B, t2b.K1r as K1rB, +t2b.rowTimestamp as rowTimestampB, t2b.Event as EventB +FROM +t1 as t1a JOIN t2 as t2a ON t2a.K1r = t1a.K1 +LEFT JOIN +v1 as t2b +ON ((t2b.K1r = t1a.K1 AND t2b.rowTimestamp > t2a.rowTimestamp) OR +(t2b.rowTimestamp = t2a.rowTimestamp AND t2b.K2 > t2a.K2)) +OR (t2b.K2 IS NULL) +WHERE +t1a.K1 = 1 AND +t2b.K2 IS NULL; +K1 Name K2 K1r rowTimestamp Event K2B K1rB rowTimestampB EventB +1 T1Row1 3 1 2015-04-13 10:42:12 T1Row1Event3 NULL NULL NULL NULL +EXPLAIN EXTENDED SELECT +t1a.*, t2a.*, t2b.K2 as K2B, t2b.K1r as K1rB, +t2b.rowTimestamp as rowTimestampB, t2b.Event as EventB +FROM +t1 as t1a JOIN t2 as t2a ON t2a.K1r = t1a.K1 +LEFT JOIN +v1 as t2b +ON ((t2b.K1r = t1a.K1 AND t2b.rowTimestamp > t2a.rowTimestamp) OR +(t2b.rowTimestamp = t2a.rowTimestamp AND t2b.K2 > t2a.K2)) +OR (t2b.K2 IS NULL) +WHERE +t1a.K1 = 1 AND +t2b.K2 IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1a const PRIMARY PRIMARY 4 const 1 100.00 +1 SIMPLE t2a ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1i const PRIMARY PRIMARY 4 const 1 100.00 Using index +1 SIMPLE t2i ALL NULL NULL NULL NULL 3 100.00 Using where; Not exists +Warnings: +Note 1003 select 1 AS `K1`,'T1Row1' AS `Name`,`t2a`.`K2` AS `K2`,`t2a`.`K1r` AS `K1r`,`t2a`.`rowTimestamp` AS `rowTimestamp`,`t2a`.`Event` AS `Event`,`test`.`t2i`.`K2` AS `K2B`,`test`.`t2i`.`K1r` AS `K1rB`,`test`.`t2i`.`rowTimestamp` AS `rowTimestampB`,`test`.`t2i`.`Event` AS `EventB` from `test`.`t1` `t1a` join `test`.`t2` `t2a` left join (`test`.`t1` `t1i` left join `test`.`t2` `t2i` on(`test`.`t2i`.`K1r` = 1)) on(`test`.`t1i`.`K1` = 1 and (`test`.`t2i`.`K1r` = 1 and `test`.`t2i`.`rowTimestamp` > `t2a`.`rowTimestamp` or `test`.`t2i`.`rowTimestamp` = `t2a`.`rowTimestamp` and `test`.`t2i`.`K2` > `t2a`.`K2` or `test`.`t2i`.`K2` is null)) where `t2a`.`K1r` = 1 and `test`.`t2i`.`K2` is null +DROP VIEW v1; +DROP TABLE t1,t2; +set optimizer_search_depth= @tmp_mdev621; +# +# MDEV-19588: Nested left joins using optimized join cache +# +set optimizer_switch='optimize_join_buffer_size=on'; +set @save_join_cache_level= @@join_cache_level; +set join_cache_level=2; +CREATE TABLE t1 (i1 int, c1 varchar(20), pk int) engine=myisam; +CREATE TABLE t2 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t2 VALUES (7,'a',-912),(8,'a',5); +CREATE TABLE t3 (pk int, c1 varchar(20), i1 int) engine=myisam; +INSERT INTO t3 VALUES +(1,'a',-145),(2,'a',6),(3,'a',1),(7,'a',NULL),(8,'a',889),(9,'a',146), +(10,'a',177),(16,'a',-433),(17,'a',NULL),(18,'a',2),(19,'a',3),(20,'a',5), +(21,'a',-484),(22,'a',369),(23,'a',-192),(24,'a',-163),(25,'a',5),(26,'a',NULL); +SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; +pk c1 i1 +7 a NULL +17 a NULL +26 a NULL +explain extended SELECT t3.* +FROM t3 LEFT JOIN t1 LEFT JOIN t2 ON t1.i1 = t2.i1 ON t3.i1 = t1.i1 +WHERE t2.pk < 13 OR t3.i1 IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 ALL NULL NULL NULL NULL 18 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 0 0.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) +Warnings: +Note 1003 select `test`.`t3`.`pk` AS `pk`,`test`.`t3`.`c1` AS `c1`,`test`.`t3`.`i1` AS `i1` from `test`.`t3` left join (`test`.`t1` left join `test`.`t2` on(`test`.`t2`.`i1` = `test`.`t3`.`i1`)) on(`test`.`t1`.`i1` = `test`.`t3`.`i1`) where `test`.`t2`.`pk` < 13 or `test`.`t3`.`i1` is null +DROP TABLE t1,t2,t3; +set join_cache_level= @save_join_cache_level; +set optimizer_switch=@save_optimizer_switch; +# +# MDEV-27624: Nested left joins with not_exists optimization +# for most inner left join +# +set @save_join_cache_level= @@join_cache_level; +CREATE TABLE t1 (a INT NOT NULL, b INT, c INT); +INSERT INTO t1 VALUES (1,1,1), (1,2,1), (1,3,1); +CREATE TABLE t2(a INT NOT NULL); +INSERT INTO t2 VALUES (1), (2); +CREATE TABLE t3(a INT not null, b INT); +INSERT INTO t3 VALUES (1, 1), (2, 1), (3, 1); +set join_cache_level = 0; +EXPLAIN SELECT * +FROM t1 +LEFT JOIN +( t2 LEFT JOIN t3 ON t2.a = t3.b ) +ON t2.a = 1 AND (t3.b = t1.a AND t3.a > t1.b OR t3.a is NULL) +WHERE t1.c = 1 AND t3.a is NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Not exists +SELECT * +FROM t1 +LEFT JOIN +( t2 LEFT JOIN t3 ON t2.a = t3.b ) +ON t2.a = 1 AND (t3.b = t1.a AND t3.a > t1.b OR t3.a is NULL) +WHERE t1.c = 1 AND t3.a is NULL; +a b c a a b +1 3 1 NULL NULL NULL +set join_cache_level = 2; +EXPLAIN SELECT * +FROM t1 +LEFT JOIN +( t2 LEFT JOIN t3 ON t2.a = t3.b ) +ON t2.a = 1 AND (t3.b = t1.a AND t3.a > t1.b OR t3.a is NULL) +WHERE t1.c = 1 AND t3.a is NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 Using where +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 Using where; Not exists; Using join buffer (incremental, BNL join) +SELECT * +FROM t1 +LEFT JOIN +( t2 LEFT JOIN t3 ON t2.a = t3.b ) +ON t2.a = 1 AND (t3.b = t1.a AND t3.a > t1.b OR t3.a is NULL) +WHERE t1.c = 1 AND t3.a is NULL; +a b c a a b +1 3 1 NULL NULL NULL +DROP TABLE t1, t2, t3; +set join_cache_level= @save_join_cache_level; +# end of 10.3 tests +# +# MDEV-32084: Assertion in best_extension_by_limited_search(), or crash elsewhere in release +# +CREATE TABLE t1 (i int); +INSERT INTO t1 values (1),(2); +SELECT 1 FROM t1 WHERE i IN +(SELECT 1 FROM t1 c +LEFT JOIN (t1 a LEFT JOIN t1 b ON t1.i = b.i) ON c.i = t1.i); +1 +1 +DROP TABLE t1; +# +# MDEV-35206: Assertion in JOIN::dbug_verify_sj_inner_tables +# +SET @save_optimizer_join_limit_pref_ratio= @@optimizer_join_limit_pref_ratio; +SET @save_optimizer_search_depth= @@optimizer_search_depth; +CREATE TABLE t1 (c1 VARCHAR(64) DEFAULT NULL, c2 VARCHAR(8) DEFAULT NULL); +INSERT INTO t1 (c1) values ('one'); +INSERT INTO t1 (c2) values ('2'); +SET optimizer_join_limit_pref_ratio=10; +SET optimizer_search_depth=1; +SELECT +c1 +FROM +t1 +WHERE +c2 IN (SELECT c2 +FROM t1 +WHERE c1 IN (SELECT c1 +FROM t1 +WHERE c1 IN (NULL) +) +) +ORDER BY c1 LIMIT 1; +c1 +DROP TABLE t1; +# +# similar issue with join::cur_embedding_map +# +CREATE TABLE t10 (a int, b int, index(b)); +INSERT INTO t10 SELECT seq, seq FROM seq_1_to_10; +CREATE TABLE t11(a int, b int); +CREATE TABLE t12(a int, b int, index(b)); +INSERT INTO t11 select seq, seq FROM seq_1_to_20; +INSERT INTO t12 select seq, seq FROM seq_1_to_40; +CREATE TABLE t13(a int, b int); +CREATE TABLE t14(a int, b int, index(b)); +INSERT INTO t13 select seq, seq FROM seq_1_to_20; +INSERT INTO t14 select seq, seq FROM seq_1_to_40; +ANALYZE TABLE t10, t11, t12; +Table Op Msg_type Msg_text +test.t10 analyze status Engine-independent statistics collected +test.t10 analyze status Table is already up to date +test.t11 analyze status Engine-independent statistics collected +test.t11 analyze status OK +test.t12 analyze status Engine-independent statistics collected +test.t12 analyze status Table is already up to date +EXPLAIN SELECT * +FROM +t10 LEFT JOIN +( +t11 JOIN t12 ON t11.b=t12.b +left join (t13 join t14 on t13.b=t14.b) on t13.a=t11.a +) ON t10.a=t11.a +ORDER BY t10.b LIMIT 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t10 ALL NULL NULL NULL NULL 10 Using temporary; Using filesort +1 SIMPLE t11 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t12 ref b b 5 test.t11.b 1 +1 SIMPLE t13 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE t14 ref b b 5 test.t13.b 1 +DROP TABLE t10, t11, t12, t13, t14; +SET optimizer_join_limit_pref_ratio= @save_optimizer_join_limit_pref_ratio; +SET optimizer_search_depth= @save_optimizer_search_depth; +# end of 10.11 tests +drop table if exists t0,t1,t2,t3,t4,t5; +drop view if exists v0,v1,v2,v3; +SET @org_optimizer_switch=@@optimizer_switch; +SET optimizer_switch=ifnull(@optimizer_switch_for_join_outer_test,'outer_join_with_cache=off'); +set join_cache_level=1; +CREATE TABLE t1 ( +grp int(11) default NULL, +a bigint(20) unsigned default NULL, +c char(10) NOT NULL default '' +) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1,1,'a'),(2,2,'b'),(2,3,'c'),(3,4,'E'),(3,5,'C'),(3,6,'D'),(NULL,NULL,''); +create table t2 (id int, a bigint unsigned not null, c char(10), d int, primary key (a)); +insert into t2 values (1,1,"a",1),(3,4,"A",4),(3,5,"B",5),(3,6,"C",6),(4,7,"D",7); +select t1.*,t2.* from t1 JOIN t2 where t1.a=t2.a; +grp a c id a c d +1 1 a 1 1 a 1 +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) order by t1.grp,t1.a,t2.c; +grp a c id a c d +NULL NULL NULL NULL NULL NULL +1 1 a 1 1 a 1 +2 2 b NULL NULL NULL NULL +2 3 c NULL NULL NULL NULL +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +select t1.*,t2.* from { oj t2 left outer join t1 on (t1.a=t2.a) }; +grp a c id a c d +1 1 a 1 1 a 1 +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +NULL NULL NULL 4 7 D 7 +select t1.*,t2.* from t1 as t0,{ oj t2 left outer join t1 on (t1.a=t2.a) } WHERE t0.a=2; +grp a c id a c d +1 1 a 1 1 a 1 +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +NULL NULL NULL 4 7 D 7 +select t1.*,t2.* from t1 left join t2 using (a); +grp a c id a c d +1 1 a 1 1 a 1 +2 2 b NULL NULL NULL NULL +2 3 c NULL NULL NULL NULL +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +NULL NULL NULL NULL NULL NULL +select t1.*,t2.* from t1 left join t2 using (a) where t1.a=t2.a; +grp a c id a c d +1 1 a 1 1 a 1 +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +select t1.*,t2.* from t1 left join t2 using (a,c); +grp a c id a c d +1 1 a 1 1 a 1 +2 2 b NULL NULL NULL NULL +2 3 c NULL NULL NULL NULL +3 4 E NULL NULL NULL NULL +3 5 C NULL NULL NULL NULL +3 6 D NULL NULL NULL NULL +NULL NULL NULL NULL NULL NULL +select t1.*,t2.* from t1 left join t2 using (c); +grp a c id a c d +1 1 a 1 1 a 1 +1 1 a 3 4 A 4 +2 2 b 3 5 B 5 +2 3 c 3 6 C 6 +3 4 E NULL NULL NULL NULL +3 5 C 3 6 C 6 +3 6 D 4 7 D 7 +NULL NULL NULL NULL NULL NULL +select t1.*,t2.* from t1 natural left outer join t2; +grp a c id a c d +1 1 a 1 1 a 1 +2 2 b NULL NULL NULL NULL +2 3 c NULL NULL NULL NULL +3 4 E NULL NULL NULL NULL +3 5 C NULL NULL NULL NULL +3 6 D NULL NULL NULL NULL +NULL NULL NULL NULL NULL NULL +select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id=3; +grp a c id a c d +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +select t1.*,t2.* from t1 left join t2 on (t1.a=t2.a) where t2.id is null; +grp a c id a c d +2 2 b NULL NULL NULL NULL +2 3 c NULL NULL NULL NULL +NULL NULL NULL NULL NULL NULL +explain select t1.*,t2.* from t1,t2 where t1.a=t2.a and isnull(t2.a)=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 8 test.t1.a 1 Using where +select t1.*,t2.*,t3.a from t1 left join t2 on (t1.a=t2.a) left join t1 as t3 on (t2.a=t3.a); +grp a c id a c d a +1 1 a 1 1 a 1 1 +2 2 b NULL NULL NULL NULL NULL +2 3 c NULL NULL NULL NULL NULL +3 4 E 3 4 A 4 4 +3 5 C 3 5 B 5 5 +3 6 D 3 6 C 6 6 +NULL NULL NULL NULL NULL NULL NULL +explain select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a); +ERROR 42S22: Unknown column 't3.a' in 'ON' +select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t1.a=t3.a); +ERROR 42S22: Unknown column 't3.a' in 'ON' +select t1.*,t2.*,t3.a from t1 left join t2 on (t3.a=t2.a) left join t1 as t3 on (t2.a=t3.a); +ERROR 42S22: Unknown column 't3.a' in 'ON' +select t1.*,t2.* from t1 inner join t2 using (a); +grp a c id a c d +1 1 a 1 1 a 1 +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +select t1.*,t2.* from t1 inner join t2 on (t1.a=t2.a); +grp a c id a c d +1 1 a 1 1 a 1 +3 4 E 3 4 A 4 +3 5 C 3 5 B 5 +3 6 D 3 6 C 6 +select t1.*,t2.* from t1 natural join t2; +grp a c id a c d +1 1 a 1 1 a 1 +drop table t1,t2; +CREATE TABLE t1 ( +usr_id INT unsigned NOT NULL, +uniq_id INT unsigned NOT NULL AUTO_INCREMENT, +start_num INT unsigned NOT NULL DEFAULT 1, +increment INT unsigned NOT NULL DEFAULT 1, +PRIMARY KEY (uniq_id), +INDEX usr_uniq_idx (usr_id, uniq_id), +INDEX uniq_usr_idx (uniq_id, usr_id) +); +CREATE TABLE t2 ( +id INT unsigned NOT NULL DEFAULT 0, +usr2_id INT unsigned NOT NULL DEFAULT 0, +max INT unsigned NOT NULL DEFAULT 0, +c_amount INT unsigned NOT NULL DEFAULT 0, +d_max INT unsigned NOT NULL DEFAULT 0, +d_num INT unsigned NOT NULL DEFAULT 0, +orig_time INT unsigned NOT NULL DEFAULT 0, +c_time INT unsigned NOT NULL DEFAULT 0, +active ENUM ("no","yes") NOT NULL, +PRIMARY KEY (id,usr2_id), +INDEX id_idx (id), +INDEX usr2_idx (usr2_id) +); +INSERT INTO t1 VALUES (3,NULL,0,50),(3,NULL,0,200),(3,NULL,0,25),(3,NULL,0,84676),(3,NULL,0,235),(3,NULL,0,10),(3,NULL,0,3098),(3,NULL,0,2947),(3,NULL,0,8987),(3,NULL,0,8347654),(3,NULL,0,20398),(3,NULL,0,8976),(3,NULL,0,500),(3,NULL,0,198); +SELECT t1.usr_id,t1.uniq_id,t1.increment, +t2.usr2_id,t2.c_amount,t2.max +FROM t1 +LEFT JOIN t2 ON t2.id = t1.uniq_id +WHERE t1.uniq_id = 4 +ORDER BY t2.c_amount; +usr_id uniq_id increment usr2_id c_amount max +3 4 84676 NULL NULL NULL +SELECT t1.usr_id,t1.uniq_id,t1.increment, +t2.usr2_id,t2.c_amount,t2.max +FROM t2 +RIGHT JOIN t1 ON t2.id = t1.uniq_id +WHERE t1.uniq_id = 4 +ORDER BY t2.c_amount; +usr_id uniq_id increment usr2_id c_amount max +3 4 84676 NULL NULL NULL +INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes'); +INSERT INTO t2 VALUES (2,3,3000,6000,0,0,746584,837484,'yes'); +ERROR 23000: Duplicate entry '2-3' for key 'PRIMARY' +INSERT INTO t2 VALUES (7,3,1000,2000,0,0,746294,937484,'yes'); +SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 ORDER BY t2.c_amount; +usr_id uniq_id increment usr2_id c_amount max +3 4 84676 NULL NULL NULL +SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4 GROUP BY t2.c_amount; +usr_id uniq_id increment usr2_id c_amount max +3 4 84676 NULL NULL NULL +SELECT t1.usr_id,t1.uniq_id,t1.increment,t2.usr2_id,t2.c_amount,t2.max FROM t1 LEFT JOIN t2 ON t2.id = t1.uniq_id WHERE t1.uniq_id = 4; +usr_id uniq_id increment usr2_id c_amount max +3 4 84676 NULL NULL NULL +drop table t1,t2; +CREATE TABLE t1 ( +cod_asig int(11) DEFAULT '0' NOT NULL, +desc_larga_cat varchar(80) DEFAULT '' NOT NULL, +desc_larga_cas varchar(80) DEFAULT '' NOT NULL, +desc_corta_cat varchar(40) DEFAULT '' NOT NULL, +desc_corta_cas varchar(40) DEFAULT '' NOT NULL, +cred_total double(3,1) DEFAULT '0.0' NOT NULL, +pre_requisit int(11), +co_requisit int(11), +preco_requisit int(11), +PRIMARY KEY (cod_asig) +); +INSERT INTO t1 VALUES (10360,'asdfggfg','Introduccion a los Ordenadores I','asdfggfg','Introduccio Ordinadors I',6.0,NULL,NULL,NULL); +INSERT INTO t1 VALUES (10361,'Components i Circuits Electronics I','Componentes y Circuitos Electronicos I','Components i Circuits Electronics I','Comp. i Circ. Electr. I',6.0,NULL,NULL,NULL); +INSERT INTO t1 VALUES (10362,'Laboratori d`Ordinadors','Laboratorio de Ordenadores','Laboratori d`Ordinadors','Laboratori Ordinadors',4.5,NULL,NULL,NULL); +INSERT INTO t1 VALUES (10363,'Tecniques de Comunicacio Oral i Escrita','Tecnicas de Comunicacion Oral y Escrita','Tecniques de Comunicacio Oral i Escrita','Tec. Com. Oral i Escrita',4.5,NULL,NULL,NULL); +INSERT INTO t1 VALUES (11403,'Projecte Fi de Carrera','Proyecto Fin de Carrera','Projecte Fi de Carrera','PFC',9.0,NULL,NULL,NULL); +INSERT INTO t1 VALUES (11404,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',15.0,NULL,NULL,NULL); +INSERT INTO t1 VALUES (11405,'+lgebra lineal','Algebra lineal','+lgebra lineal','+lgebra lineal',18.0,NULL,NULL,NULL); +INSERT INTO t1 VALUES (11406,'Calcul Infinitesimal','Cßlculo Infinitesimal','Calcul Infinitesimal','Calcul Infinitesimal',15.0,NULL,NULL,NULL); +CREATE TABLE t2 ( +idAssignatura int(11) DEFAULT '0' NOT NULL, +Grup int(11) DEFAULT '0' NOT NULL, +Places smallint(6) DEFAULT '0' NOT NULL, +PlacesOcupades int(11) DEFAULT '0', +PRIMARY KEY (idAssignatura,Grup) +); +INSERT INTO t2 VALUES (10360,12,333,0); +INSERT INTO t2 VALUES (10361,30,2,0); +INSERT INTO t2 VALUES (10361,40,3,0); +INSERT INTO t2 VALUES (10360,45,10,0); +INSERT INTO t2 VALUES (10362,10,12,0); +INSERT INTO t2 VALUES (10360,55,2,0); +INSERT INTO t2 VALUES (10360,70,0,0); +INSERT INTO t2 VALUES (10360,565656,0,0); +INSERT INTO t2 VALUES (10360,32767,7,0); +INSERT INTO t2 VALUES (10360,33,8,0); +INSERT INTO t2 VALUES (10360,7887,85,0); +INSERT INTO t2 VALUES (11405,88,8,0); +INSERT INTO t2 VALUES (10360,0,55,0); +INSERT INTO t2 VALUES (10360,99,0,0); +INSERT INTO t2 VALUES (11411,30,10,0); +INSERT INTO t2 VALUES (11404,0,0,0); +INSERT INTO t2 VALUES (10362,11,111,0); +INSERT INTO t2 VALUES (10363,33,333,0); +INSERT INTO t2 VALUES (11412,55,0,0); +INSERT INTO t2 VALUES (50003,66,6,0); +INSERT INTO t2 VALUES (11403,5,0,0); +INSERT INTO t2 VALUES (11406,11,11,0); +INSERT INTO t2 VALUES (11410,11410,131,0); +INSERT INTO t2 VALUES (11416,11416,32767,0); +INSERT INTO t2 VALUES (11409,0,0,0); +CREATE TABLE t3 ( +id int(11) NOT NULL auto_increment, +dni_pasaporte char(16) DEFAULT '' NOT NULL, +idPla int(11) DEFAULT '0' NOT NULL, +cod_asig int(11) DEFAULT '0' NOT NULL, +any smallint(6) DEFAULT '0' NOT NULL, +quatrimestre smallint(6) DEFAULT '0' NOT NULL, +estat char(1) DEFAULT 'M' NOT NULL, +PRIMARY KEY (id), +UNIQUE dni_pasaporte (dni_pasaporte,idPla), +UNIQUE dni_pasaporte_2 (dni_pasaporte,idPla,cod_asig,any,quatrimestre) +); +INSERT INTO t3 VALUES (1,'11111111',1,10362,98,1,'M'); +CREATE TABLE t4 ( +id int(11) NOT NULL auto_increment, +papa int(11) DEFAULT '0' NOT NULL, +fill int(11) DEFAULT '0' NOT NULL, +idPla int(11) DEFAULT '0' NOT NULL, +PRIMARY KEY (id), +KEY papa (idPla,papa), +UNIQUE papa_2 (idPla,papa,fill) +); +INSERT INTO t4 VALUES (1,-1,10360,1); +INSERT INTO t4 VALUES (2,-1,10361,1); +INSERT INTO t4 VALUES (3,-1,10362,1); +SELECT DISTINCT fill,desc_larga_cat,cred_total,Grup,Places,PlacesOcupades FROM t4 LEFT JOIN t3 ON t3.cod_asig=fill AND estat='S' AND dni_pasaporte='11111111' AND t3.idPla=1 , t2,t1 WHERE fill=t1.cod_asig AND Places>PlacesOcupades AND fill=idAssignatura AND t4.idPla=1 AND papa=-1; +fill desc_larga_cat cred_total Grup Places PlacesOcupades +10360 asdfggfg 6.0 0 55 0 +10360 asdfggfg 6.0 12 333 0 +10360 asdfggfg 6.0 32767 7 0 +10360 asdfggfg 6.0 33 8 0 +10360 asdfggfg 6.0 45 10 0 +10360 asdfggfg 6.0 55 2 0 +10360 asdfggfg 6.0 7887 85 0 +10361 Components i Circuits Electronics I 6.0 30 2 0 +10361 Components i Circuits Electronics I 6.0 40 3 0 +10362 Laboratori d`Ordinadors 4.5 10 12 0 +10362 Laboratori d`Ordinadors 4.5 11 111 0 +SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ; +fill idPla +10360 NULL +10361 NULL +10362 NULL +INSERT INTO t3 VALUES (3,'1234',1,10360,98,1,'S'); +SELECT DISTINCT fill,t3.idPla FROM t4 LEFT JOIN t3 ON t3.cod_asig=t4.fill AND t3.estat='S' AND t3.dni_pasaporte='1234' AND t3.idPla=1 ; +fill idPla +10360 1 +10361 NULL +10362 NULL +drop table t1,t2,t3,test.t4; +CREATE TABLE t1 ( +id smallint(5) unsigned NOT NULL auto_increment, +name char(60) DEFAULT '' NOT NULL, +PRIMARY KEY (id) +); +INSERT INTO t1 VALUES (1,'Antonio Paz'); +INSERT INTO t1 VALUES (2,'Lilliana Angelovska'); +INSERT INTO t1 VALUES (3,'Thimble Smith'); +CREATE TABLE t2 ( +id smallint(5) unsigned NOT NULL auto_increment, +owner smallint(5) unsigned DEFAULT '0' NOT NULL, +name char(60), +PRIMARY KEY (id) +); +INSERT INTO t2 VALUES (1,1,'El Gato'); +INSERT INTO t2 VALUES (2,1,'Perrito'); +INSERT INTO t2 VALUES (3,3,'Happy'); +select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner); +name name id +Antonio Paz El Gato 1 +Antonio Paz Perrito 2 +Lilliana Angelovska NULL NULL +Thimble Smith Happy 3 +select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null; +name name id +Lilliana Angelovska NULL NULL +explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.id is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists +explain select t1.name, t2.name, t2.id from t1 left join t2 on (t1.id = t2.owner) where t2.name is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where +select count(*) from t1 left join t2 on (t1.id = t2.owner); +count(*) +4 +select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner); +name name id +Antonio Paz El Gato 1 +Antonio Paz Perrito 2 +Lilliana Angelovska NULL NULL +Thimble Smith Happy 3 +select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null; +name name id +Lilliana Angelovska NULL NULL +explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.id is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where; Not exists +explain select t1.name, t2.name, t2.id from t2 right join t1 on (t1.id = t2.owner) where t2.name is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 Using where +select count(*) from t2 right join t1 on (t1.id = t2.owner); +count(*) +4 +select t1.name, t2.name, t2.id,t3.id from t2 right join t1 on (t1.id = t2.owner) left join t1 as t3 on t3.id=t2.owner; +name name id id +Antonio Paz El Gato 1 1 +Antonio Paz Perrito 2 1 +Lilliana Angelovska NULL NULL NULL +Thimble Smith Happy 3 3 +select t1.name, t2.name, t2.id,t3.id from t1 right join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner; +name name id id +Antonio Paz El Gato 1 1 +Antonio Paz Perrito 2 1 +NULL NULL NULL 2 +Thimble Smith Happy 3 3 +select t1.name, t2.name, t2.id, t2.owner, t3.id from t1 left join t2 on (t1.id = t2.owner) right join t1 as t3 on t3.id=t2.owner; +name name id owner id +Antonio Paz El Gato 1 1 1 +Antonio Paz Perrito 2 1 1 +NULL NULL NULL NULL 2 +Thimble Smith Happy 3 3 3 +drop table t1,t2; +create table t1 (id int not null, str char(10), index(str)); +insert into t1 values (1, null), (2, null), (3, "foo"), (4, "bar"); +select * from t1 where str is not null order by id; +id str +3 foo +4 bar +select * from t1 where str is null; +id str +1 NULL +2 NULL +drop table t1; +CREATE TABLE t1 ( +t1_id bigint(21) NOT NULL auto_increment, +PRIMARY KEY (t1_id) +); +CREATE TABLE t2 ( +t2_id bigint(21) NOT NULL auto_increment, +PRIMARY KEY (t2_id) +); +CREATE TABLE t3 ( +t3_id bigint(21) NOT NULL auto_increment, +PRIMARY KEY (t3_id) +); +CREATE TABLE t4 ( +seq_0_id bigint(21) DEFAULT '0' NOT NULL, +seq_1_id bigint(21) DEFAULT '0' NOT NULL, +KEY seq_0_id (seq_0_id), +KEY seq_1_id (seq_1_id) +); +CREATE TABLE t5 ( +seq_0_id bigint(21) DEFAULT '0' NOT NULL, +seq_1_id bigint(21) DEFAULT '0' NOT NULL, +KEY seq_1_id (seq_1_id), +KEY seq_0_id (seq_0_id) +); +insert into t1 values (1); +insert into t2 values (1); +insert into t3 values (1); +insert into t4 values (1,1); +insert into t5 values (1,1); +explain select * from t3 left join t4 on t4.seq_1_id = t2.t2_id left join t1 on t1.t1_id = t4.seq_0_id left join t5 on t5.seq_0_id = t1.t1_id left join t2 on t2.t2_id = t5.seq_1_id where t3.t3_id = 23; +ERROR 42S22: Unknown column 't2.t2_id' in 'ON' +drop table t1,t2,t3,t4,t5; +create table t1 (n int, m int, o int, key(n)); +create table t2 (n int not null, m int, o int, primary key(n)); +insert into t1 values (1, 2, 11), (1, 2, 7), (2, 2, 8), (1,2,9),(1,3,9); +insert into t2 values (1, 2, 3),(2, 2, 8), (4,3,9),(3,2,10); +select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and +t1.m = t2.m where t1.n = 1; +n m o n m o +1 2 11 1 2 3 +1 2 7 1 2 3 +1 2 9 1 2 3 +1 3 9 NULL NULL NULL +select t1.*, t2.* from t1 left join t2 on t1.n = t2.n and +t1.m = t2.m where t1.n = 1 order by t1.o; +n m o n m o +1 2 11 1 2 3 +1 2 7 1 2 3 +1 2 9 1 2 3 +1 3 9 NULL NULL NULL +drop table t1,t2; +CREATE TABLE t1 (id1 INT NOT NULL PRIMARY KEY, dat1 CHAR(1), id2 INT); +INSERT INTO t1 VALUES (1,'a',1); +INSERT INTO t1 VALUES (2,'b',1); +INSERT INTO t1 VALUES (3,'c',2); +CREATE TABLE t2 (id2 INT NOT NULL PRIMARY KEY, dat2 CHAR(1)); +INSERT INTO t2 VALUES (1,'x'); +INSERT INTO t2 VALUES (2,'y'); +INSERT INTO t2 VALUES (3,'z'); +SELECT t2.id2 FROM t2 LEFT OUTER JOIN t1 ON t1.id2 = t2.id2 WHERE id1 IS NULL; +id2 +3 +SELECT t2.id2 FROM t2 NATURAL LEFT OUTER JOIN t1 WHERE id1 IS NULL; +id2 +3 +drop table t1,t2; +create table t1 ( color varchar(20), name varchar(20) ); +insert into t1 values ( 'red', 'apple' ); +insert into t1 values ( 'yellow', 'banana' ); +insert into t1 values ( 'green', 'lime' ); +insert into t1 values ( 'black', 'grape' ); +insert into t1 values ( 'blue', 'blueberry' ); +create table t2 ( count int, color varchar(20) ); +insert into t2 values (10, 'green'); +insert into t2 values (5, 'black'); +insert into t2 values (15, 'white'); +insert into t2 values (7, 'green'); +select * from t1; +color name +red apple +yellow banana +green lime +black grape +blue blueberry +select * from t2; +count color +10 green +5 black +15 white +7 green +select * from t2 natural join t1; +color count name +green 10 lime +green 7 lime +black 5 grape +select t2.count, t1.name from t2 natural join t1; +count name +10 lime +7 lime +5 grape +select t2.count, t1.name from t2 inner join t1 using (color); +count name +10 lime +7 lime +5 grape +drop table t1; +drop table t2; +CREATE TABLE t1 ( +pcode varchar(8) DEFAULT '' NOT NULL +); +INSERT INTO t1 VALUES ('kvw2000'),('kvw2001'),('kvw3000'),('kvw3001'),('kvw3002'),('kvw3500'),('kvw3501'),('kvw3502'),('kvw3800'),('kvw3801'),('kvw3802'),('kvw3900'),('kvw3901'),('kvw3902'),('kvw4000'),('kvw4001'),('kvw4002'),('kvw4200'),('kvw4500'),('kvw5000'),('kvw5001'),('kvw5500'),('kvw5510'),('kvw5600'),('kvw5601'),('kvw6000'),('klw1000'),('klw1020'),('klw1500'),('klw2000'),('klw2001'),('klw2002'),('kld2000'),('klw2500'),('kmw1000'),('kmw1500'),('kmw2000'),('kmw2001'),('kmw2100'),('kmw3000'),('kmw3200'); +CREATE TABLE t2 ( +pcode varchar(8) DEFAULT '' NOT NULL, +KEY pcode (pcode) +); +INSERT INTO t2 VALUES ('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw2000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3000'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw3500'),('kvw6000'),('kvw6000'),('kld2000'); +SELECT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1 +LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode; +pcode count +kld2000 1 +klw1000 0 +klw1020 0 +klw1500 0 +klw2000 0 +klw2001 0 +klw2002 0 +klw2500 0 +kmw1000 0 +kmw1500 0 +kmw2000 0 +kmw2001 0 +kmw2100 0 +kmw3000 0 +kmw3200 0 +kvw2000 26 +kvw2001 0 +kvw3000 36 +kvw3001 0 +kvw3002 0 +kvw3500 26 +kvw3501 0 +kvw3502 0 +kvw3800 0 +kvw3801 0 +kvw3802 0 +kvw3900 0 +kvw3901 0 +kvw3902 0 +kvw4000 0 +kvw4001 0 +kvw4002 0 +kvw4200 0 +kvw4500 0 +kvw5000 0 +kvw5001 0 +kvw5500 0 +kvw5510 0 +kvw5600 0 +kvw5601 0 +kvw6000 2 +SELECT SQL_BIG_RESULT t1.pcode, IF(ISNULL(t2.pcode), 0, COUNT(*)) AS count FROM t1 LEFT JOIN t2 ON t1.pcode = t2.pcode GROUP BY t1.pcode; +pcode count +kld2000 1 +klw1000 0 +klw1020 0 +klw1500 0 +klw2000 0 +klw2001 0 +klw2002 0 +klw2500 0 +kmw1000 0 +kmw1500 0 +kmw2000 0 +kmw2001 0 +kmw2100 0 +kmw3000 0 +kmw3200 0 +kvw2000 26 +kvw2001 0 +kvw3000 36 +kvw3001 0 +kvw3002 0 +kvw3500 26 +kvw3501 0 +kvw3502 0 +kvw3800 0 +kvw3801 0 +kvw3802 0 +kvw3900 0 +kvw3901 0 +kvw3902 0 +kvw4000 0 +kvw4001 0 +kvw4002 0 +kvw4200 0 +kvw4500 0 +kvw5000 0 +kvw5001 0 +kvw5500 0 +kvw5510 0 +kvw5600 0 +kvw5601 0 +kvw6000 2 +drop table t1,t2; +CREATE TABLE t1 ( +id int(11), +pid int(11), +rep_del tinyint(4), +KEY id (id), +KEY pid (pid) +); +INSERT INTO t1 VALUES (1,NULL,NULL); +INSERT INTO t1 VALUES (2,1,NULL); +select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL; +id pid rep_del id pid rep_del +1 NULL NULL 2 1 NULL +2 1 NULL NULL NULL NULL +create index rep_del ON t1(rep_del); +select * from t1 LEFT JOIN t1 t2 ON (t1.id=t2.pid) AND t2.rep_del IS NULL; +id pid rep_del id pid rep_del +1 NULL NULL 2 1 NULL +2 1 NULL NULL NULL NULL +drop table t1; +CREATE TABLE t1 ( +id int(11) DEFAULT '0' NOT NULL, +name tinytext DEFAULT '' NOT NULL, +UNIQUE id (id) +); +INSERT INTO t1 VALUES (1,'yes'),(2,'no'); +CREATE TABLE t2 ( +id int(11) DEFAULT '0' NOT NULL, +idx int(11) DEFAULT '0' NOT NULL, +UNIQUE id (id,idx) +); +INSERT INTO t2 VALUES (1,1); +explain SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 +1 SIMPLE t2 ref id id 4 test.t1.id 1 Using where; Using index; Not exists +SELECT * from t1 left join t2 on t1.id=t2.id where t2.id IS NULL; +id name id idx +2 no NULL NULL +drop table t1,t2; +create table t1 (bug_id mediumint, reporter mediumint); +create table t2 (bug_id mediumint, who mediumint, index(who)); +insert into t2 values (1,1),(1,2); +insert into t1 values (1,1),(2,1); +SELECT * FROM t1 LEFT JOIN t2 ON (t1.bug_id = t2.bug_id AND t2.who = 2) WHERE (t1.reporter = 2 OR t2.who = 2); +bug_id reporter bug_id who +1 1 1 2 +drop table t1,t2; +create table t1 (fooID smallint unsigned auto_increment, primary key (fooID)); +create table t2 (fooID smallint unsigned not null, barID smallint unsigned not null, primary key (fooID,barID)); +insert into t1 (fooID) values (10),(20),(30); +insert into t2 values (10,1),(20,2),(30,3); +explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index +1 SIMPLE t1 const PRIMARY PRIMARY 2 const 1 Using where; Using index +select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; +fooID barID fooID +10 1 NULL +20 2 NULL +30 3 30 +select * from t2 left join t1 ignore index(primary) on t1.fooID = t2.fooID and t1.fooID = 30; +fooID barID fooID +10 1 NULL +20 2 NULL +30 3 30 +drop table t1,t2; +create table t1 (i int); +create table t2 (i int); +create table t3 (i int); +insert into t1 values(1),(2); +insert into t2 values(2),(3); +insert into t3 values(2),(4); +select * from t1 natural left join t2 natural left join t3; +i +1 +2 +select * from t1 natural left join t2 where (t2.i is not null)=0; +i +1 +select * from t1 natural left join t2 where (t2.i is not null) is not null; +i +1 +2 +select * from t1 natural left join t2 where (i is not null)=0; +i +select * from t1 natural left join t2 where (i is not null) is not null; +i +1 +2 +drop table t1,t2,t3; +create table t1 (f1 integer,f2 integer,f3 integer); +create table t2 (f2 integer,f4 integer); +create table t3 (f3 integer,f5 integer); +select * from t1 +left outer join t2 using (f2) +left outer join t3 using (f3); +f3 f2 f1 f4 f5 +drop table t1,t2,t3; +create table t1 (a1 int, a2 int); +create table t2 (b1 int not null, b2 int); +create table t3 (c1 int, c2 int); +insert into t1 values (1,2), (2,2), (3,2); +insert into t2 values (1,3), (2,3); +insert into t3 values (2,4), (3,4); +select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; +a1 a2 b1 b2 c1 c2 +1 2 1 3 NULL NULL +2 2 2 3 NULL NULL +3 2 NULL NULL 3 4 +explain select * from t1 left join t2 on b1 = a1 left join t3 on c1 = a1 and b1 is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 Using where +drop table t1, t2, t3; +create table t1 ( +a int(11), +b char(10), +key (a) +); +insert into t1 (a) values (1),(2),(3),(4); +create table t2 (a int); +select * from t1 left join t2 on t1.a=t2.a where not (t2.a <=> t1.a); +a b a +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +select * from t1 left join t2 on t1.a=t2.a having not (t2.a <=> t1.a); +a b a +1 NULL NULL +2 NULL NULL +3 NULL NULL +4 NULL NULL +drop table t1,t2; +create table t1 ( +match_id tinyint(3) unsigned not null auto_increment, +home tinyint(3) unsigned default '0', +unique key match_id (match_id), +key match_id_2 (match_id) +); +insert into t1 values("1", "2"); +create table t2 ( +player_id tinyint(3) unsigned default '0', +match_1_h tinyint(3) unsigned default '0', +key player_id (player_id) +); +insert into t2 values("1", "5"); +insert into t2 values("2", "9"); +insert into t2 values("3", "3"); +insert into t2 values("4", "7"); +insert into t2 values("5", "6"); +insert into t2 values("6", "8"); +insert into t2 values("7", "4"); +insert into t2 values("8", "12"); +insert into t2 values("9", "11"); +insert into t2 values("10", "10"); +explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +(t2 s left join t1 m on m.match_id = 1) +order by m.match_id desc; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort +1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 +explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +(t2 s left join t1 m on m.match_id = 1) +order by UUX desc; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort +1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 +select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +(t2 s left join t1 m on m.match_id = 1) +order by UUX desc; +player_id match_1_h * match_id home UUX +8 12 * 1 2 10 +9 11 * 1 2 9 +10 10 * 1 2 8 +2 9 * 1 2 7 +6 8 * 1 2 6 +4 7 * 1 2 5 +5 6 * 1 2 4 +1 5 * 1 2 3 +7 4 * 1 2 2 +3 3 * 1 2 1 +explain select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +t2 s straight_join t1 m where m.match_id = 1 +order by UUX desc; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE s ALL NULL NULL NULL NULL 10 Using temporary; Using filesort +1 SIMPLE m const match_id,match_id_2 match_id 1 const 1 +select s.*, '*', m.*, (s.match_1_h - m.home) UUX from +t2 s straight_join t1 m where m.match_id = 1 +order by UUX desc; +player_id match_1_h * match_id home UUX +8 12 * 1 2 10 +9 11 * 1 2 9 +10 10 * 1 2 8 +2 9 * 1 2 7 +6 8 * 1 2 6 +4 7 * 1 2 5 +5 6 * 1 2 4 +1 5 * 1 2 3 +7 4 * 1 2 2 +3 3 * 1 2 1 +drop table t1, t2; +create table t1 (a int, b int, unique index idx (a, b)); +create table t2 (a int, b int, c int, unique index idx (a, b)); +insert into t1 values (1, 10), (1,11), (2,10), (2,11); +insert into t2 values (1,10,3); +select t1.a, t1.b, t2.c from t1 left join t2 +on t1.a=t2.a and t1.b=t2.b and t2.c=3 +where t1.a=1 and t2.c is null; +a b c +1 11 NULL +drop table t1, t2; +CREATE TABLE t1 ( +ts_id bigint(20) default NULL, +inst_id tinyint(4) default NULL, +flag_name varchar(64) default NULL, +flag_value text, +UNIQUE KEY ts_id (ts_id,inst_id,flag_name) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +CREATE TABLE t2 ( +ts_id bigint(20) default NULL, +inst_id tinyint(4) default NULL, +flag_name varchar(64) default NULL, +flag_value text, +UNIQUE KEY ts_id (ts_id,inst_id,flag_name) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; +INSERT INTO t1 VALUES +(111056548820001, 0, 'flag1', NULL), +(111056548820001, 0, 'flag2', NULL), +(2, 0, 'other_flag', NULL); +INSERT INTO t2 VALUES +(111056548820001, 3, 'flag1', 'sss'); +SELECT t1.flag_name,t2.flag_value +FROM t1 LEFT JOIN t2 +ON (t1.ts_id = t2.ts_id AND t1.flag_name = t2.flag_name AND +t2.inst_id = 3) +WHERE t1.inst_id = 0 AND t1.ts_id=111056548820001 AND +t2.flag_value IS NULL; +flag_name flag_value +flag2 NULL +DROP TABLE t1,t2; +CREATE TABLE t1 ( +id int(11) unsigned NOT NULL auto_increment, +text_id int(10) unsigned default NULL, +PRIMARY KEY (id) +); +INSERT INTO t1 VALUES("1", "0"); +INSERT INTO t1 VALUES("2", "10"); +CREATE TABLE t2 ( +text_id char(3) NOT NULL default '', +language_id char(3) NOT NULL default '', +text_data text, +PRIMARY KEY (text_id,language_id) +); +INSERT INTO t2 VALUES("0", "EN", "0-EN"); +INSERT INTO t2 VALUES("0", "SV", "0-SV"); +INSERT INTO t2 VALUES("10", "EN", "10-EN"); +INSERT INTO t2 VALUES("10", "SV", "10-SV"); +SELECT t1.id, t1.text_id, t2.text_data +FROM t1 LEFT JOIN t2 +ON t1.text_id = t2.text_id +AND t2.language_id = 'SV' + WHERE (t1.id LIKE '%' OR t2.text_data LIKE '%'); +id text_id text_data +1 0 0-SV +2 10 10-SV +DROP TABLE t1, t2; +CREATE TABLE t0 (a0 int PRIMARY KEY); +CREATE TABLE t1 (a1 int PRIMARY KEY); +CREATE TABLE t2 (a2 int); +CREATE TABLE t3 (a3 int); +INSERT INTO t0 VALUES (1); +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1), (2); +INSERT INTO t3 VALUES (1), (2); +SELECT * FROM t1 LEFT JOIN t2 ON a1=0; +a1 a2 +1 NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON a1=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0; +a1 a2 a3 +1 NULL NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN (t2,t3) ON a1=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 +SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1; +a0 a1 a2 a3 +1 1 NULL NULL +EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=0 WHERE a0=a1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 system PRIMARY NULL NULL NULL 1 +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 +INSERT INTO t0 VALUES (0); +INSERT INTO t1 VALUES (0); +SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1; +a0 a1 a2 a3 +1 1 NULL NULL +EXPLAIN SELECT * FROM t0, t1 LEFT JOIN (t2,t3) ON a1=5 WHERE a0=a1 AND a0=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 +drop table t1,t2; +create table t1 (a int, b int); +insert into t1 values (1,1),(2,2),(3,3); +create table t2 (a int, b int); +insert into t2 values (1,1), (2,2); +select * from t2 right join t1 on t2.a=t1.a; +a b a b +1 1 1 1 +2 2 2 2 +NULL NULL 3 3 +select straight_join * from t2 right join t1 on t2.a=t1.a; +a b a b +1 1 1 1 +2 2 2 2 +NULL NULL 3 3 +DROP TABLE t0,t1,t2,t3; +CREATE TABLE t1 (a int PRIMARY KEY, b int); +CREATE TABLE t2 (a int PRIMARY KEY, b int); +INSERT INTO t1 VALUES (1,1), (2,1), (3,1), (4,2); +INSERT INTO t2 VALUES (1,2), (2,2); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a; +a b a b +1 1 1 2 +2 1 2 2 +3 1 NULL NULL +4 2 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE t1.b=1; +a b a b +1 1 1 2 +2 1 2 2 +3 1 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a +WHERE t1.b=1 XOR (NOT ISNULL(t2.a) AND t2.b=1); +a b a b +1 1 1 2 +2 1 2 2 +3 1 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a=t2.a WHERE not(0+(t1.a=30 and t2.b=1)); +a b a b +1 1 1 2 +2 1 2 2 +3 1 NULL NULL +4 2 NULL NULL +DROP TABLE t1,t2; +set group_concat_max_len=5; +create table t1 (a int, b varchar(20)); +create table t2 (a int, c varchar(20)); +insert into t1 values (1,"aaaaaaaaaa"),(2,"bbbbbbbbbb"); +insert into t2 values (1,"cccccccccc"),(2,"dddddddddd"); +select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by t1.a; +group_concat(t1.b,t2.c) +aaaaa +bbbbb +Warnings: +Warning 1260 Row 1 was cut by group_concat() +Warning 1260 Row 2 was cut by group_concat() +select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by t1.a; +group_concat(t1.b,t2.c) +aaaaa +bbbbb +Warnings: +Warning 1260 Row 1 was cut by group_concat() +Warning 1260 Row 2 was cut by group_concat() +select group_concat(t1.b,t2.c) from t1 left join t2 using(a) group by a; +group_concat(t1.b,t2.c) +aaaaa +bbbbb +Warnings: +Warning 1260 Row 1 was cut by group_concat() +Warning 1260 Row 2 was cut by group_concat() +select group_concat(t1.b,t2.c) from t1 inner join t2 using(a) group by a; +group_concat(t1.b,t2.c) +aaaaa +bbbbb +Warnings: +Warning 1260 Row 1 was cut by group_concat() +Warning 1260 Row 2 was cut by group_concat() +drop table t1, t2; +set group_concat_max_len=default; +create table t1 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, art int(11) not null, primary key (gid,x,y)); +insert t1 values (1, -5, -8, 2), (1, 2, 2, 1), (1, 1, 1, 1); +create table t2 (gid smallint(5) unsigned not null, x int(11) not null, y int(11) not null, id int(11) not null, primary key (gid,id,x,y), key id (id)); +insert t2 values (1, -5, -8, 1), (1, 1, 1, 1), (1, 2, 2, 1); +create table t3 ( set_id smallint(5) unsigned not null, id tinyint(4) unsigned not null, name char(12) not null, primary key (id,set_id)); +insert t3 values (0, 1, 'a'), (1, 1, 'b'), (0, 2, 'c'), (1, 2, 'd'), (1, 3, 'e'), (1, 4, 'f'), (1, 5, 'g'), (1, 6, 'h'); +explain select name from t1 left join t2 on t1.x = t2.x and t1.y = t2.y +left join t3 on t1.art = t3.id where t2.id =1 and t2.x = -5 and t2.y =-8 +and t1.gid =1 and t2.gid =1 and t3.set_id =1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 10 const,const,const 1 +1 SIMPLE t2 const PRIMARY,id PRIMARY 14 const,const,const,const 1 Using index +1 SIMPLE t3 const PRIMARY PRIMARY 3 const,const 1 +drop tables t1,t2,t3; +CREATE TABLE t1 (EMPNUM INT, GRP INT); +INSERT INTO t1 VALUES (0, 10); +INSERT INTO t1 VALUES (2, 30); +CREATE TABLE t2 (EMPNUM INT, NAME CHAR(5)); +INSERT INTO t2 VALUES (0, 'KERI'); +INSERT INTO t2 VALUES (9, 'BARRY'); +CREATE VIEW v1 AS +SELECT COALESCE(t2.EMPNUM,t1.EMPNUM) AS EMPNUM, NAME, GRP +FROM t2 LEFT OUTER JOIN t1 ON t2.EMPNUM=t1.EMPNUM; +SELECT * FROM v1; +EMPNUM NAME GRP +0 KERI 10 +9 BARRY NULL +SELECT * FROM v1 WHERE EMPNUM < 10; +EMPNUM NAME GRP +0 KERI 10 +9 BARRY NULL +DROP VIEW v1; +DROP TABLE t1,t2; +CREATE TABLE t1 (c11 int); +CREATE TABLE t2 (c21 int); +INSERT INTO t1 VALUES (30), (40), (50); +INSERT INTO t2 VALUES (300), (400), (500); +SELECT * FROM t1 LEFT JOIN t2 ON (c11=c21 AND c21=30) WHERE c11=40; +c11 c21 +40 NULL +DROP TABLE t1, t2; +CREATE TABLE t1 (a int PRIMARY KEY, b int); +CREATE TABLE t2 (a int PRIMARY KEY, b int); +INSERT INTO t1 VALUES (1,2), (2,1), (3,2), (4,3), (5,6), (6,5), (7,8), (8,7), (9,10); +INSERT INTO t2 VALUES (3,0), (4,1), (6,4), (7,5); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.b <= t1.a AND t1.a <= t1.b; +a b a b +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a BETWEEN t2.b AND t1.b; +a b a b +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a NOT BETWEEN t2.b AND t1.b); +a b a b +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.b > t1.a OR t1.a > t1.b; +a b a b +2 1 NULL NULL +3 2 3 0 +4 3 4 1 +6 5 6 4 +8 7 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a NOT BETWEEN t2.b AND t1.b; +a b a b +2 1 NULL NULL +3 2 3 0 +4 3 4 1 +6 5 6 4 +8 7 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a BETWEEN t2.b AND t1.b); +a b a b +2 1 NULL NULL +3 2 3 0 +4 3 4 1 +6 5 6 4 +8 7 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t2.b > t1.a OR t1.a > t1.b; +a b a b +2 1 NULL NULL +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +8 7 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a != t2.a AND t1.a BETWEEN t2.b AND t1.b); +a b a b +2 1 NULL NULL +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +8 7 NULL NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a AND (t2.b > t1.a OR t1.a > t1.b); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a != t2.a OR t1.a BETWEEN t2.b AND t1.b); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b; +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a NOT IN(t2.a, t2.b)); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a != t1.b AND t1.a != t2.b; +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a NOT IN(t1.b, t2.b); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t1.a IN(t1.b, t2.b)); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.a != t2.b OR (t1.a != t2.a AND t1.a != t2.b); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t2.a = t2.b AND t1.a IN(t2.a, t2.b)); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t2.a != t2.b AND t1.a != t1.b AND t1.a != t2.b; +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE NOT(t2.a = t2.b OR t1.a IN(t1.b, t2.b)); +a b a b +3 2 3 0 +4 3 4 1 +6 5 6 4 +7 8 7 5 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a = t2.a OR t1.a = t2.b; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a IN(t2.a, t2.b); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a WHERE t1.a > IF(t1.a = t2.b-2, t2.b, t2.b-1); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ALL PRIMARY NULL NULL NULL 4 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.a 1 +DROP TABLE t1,t2; +DROP VIEW IF EXISTS v1,v2; +DROP TABLE IF EXISTS t1,t2; +CREATE TABLE t1 (a int); +CREATE table t2 (b int); +INSERT INTO t1 VALUES (1), (2), (3), (4), (1), (1), (3); +INSERT INTO t2 VALUES (2), (3); +CREATE VIEW v1 AS SELECT a FROM t1 JOIN t2 ON t1.a=t2.b; +CREATE VIEW v2 AS SELECT b FROM t2 JOIN t1 ON t2.b=t1.a; +SELECT v1.a, v2. b +FROM v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) +GROUP BY v1.a; +a b +2 NULL +3 3 +SELECT v1.a, v2. b +FROM { OJ v1 LEFT OUTER JOIN v2 ON (v1.a=v2.b) AND (v1.a >= 3) } +GROUP BY v1.a; +a b +2 NULL +3 3 +DROP VIEW v1,v2; +DROP TABLE t1,t2; +CREATE TABLE t1 (a int); +CREATE TABLE t2 (b int); +INSERT INTO t1 VALUES (1), (2), (3), (4); +INSERT INTO t2 VALUES (2), (3); +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1 OR 1); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (0 OR 1); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 2=2); +a b +1 NULL +2 2 +3 3 +4 NULL +SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.b WHERE (1=1 OR 1=0); +a b +1 NULL +2 2 +3 3 +4 NULL +DROP TABLE t1,t2; +CREATE TABLE t1 ( +f1 varchar(16) collate latin1_swedish_ci PRIMARY KEY, +f2 varchar(16) collate latin1_swedish_ci +); +CREATE TABLE t2 ( +f1 varchar(16) collate latin1_swedish_ci PRIMARY KEY, +f3 varchar(16) collate latin1_swedish_ci +); +INSERT INTO t1 VALUES ('bla','blah'); +INSERT INTO t2 VALUES ('bla','sheep'); +SELECT * FROM t1 JOIN t2 USING(f1) WHERE f1='Bla'; +f1 f2 f3 +bla blah sheep +SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='bla'; +f1 f2 f3 +bla blah sheep +SELECT * FROM t1 LEFT JOIN t2 USING(f1) WHERE f1='Bla'; +f1 f2 f3 +bla blah sheep +DROP TABLE t1,t2; +CREATE TABLE t1 (id int PRIMARY KEY, a varchar(8)); +CREATE TABLE t2 (id int NOT NULL, b int NOT NULL, INDEX idx(id)); +INSERT INTO t1 VALUES +(1,'aaaaaaa'), (5,'eeeeeee'), (4,'ddddddd'), (2,'bbbbbbb'), (3,'ccccccc'); +INSERT INTO t2 VALUES +(3,10), (2,20), (5,30), (3,20), (5,10), (3,40), (3,30), (2,10), (2,40); +EXPLAIN +SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 5 +1 SIMPLE t2 ref idx idx 4 test.t1.id 1 Using where; Not exists +flush status; +SELECT t1.id, a FROM t1 LEFT JOIN t2 ON t1.id=t2.id WHERE t2.b IS NULL; +id a +1 aaaaaaa +4 ddddddd +show status like 'Handler_read%'; +Variable_name Value +Handler_read_first 0 +Handler_read_key 5 +Handler_read_last 0 +Handler_read_next 0 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 6 +DROP TABLE t1,t2; +CREATE TABLE t1 (c int PRIMARY KEY, e int NOT NULL); +INSERT INTO t1 VALUES (1,0), (2,1); +CREATE TABLE t2 (d int PRIMARY KEY); +INSERT INTO t2 VALUES (1), (2), (3); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using where; Using index; Not exists +SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d IS NULL; +c e d +1 0 NULL +SELECT * FROM t1 LEFT JOIN t2 ON e<>0 WHERE c=1 AND d<=>NULL; +c e d +1 0 NULL +DROP TABLE t1,t2; +# +# Bug#47650: using group by with rollup without indexes returns incorrect +# results with where +# +CREATE TABLE t1 ( a INT ); +INSERT INTO t1 VALUES (1); +CREATE TABLE t2 ( a INT, b INT ); +INSERT INTO t2 VALUES (1, 1),(1, 2),(1, 3),(2, 4),(2, 5); +EXPLAIN +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 LEFT JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary; Using filesort +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 LEFT JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b ) +1 3 6 3 +NULL 3 6 3 +EXPLAIN +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where; Using filesort +SELECT t1.a, COUNT( t2.b ), SUM( t2.b ), MAX( t2.b ) +FROM t1 JOIN t2 USING( a ) +GROUP BY t1.a WITH ROLLUP; +a COUNT( t2.b ) SUM( t2.b ) MAX( t2.b ) +1 3 6 3 +NULL 3 6 3 +DROP TABLE t1, t2; +# +# Bug#51598 Inconsistent behaviour with a COALESCE statement inside an IN comparison +# +CREATE TABLE t1(f1 INT, f2 INT, f3 INT); +INSERT INTO t1 VALUES (1, NULL, 3); +CREATE TABLE t2(f1 INT, f2 INT); +INSERT INTO t2 VALUES (2, 1); +EXPLAIN EXTENDED SELECT * FROM t1 LEFT JOIN t2 ON t1.f2 = t2.f2 +WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +1 SIMPLE t2 system NULL NULL NULL NULL 1 100.00 +Warnings: +Note 1003 select 1 AS `f1`,NULL AS `f2`,3 AS `f3`,NULL AS `f1`,NULL AS `f2` from `test`.`t2` where 1 +SELECT * FROM t1 LEFT JOIN t2 ON t1.f2 = t2.f2 +WHERE (COALESCE(t1.f1, t2.f1), f3) IN ((1, 3), (2, 2)); +f1 f2 f3 f1 f2 +1 NULL 3 NULL NULL +DROP TABLE t1, t2; +# +# Bug#52357: Assertion failed: join->best_read in greedy_search +# optimizer_search_depth=0 +# +CREATE TABLE t1( a INT ); +INSERT INTO t1 VALUES (1),(2); +SET optimizer_search_depth = 0; +# Should not core dump on query preparation +EXPLAIN +SELECT 1 +FROM t1 tt3 LEFT OUTER JOIN t1 tt4 ON 1 +LEFT OUTER JOIN t1 tt5 ON 1 +LEFT OUTER JOIN t1 tt6 ON 1 +LEFT OUTER JOIN t1 tt7 ON 1 +LEFT OUTER JOIN t1 tt8 ON 1 +RIGHT OUTER JOIN t1 tt2 ON 1 +RIGHT OUTER JOIN t1 tt1 ON 1 +STRAIGHT_JOIN t1 tt9 ON 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE tt1 ALL NULL NULL NULL NULL 2 +1 SIMPLE tt2 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt3 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt4 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt5 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt6 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt7 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt8 ALL NULL NULL NULL NULL 2 Using where +1 SIMPLE tt9 ALL NULL NULL NULL NULL 2 Using join buffer (flat, BNL join) +SET optimizer_search_depth = DEFAULT; +DROP TABLE t1; +# +# Bug#46091 STRAIGHT_JOIN + RIGHT JOIN returns different result +# +CREATE TABLE t1 (f1 INT NOT NULL); +INSERT INTO t1 VALUES (9),(0); +CREATE TABLE t2 (f1 INT NOT NULL); +INSERT INTO t2 VALUES +(5),(3),(0),(3),(1),(0),(1),(7),(1),(0),(0),(8),(4),(9),(0),(2),(0),(8),(5),(1); +SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1 +RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1; +COUNT(*) +476 +EXPLAIN SELECT STRAIGHT_JOIN COUNT(*) FROM t1 TA1 +RIGHT JOIN t2 TA2 JOIN t2 TA3 ON TA2.f1 ON TA3.f1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE TA2 ALL NULL NULL NULL NULL 20 Using where +1 SIMPLE TA3 ALL NULL NULL NULL NULL 20 Using join buffer (flat, BNL join) +1 SIMPLE TA1 ALL NULL NULL NULL NULL 2 Using where +DROP TABLE t1, t2; +# +# Bug#48971 Segfault in add_found_match_trig_cond () at sql_select.cc:5990 +# +CREATE TABLE t1(f1 INT, PRIMARY KEY (f1)); +INSERT INTO t1 VALUES (1),(2); +EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1 +LEFT JOIN t1 AS jt2 +RIGHT JOIN t1 AS jt3 +JOIN t1 AS jt4 ON 1 +LEFT JOIN t1 AS jt5 ON 1 +ON 1 +RIGHT JOIN t1 AS jt6 ON jt6.f1 +ON 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using index +1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index +1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +Warnings: +Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt1` left join (`test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on(`test`.`jt6`.`f1` is true and 1)) on(1) where 1 +EXPLAIN EXTENDED SELECT STRAIGHT_JOIN jt1.f1 FROM t1 AS jt1 +RIGHT JOIN t1 AS jt2 +RIGHT JOIN t1 AS jt3 +JOIN t1 AS jt4 ON 1 +LEFT JOIN t1 AS jt5 ON 1 +ON 1 +RIGHT JOIN t1 AS jt6 ON jt6.f1 +ON 1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE jt6 index NULL PRIMARY 4 NULL 2 100.00 Using index +1 SIMPLE jt3 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +1 SIMPLE jt4 index NULL PRIMARY 4 NULL 2 100.00 Using index +1 SIMPLE jt5 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +1 SIMPLE jt2 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +1 SIMPLE jt1 index NULL PRIMARY 4 NULL 2 100.00 Using where; Using index +Warnings: +Note 1003 select straight_join `test`.`jt1`.`f1` AS `f1` from `test`.`t1` `jt6` left join (`test`.`t1` `jt3` join `test`.`t1` `jt4` left join `test`.`t1` `jt5` on(1) left join `test`.`t1` `jt2` on(1)) on(`test`.`jt6`.`f1` is true and 1) left join `test`.`t1` `jt1` on(1) where 1 +DROP TABLE t1; +# +# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +# +CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1)); +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2)); +INSERT INTO t1 VALUES (4); +INSERT INTO t2 VALUES (3, 3); +INSERT INTO t2 VALUES (7, 7); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using temporary; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; +f1 f1 f2 +4 NULL NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; +f1 f1 f2 +DROP TABLE t1,t2; +# +# Bug#57034 incorrect OUTER JOIN result when joined on unique key +# +CREATE TABLE t1 (pk INT PRIMARY KEY, +col_int INT, +col_int_unique INT UNIQUE KEY); +INSERT INTO t1 VALUES (1,NULL,2), (2,0,0); +CREATE TABLE t2 (pk INT PRIMARY KEY, +col_int INT, +col_int_unique INT UNIQUE KEY); +INSERT INTO t2 VALUES (1,0,1), (2,0,2); +EXPLAIN +SELECT * FROM t1 LEFT JOIN t2 +ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int +WHERE t1.pk=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 +1 SIMPLE t2 const col_int_unique col_int_unique 5 const 1 +SELECT * FROM t1 LEFT JOIN t2 +ON t1.col_int_unique = t2.col_int_unique AND t1.col_int = t2.col_int +WHERE t1.pk=1; +pk col_int col_int_unique pk col_int col_int_unique +1 NULL 2 NULL NULL NULL +DROP TABLE t1,t2; +# +# Bug#48046 Server incorrectly processing JOINs on NULL values +# +CREATE TABLE `BB` ( +`pk` int(11) NOT NULL AUTO_INCREMENT, +`time_key` time DEFAULT NULL, +`varchar_key` varchar(1) DEFAULT NULL, +`varchar_nokey` varchar(1) DEFAULT NULL, +PRIMARY KEY (`pk`), +KEY `time_key` (`time_key`), +KEY `varchar_key` (`varchar_key`) +) ENGINE=MyISAM AUTO_INCREMENT=11 DEFAULT CHARSET=latin1; +INSERT INTO `BB` VALUES (10,'18:27:58',NULL,NULL); +SELECT table1.time_key AS field1, table2.pk +FROM BB table1 LEFT JOIN BB table2 +ON table2.varchar_nokey = table1.varchar_key +HAVING field1; +field1 pk +18:27:58 NULL +DROP TABLE BB; +# +# Bug#49600 Server incorrectly processing RIGHT JOIN with +# constant WHERE clause and no index +# +CREATE TABLE `BB` ( +`col_datetime_key` datetime DEFAULT NULL, +`col_varchar_key` varchar(1) DEFAULT NULL, +`col_varchar_nokey` varchar(1) DEFAULT NULL, +KEY `col_datetime_key` (`col_datetime_key`), +KEY `col_varchar_key` (`col_varchar_key`) +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +INSERT INTO `BB` VALUES ('1900-01-01 00:00:00',NULL,NULL); +SELECT table1.col_datetime_key +FROM BB table1 RIGHT JOIN BB table2 +ON table2 .col_varchar_nokey = table1.col_varchar_key +WHERE 7; +col_datetime_key +NULL +ALTER TABLE BB DISABLE KEYS; +SELECT table1.col_datetime_key +FROM BB table1 RIGHT JOIN BB table2 +ON table2 .col_varchar_nokey = table1.col_varchar_key +WHERE 7; +col_datetime_key +NULL +DROP TABLE BB; +# +# Bug#58490: Incorrect result in multi level OUTER JOIN +# in combination with IS NULL +# +CREATE TABLE t1 (i INT NOT NULL); +INSERT INTO t1 VALUES (0), (2),(3),(4); +CREATE TABLE t2 (i INT NOT NULL); +INSERT INTO t2 VALUES (0),(1), (3),(4); +CREATE TABLE t3 (i INT NOT NULL); +INSERT INTO t3 VALUES (0),(1),(2), (4); +CREATE TABLE t4 (i INT NOT NULL); +INSERT INTO t4 VALUES (0),(1),(2),(3) ; +SELECT * FROM +t1 LEFT JOIN +( t2 LEFT JOIN +( t3 LEFT JOIN +t4 +ON t4.i = t3.i +) +ON t3.i = t2.i +) +ON t2.i = t1.i +; +i i i i +0 0 0 0 +2 NULL NULL NULL +3 3 NULL NULL +4 4 4 NULL +SELECT * FROM +t1 LEFT JOIN +( t2 LEFT JOIN +( t3 LEFT JOIN +t4 +ON t4.i = t3.i +) +ON t3.i = t2.i +) +ON t2.i = t1.i +WHERE t4.i IS NULL; +i i i i +2 NULL NULL NULL +3 3 NULL NULL +4 4 4 NULL +SELECT * FROM +t1 LEFT JOIN +( ( t2 LEFT JOIN +t3 +ON t3.i = t2.i +) +) +ON t2.i = t1.i +WHERE t3.i IS NULL; +i i i +2 NULL NULL +3 3 NULL +SELECT * FROM +t1 LEFT JOIN +( ( t2 LEFT JOIN +t3 +ON t3.i = t2.i +) +JOIN t4 +ON t4.i=t2.i +) +ON t2.i = t1.i +WHERE t3.i IS NULL; +i i i i +2 NULL NULL NULL +3 3 NULL 3 +4 NULL NULL NULL +SELECT * FROM +t1 LEFT JOIN +( ( t2 LEFT JOIN +t3 +ON t3.i = t2.i +) +JOIN (t4 AS t4a JOIN t4 AS t4b ON t4a.i=t4b.i) +ON t4a.i=t2.i +) +ON t2.i = t1.i +WHERE t3.i IS NULL; +i i i i i +2 NULL NULL NULL NULL +3 3 NULL 3 3 +4 NULL NULL NULL NULL +SELECT * FROM +t1 LEFT JOIN +( ( t2 LEFT JOIN +t3 +ON t3.i = t2.i +) +JOIN (t4 AS t4a, t4 AS t4b) +ON t4a.i=t2.i +) +ON t2.i = t1.i +WHERE t3.i IS NULL; +i i i i i +2 NULL NULL NULL NULL +3 3 NULL 3 0 +3 3 NULL 3 1 +3 3 NULL 3 2 +3 3 NULL 3 3 +4 NULL NULL NULL NULL +DROP TABLE t1,t2,t3,t4; +# +# Bug#49322(Duplicate): Server is adding extra NULL row +# on processing a WHERE clause +# +CREATE TABLE h (pk INT NOT NULL, col_int_key INT); +INSERT INTO h VALUES (1,NULL),(4,2),(5,2),(3,4),(2,8); +CREATE TABLE m (pk INT NOT NULL, col_int_key INT); +INSERT INTO m VALUES (1,2),(2,7),(3,5),(4,7),(5,5),(6,NULL),(7,NULL),(8,9); +CREATE TABLE k (pk INT NOT NULL, col_int_key INT); +INSERT INTO k VALUES (1,9),(2,2),(3,5),(4,2),(5,7),(6,0),(7,5); +SELECT TABLE1.pk FROM k TABLE1 +RIGHT JOIN h TABLE2 ON TABLE1.col_int_key=TABLE2.col_int_key +RIGHT JOIN m TABLE4 ON TABLE2.col_int_key=TABLE4.col_int_key; +pk +2 +2 +4 +4 +NULL +NULL +NULL +NULL +NULL +NULL +NULL +SELECT TABLE1.pk FROM k TABLE1 +RIGHT JOIN h TABLE2 ON TABLE1.col_int_key=TABLE2.col_int_key +RIGHT JOIN m TABLE4 ON TABLE2.col_int_key=TABLE4.col_int_key +WHERE TABLE1.pk IS NULL; +pk +NULL +NULL +NULL +NULL +NULL +NULL +NULL +DROP TABLE h,m,k; + +# BUG#12567331 - INFINITE LOOP WHEN RESOLVING AN ALIASED COLUMN +# USED IN GROUP BY + +CREATE TABLE t1 ( +col_varchar_1024_latin1_key varchar(1024), +col_varchar_10_latin1 varchar(10), +col_int int(11), +pk int(11) +); +CREATE TABLE t2 ( +col_int_key int(11), +col_int int(11), +pk int(11) +); +PREPARE prep_stmt_9846 FROM ' +SELECT alias1.pk AS field1 FROM +t1 AS alias1 +LEFT JOIN +( + t2 AS alias2 + RIGHT JOIN + ( + t2 AS alias3 + JOIN t1 AS alias4 + ON 1 + ) + ON 1 +) +ON 1 +GROUP BY field1'; +execute prep_stmt_9846; +field1 +execute prep_stmt_9846; +field1 +drop table t1,t2; +# +# Bug #11765810 58813: SERVER THREAD HANGS WHEN JOIN + WHERE + GROUP BY +# IS EXECUTED TWICE FROM P +# +CREATE TABLE t1 ( a INT ) ENGINE = MYISAM; +INSERT INTO t1 VALUES (1); +PREPARE prep_stmt FROM ' + SELECT 1 AS f FROM t1 + LEFT JOIN t1 t2 + RIGHT JOIN t1 t3 + JOIN t1 t4 + ON 1 + ON 1 + ON 1 + GROUP BY f'; +EXECUTE prep_stmt; +f +1 +EXECUTE prep_stmt; +f +1 +DROP TABLE t1; +# +# Bug#49600: outer join of two single-row tables with joining attributes +# evaluated to nulls +create table t1 (a int, b int); +create table t2 (a int, b int); +insert into t1 values (1, NULL); +insert into t2 values (2, NULL); +select * from t1 left join t2 on t1.b=t2.b; +a b a b +1 NULL NULL NULL +select * from t1 left join t2 on t1.b=t2.b where 1=1; +a b a b +1 NULL NULL NULL +drop table t1,t2; +# +# Bug#53161: outer join in the derived table is erroneously converted +# into an inner join for a query with a group by clause +# +create table t1 (pk int not null primary key, a int not null); +create table t2 like t1; +create table t3 like t1; +create table t4 (pk int not null primary key); +insert into t1 values (1000, 1), (1001, 1); +insert into t2 values (2000, 2), (2001, 2); +insert into t3 values (3000, 3), (3001, 2); +insert into t4 values (4000), (4001); +explain extended +select t2.pk, +(select t3.pk+if(isnull(t4.pk),0,t4.pk) +from t3 left join t4 on t4.pk=t3.pk +where t3.pk=t2.pk+1000 limit 1 ) as t +from t1,t2 +where t2.pk=t1.pk+1000 and t1.pk>1000 +group by t2.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 range PRIMARY PRIMARY 4 NULL 1 100.00 Using where; Using index; Using temporary; Using filesort +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t3 eq_ref PRIMARY PRIMARY 4 func 1 100.00 Using where; Using index +2 DEPENDENT SUBQUERY t4 eq_ref PRIMARY PRIMARY 4 test.t3.pk 1 100.00 Using index +Warnings: +Note 1276 Field or reference 'test.t2.pk' of SELECT #2 was resolved in SELECT #1 +Note 1003 /* select#1 */ select `test`.`t2`.`pk` AS `pk`,<`test`.`t2`.`pk`>((/* select#2 */ select `test`.`t3`.`pk` + if(`test`.`t4`.`pk` is null,0,`test`.`t4`.`pk`) from `test`.`t3` left join `test`.`t4` on(`test`.`t4`.`pk` = `test`.`t3`.`pk`) where `test`.`t3`.`pk` = `test`.`t2`.`pk` + 1000 limit 1)) AS `t` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`pk` = `test`.`t1`.`pk` + 1000 and `test`.`t1`.`pk` > 1000 group by `test`.`t2`.`pk` +select t2.pk, +(select t3.pk+if(isnull(t4.pk),0,t4.pk) +from t3 left join t4 on t4.pk=t3.pk +where t3.pk=t2.pk+1000 limit 1 ) as t +from t1,t2 +where t2.pk=t1.pk+1000 and t1.pk>1000 +group by t2.pk; +pk t +2001 3001 +drop table t1,t2,t3,t4; +# +# Bug#57024: Poor performance when conjunctive condition over the outer +# table is used in the on condition of an outer join +# +create table t1 (a int); +insert into t1 values (NULL), (NULL), (NULL), (NULL); +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 select * from t1; +insert into t1 values (4), (2), (1), (3); +create table t2 like t1; +insert into t2 select if(t1.a is null, 10, t1.a) from t1; +create table t3 (a int, b int, index idx(a)); +insert into t3 values (1, 100), (3, 301), (4, 402), (1, 102), (1, 101); +insert into t3 values (11, 100), (33, 301), (44, 402), (11, 102), (11, 101); +insert into t3 values (22, 100), (53, 301), (64, 402), (22, 102), (22, 101); +analyze table t1,t2,t3; +Table Op Msg_type Msg_text +test.t1 analyze status Engine-independent statistics collected +test.t1 analyze status OK +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +flush status; +select sum(t3.b) from t1 left join t3 on t3.a=t1.a and t1.a is not null; +sum(t3.b) +1006 +show status like "handler_read%"; +Variable_name Value +Handler_read_first 0 +Handler_read_key 4 +Handler_read_last 0 +Handler_read_next 5 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 1048581 +flush status; +select sum(t3.b) from t2 left join t3 on t3.a=t2.a and t2.a <> 10; +sum(t3.b) +1006 +show status like "handler_read%"; +Variable_name Value +Handler_read_first 0 +Handler_read_key 4 +Handler_read_last 0 +Handler_read_next 5 +Handler_read_prev 0 +Handler_read_retry 0 +Handler_read_rnd 0 +Handler_read_rnd_deleted 0 +Handler_read_rnd_next 1048581 +drop table t1,t2,t3; +# +# Bug#57688 Assertion `!table || (!table->write_set || bitmap_is_set(table->write_set, field +# +CREATE TABLE t1 (f1 INT NOT NULL, PRIMARY KEY (f1)); +CREATE TABLE t2 (f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY (f1, f2)); +INSERT INTO t1 VALUES (4); +INSERT INTO t2 VALUES (3, 3); +INSERT INTO t2 VALUES (7, 7); +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 Using temporary; Using filesort +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using index +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 +GROUP BY t2.f1, t2.f2; +f1 f1 f2 +4 NULL NULL +EXPLAIN SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system PRIMARY NULL NULL NULL 1 +1 SIMPLE t2 ref PRIMARY PRIMARY 4 const 1 Using where; Using index +SELECT * FROM t1 LEFT JOIN t2 ON t2.f1 = t1.f1 +WHERE t1.f1 = 4 AND t2.f1 IS NOT NULL AND t2.f2 IS NOT NULL +GROUP BY t2.f1, t2.f2; +f1 f1 f2 +DROP TABLE t1,t2; +# +# Bug#13068506 - QUERY WITH GROUP BY ON NON-AGGR COLUMN RETURNS +# WRONG RESULT +# +CREATE TABLE t1 (i1 int); +INSERT INTO t1 VALUES (100), (101); +CREATE TABLE t2 (i2 int, i3 int); +INSERT INTO t2 VALUES (20,1),(10,2); +CREATE TABLE t3 (i4 int(11)); +INSERT INTO t3 VALUES (1),(2); + +SELECT ( +SELECT MAX( t2.i2 ) +FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 ) +WHERE t2.i3 <> t1.i1 +) AS field1 +FROM t1;; +field1 +20 +20 + +SELECT ( +SELECT MAX( t2.i2 ) +FROM t3 RIGHT JOIN t2 ON ( t2.i3 = 2 ) +WHERE t2.i3 <> t1.i1 +) AS field1 +FROM t1 GROUP BY field1;; +field1 +20 + +drop table t1,t2,t3; +# End of test for Bug#13068506 +End of 5.1 tests +# +# LP BUG#994392: Wrong result with RIGHT/LEFT JOIN and ALL subquery +# predicate in WHERE condition. +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(9); +CREATE TABLE t2(b INT); +INSERT INTO t2 VALUES(8); +CREATE TABLE t3(c INT); +INSERT INTO t3 VALUES(3); +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +b c +NULL 3 +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b < ALL(SELECT a FROM t1 WHERE a <= 7); +c b +3 NULL +SELECT * FROM t2 RIGHT JOIN t3 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +b c +NULL 3 +SELECT * FROM t3 LEFT JOIN t2 ON(c = b) WHERE b not in (SELECT a FROM t1 WHERE a <= 7); +c b +3 NULL +drop table t1,t2,t3; +End of 5.2 tests +# +# LP bug #813447: LEFT JOIN with single-row inner table and +# a subquery in ON expression +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 (a int); +INSERT INTO t2 VALUES (0); +CREATE TABLE t3 (a int); +INSERT INTO t3 VALUES (0), (0); +SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3); +a +NULL +EXPLAIN EXTENDED +SELECT t2.a FROM t1 LEFT JOIN t2 ON (6) IN (SELECT a FROM t3); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 100.00 +1 PRIMARY t2 system NULL NULL NULL NULL 1 100.00 +2 SUBQUERY t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 /* select#1 */ select NULL AS `a` from `test`.`t2` where 1 +DROP TABLE t1,t2,t3; +# +# LP bug #817384 Wrong result with outer join + subquery in ON +# clause +unique key +# +CREATE TABLE t1 ( c int NOT NULL , b char(1) NOT NULL ) ; +INSERT INTO t1 VALUES (1,'b'); +CREATE TABLE t2 ( a int NOT NULL , b char(1) NOT NULL , PRIMARY KEY (a)) ; +INSERT INTO t2 VALUES (1,'a'); +create table t3 (c1 char(1), c2 char(2)); +insert into t3 values ('c','d'); +insert into t3 values ('c','d'); +EXPLAIN SELECT t2.b +FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY t2 eq_ref PRIMARY PRIMARY 4 const 1 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +SELECT t2.b +FROM t1 LEFT JOIN t2 ON t1.c = t2.a AND ( t2.b , t1.b ) IN (SELECT * from t3); +b +NULL +EXPLAIN SELECT t2.b +FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY t1 system NULL NULL NULL NULL 1 +1 PRIMARY t2 const PRIMARY PRIMARY 4 const 1 Using where +2 DEPENDENT SUBQUERY t3 ALL NULL NULL NULL NULL 2 Using where +SELECT t2.b +FROM t1 LEFT JOIN t2 ON (t2.b) IN (SELECT c2 from t3) AND t2.a = 1; +b +NULL +DROP TABLE t1,t2,t3; +# +# lp:825035 second execution of PS with outer join +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1),(2),(3),(4); +CREATE TABLE t2 (a int); +PREPARE stmt FROM +"SELECT * FROM t1 LEFT JOIN t2 ON t1.a = t2.a"; +EXECUTE stmt; +a a +1 NULL +2 NULL +3 NULL +4 NULL +EXECUTE stmt; +a a +1 NULL +2 NULL +3 NULL +4 NULL +DEALLOCATE PREPARE stmt; +DROP TABLE t1,t2; +# +# lp:838633 second execution of PS with outer join +# converted to inner join +# +CREATE TABLE t1 ( b int NOT NULL ) ; +INSERT INTO t1 VALUES (9),(10); +CREATE TABLE t2 ( b int NOT NULL, PRIMARY KEY (b)) ; +INSERT INTO t2 VALUES +(75),(76),(77),(78),(79),(80),(81),(82),(83),(84),(85),(86),(87),(88),(89), +(10), (90),(91),(92),(93),(94),(95),(96),(97),(98),(99),(100); +CREATE TABLE t3 ( a int, b int NOT NULL , PRIMARY KEY (b)) ; +INSERT INTO t3 VALUES +(0,6),(0,7),(0,8),(2,9),(0,10),(2,21),(0,22),(2,23),(2,24),(2,25); +set @save_join_cache_level= @@join_cache_level; +SET SESSION join_cache_level=4; +EXPLAIN EXTENDED +SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 hash_index PRIMARY #hash#PRIMARY:PRIMARY 4:4 test.t1.b 27 3.70 Using index; Using join buffer (flat, BNLH join) +1 SIMPLE t3 hash_ALL PRIMARY #hash#PRIMARY 4 test.t1.b 10 10.00 Using join buffer (incremental, BNLH join) +Warnings: +Note 1003 select `test`.`t2`.`b` AS `b`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t2` join `test`.`t1` join `test`.`t3` where `test`.`t2`.`b` = `test`.`t1`.`b` and `test`.`t3`.`b` = `test`.`t1`.`b` +PREPARE stmt FROM +'SELECT * FROM (t2 LEFT JOIN t1 ON t1.b = t2.b) JOIN t3 ON t1.b = t3.b'; +EXECUTE stmt; +b b a b +10 10 0 10 +EXECUTE stmt; +b b a b +10 10 0 10 +DEALLOCATE PREPARE stmt; +SET SESSION join_cache_level=@save_join_cache_level; +DROP TABLE t1,t2,t3; +# +# LP bug #943543: LEFT JOIN converted to JOIN with +# ORed IS NULL(primary key) in WHERE clause +# +CREATE TABLE t1 ( +a int, b int NOT NULL, pk int NOT NULL, +PRIMARY KEY (pk), INDEX idx(b) +); +INSERT INTO t1 VALUES +(NULL,1,1), (6,2,2), (5,3,3), (NULL,4,4), +(1,9,6), (8,5,7), (NULL,8,8), (8,1,5); +CREATE TABLE t2 (pk int PRIMARY KEY); +INSERT INTO t2 VALUES (3), (8), (5); +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 100.00 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index +Warnings: +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5 +SELECT t1.pk FROM t2 JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +pk +5 +EXPLAIN EXTENDED +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 const PRIMARY,idx PRIMARY 4 const 1 100.00 +1 SIMPLE t2 const PRIMARY PRIMARY 4 const 1 100.00 Using index +Warnings: +Note 1003 select 5 AS `pk` from `test`.`t2` join `test`.`t1` where 1 order by 5 +SELECT t1.pk FROM t2 LEFT JOIN t1 ON t2.pk = t1.a +WHERE t1.b BETWEEN 5 AND 6 AND t1.pk IS NULL OR t1.pk = 5 +ORDER BY t1.pk; +pk +5 +DROP TABLE t2; +CREATE TABLE t2 (c int, d int, KEY (c)); +INSERT INTO t2 VALUES +(3,30), (8,88), (5,50), (8,81), +(4,40), (9,90), (7,70), (9,90), +(13,130), (18,188), (15,150), (18,181), +(14,140), (19,190), (17,170), (19,190); +INSERT INTO t1 VALUES (8,5,9); +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref idx idx 4 const 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` +SELECT t1.b, t2.c, t2.d FROM t2 JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +b c d +5 8 88 +5 8 81 +5 8 88 +5 8 81 +EXPLAIN EXTENDED +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ref PRIMARY,idx idx 4 const 2 100.00 Using where +1 SIMPLE t2 ref c c 5 test.t1.a 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`b` AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t2`.`d` AS `d` from `test`.`t2` join `test`.`t1` where `test`.`t2`.`c` = `test`.`t1`.`a` and `test`.`t1`.`b` = 5 order by `test`.`t1`.`b` +SELECT t1.b, t2.c, t2.d FROM t2 LEFT JOIN t1 ON t2.c = t1.a +WHERE t1.pk BETWEEN 5 AND 6 AND t1.b IS NULL OR t1.b = 5 +ORDER BY t1.b; +b c d +5 8 88 +5 8 81 +5 8 88 +5 8 81 +DROP TABLE t1,t2; +# +# Bug mdev-4336: LEFT JOIN with disjunctive +# IS NULL in WHERE +# causes a hang and eventual crash +# +CREATE TABLE t1 ( +id int(11) NOT NULL, +modified datetime NOT NULL, +PRIMARY KEY (id) +); +SELECT a.* FROM t1 a LEFT JOIN t1 b ON a.id = b.id +WHERE a.modified > b.modified or b.modified IS NULL; +id modified +DROP TABLE t1; +# +# MDEV-4817: Optimizer fails to optimize expression of the form 'FOO' IS NULL +# +create table t0 (a int not null); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +alter table t0 add person_id varchar(255) not null; +create table t1 (pk int not null primary key); +insert into t1 select A.a + 10*B.a from t0 A, t0 B; +explain select * from t1 left join t0 on t0.a=t1.pk where t0.person_id='fooo' or 'xyz' IS NULL; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index +explain select * from t1 left join t0 on t0.a=t1.pk where t0.person_id='fooo'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index +explain select * from t1 left join t0 on t0.a=t1.pk where t0.person_id='fooo' or t0.person_id='bar'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t0.a 1 Using index +drop table t0, t1; +# +# MDEV-4836: Wrong result on IS NULL (old documented hack stopped working) +# (this is a regression after fix for MDEV-4817) +# +CREATE TABLE t1 (id INT, d DATE NOT NULL); +INSERT INTO t1 VALUES (1,'0000-00-00'),(2,'0000-00-00'); +CREATE TABLE t2 (i INT); +SELECT * FROM t1 LEFT JOIN t2 ON (id=i) WHERE NULL OR d IS NULL; +id d i +1 0000-00-00 NULL +2 0000-00-00 NULL +DROP TABLE t1,t2; +CREATE TABLE t1 (i1 INT, d1 DATE NOT NULL); +INSERT INTO t1 VALUES (1,'2012-12-21'),(2,'0000-00-00'); +CREATE TABLE t2 (i2 INT, j2 INT); +INSERT INTO t2 VALUES (1,10),(2,20); +SELECT * FROM t1 LEFT JOIN t2 ON i1 = j2 WHERE d1 IS NULL AND 1 OR i1 = i2; +i1 d1 i2 j2 +2 0000-00-00 NULL NULL +DROP TABLE t1,t2; +# Another testcase +CREATE TABLE t1 (i1 INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (NULL); +CREATE TABLE t2 (i2 INT, a INT, b INT) ENGINE=MyISAM; +CREATE ALGORITHM=TEMPTABLE VIEW v2 AS SELECT * FROM t2; +INSERT INTO t2 VALUES (NULL,1,2),(NULL,2,3); +SELECT * FROM t1 LEFT JOIN v2 ON i1 = i2 WHERE a < b; +i1 i2 a b +SELECT * FROM t1 LEFT JOIN t2 ON i1 = i2 WHERE a < b; +i1 i2 a b +drop view v2; +drop table t1,t2; +# +# Bug mdev-4942: LEFT JOIN with conjunctive +# IS NULL in WHERE +# causes an assert failure +# +CREATE TABLE t1 ( i1 int, d1 date ); +INSERT INTO t1 VALUES (1,'2001-06-26'), (2,'2000-11-16'); +CREATE TABLE t2 ( i2 int, d2 date NOT NULL ); +INSERT INTO t2 VALUES (3,'2000-03-06'), (4,'2007-09-25'); +SELECT * FROM t1 LEFT JOIN t2 ON i1 = i2 WHERE d1 IS NULL AND d2 IS NULL; +i1 d1 i2 d2 +DROP TABLE t1,t2; +# +# Bug mdev-4952: LEFT JOIN with disjunctive +# IS NULL in WHERE +# causes an assert failure +# +CREATE TABLE t1 (a1 int, b1 int NOT NULL) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1, 10), (2, 11); +CREATE TABLE t2 (dt datetime NOT NULL, a2 int, b2 int) ENGINE=MyISAM; +INSERT INTO t2 VALUES +('2006-10-08 09:34:54', 1, 100), ('2001-01-19 01:04:43', 2, 200); +SELECT * FROM t1 LEFT JOIN t2 ON a1 = a2 +WHERE ( dt IS NULL OR FALSE ) AND b2 IS NULL; +a1 b1 dt a2 b2 +DROP TABLE t1,t2; +# +# Bug mdev-4962: nested outer join with +# IS NULL in WHERE +# causes an assert failure +# +CREATE TABLE t1 (i1 int) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (i2 int) ENGINE=MyISAM; +INSERT INTO t2 VALUES (10),(20); +CREATE TABLE t3 (i3 int, d3 datetime NOT NULL) ENGINE=MyISAM; +INSERT INTO t3 VALUES (8,'2008-12-04 17:53:42'),(9,'2012-12-21 12:12:12'); +SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3 +WHERE d3 IS NULL; +i1 i2 i3 d3 +1 NULL NULL NULL +2 NULL NULL NULL +EXPLAIN EXTENDED +SELECT * FROM t1 LEFT JOIN t2 LEFT JOIN t3 ON i2 = i3 ON i1 = i3 +WHERE d3 IS NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t2`.`i2` AS `i2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`d3` AS `d3` from `test`.`t1` left join (`test`.`t2` join `test`.`t3`) on(`test`.`t2`.`i2` = `test`.`t1`.`i1` and `test`.`t3`.`i3` = `test`.`t1`.`i1`) where `test`.`t3`.`d3` = 0 or `test`.`t3`.`d3` is null +DROP TABLE t1,t2,t3; +# +# Bug mdev-6705: wrong on expression after constant row substitution +# that triggers a simplification of WHERE condition +# +CREATE TABLE t1 (a int, b int) ENGINE=MyISAM; +INSERT INTO t1 VALUES (10,8); +CREATE TABLE t2 (c int) ENGINE=MyISAM; +INSERT INTO t2 VALUES (8),(9); +CREATE TABLE t3 (d int) ENGINE=MyISAM; +INSERT INTO t3 VALUES (3),(8); +EXPLAIN EXTENDED +SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a +WHERE b IN (1,2,3) OR b = d; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select 10 AS `a`,8 AS `b`,`test`.`t2`.`c` AS `c`,`test`.`t3`.`d` AS `d` from `test`.`t2` left join `test`.`t3` on(`test`.`t3`.`d` = 10) where `test`.`t2`.`c` = 8 and `test`.`t3`.`d` = 8 +SELECT * FROM t1 INNER JOIN t2 ON c = b LEFT JOIN t3 ON d = a +WHERE b IN (1,2,3) OR b = d; +a b c d +DROP TABLE t1,t2,t3; +# +# MDEV-6634: Wrong estimates for ref(const) and key IS NULL predicate +# +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (a int, b int, c int, key(b), key(c)); +insert into t2 select +@a:=A.a + 10*B.a+100*C.a, +IF(@a<900, NULL, @a), +IF(@a<400, NULL, @a) +from t1 A, t1 B, t1 C; +delete from t1 where a=0; +# Check that there are different #rows of NULLs for b and c, both !=10: +explain select * from t2 force index (b) where b is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref b b 5 const 780 Using index condition +explain select * from t2 force index (c) where c is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 ref c c 5 const 282 Using index condition +explain select * from t1 left join t2 on t2.b is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 9 +1 SIMPLE t2 ALL b NULL NULL NULL 1000 Using where +explain select * from t1 left join t2 on t2.c is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 9 +1 SIMPLE t2 ALL c NULL NULL NULL 1000 Using where +drop table t1,t2; +# +# MDEV-10006: optimizer doesn't convert outer join to inner on views with WHERE clause +# +CREATE TABLE t1(i1 int primary key, v1 int, key(v1)); +INSERT INTO t1 VALUES (1, 1); +INSERT INTO t1 VALUES (2, 2); +INSERT INTO t1 VALUES (3, 3); +INSERT INTO t1 VALUES (4, 4); +INSERT INTO t1 VALUES (5, 3); +INSERT INTO t1 VALUES (6, 6); +INSERT INTO t1 VALUES (7, 7); +INSERT INTO t1 VALUES (8, 8); +INSERT INTO t1 VALUES (9, 9); +CREATE TABLE t2(i2 int primary key, v2 int, key(v2)); +INSERT INTO t2 VALUES (1, 1); +INSERT INTO t2 VALUES (2, 2); +INSERT INTO t2 VALUES (3, 3); +INSERT INTO t2 VALUES (4, 4); +INSERT INTO t2 VALUES (5, 3); +INSERT INTO t2 VALUES (6, 6); +INSERT INTO t2 VALUES (7, 7); +INSERT INTO t2 VALUES (8, 8); +INSERT INTO t2 VALUES (9, 9); +CREATE TABLE t3(i3 int primary key, v3 int, key(v3)); +INSERT INTO t3 VALUES (2, 2); +INSERT INTO t3 VALUES (4, 4); +INSERT INTO t3 VALUES (6, 6); +INSERT INTO t3 VALUES (8, 8); +# This should have a join order of t3,t1,t2 (or t3,t2,t1, the idea is that t3 is the first one) +EXPLAIN EXTENDED +SELECT * FROM +(SELECT t1.i1 as i1, t1.v1 as v1, +t2.i2 as i2, t2.v2 as v2, +t3.i3 as i3, t3.v3 as v3 +FROM t1 JOIN t2 on t1.i1 = t2.i2 +LEFT JOIN t3 on t2.i2 = t3.i3 +) as w1 +WHERE v3 = 4; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 ref PRIMARY,v3 v3 5 const 1 100.00 +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`v1` AS `v1`,`test`.`t2`.`i2` AS `i2`,`test`.`t2`.`v2` AS `v2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`v3` AS `v3` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`v3` = 4 and `test`.`t1`.`i1` = `test`.`t3`.`i3` and `test`.`t2`.`i2` = `test`.`t3`.`i3` +# This should have the same join order like the query above: +EXPLAIN EXTENDED +SELECT * FROM +(SELECT t1.i1 as i1, t1.v1 as v1, +t2.i2 as i2, t2.v2 as v2, +t3.i3 as i3, t3.v3 as v3 +FROM t1 JOIN t2 on t1.i1 = t2.i2 +LEFT JOIN t3 on t2.i2 = t3.i3 +WHERE t1.i1 = t2.i2 +AND 1 = 1 +) as w2 +WHERE v3 = 4; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t3 ref PRIMARY,v3 v3 5 const 1 100.00 +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 +1 SIMPLE t2 eq_ref PRIMARY PRIMARY 4 test.t3.i3 1 100.00 +Warnings: +Note 1003 select `test`.`t1`.`i1` AS `i1`,`test`.`t1`.`v1` AS `v1`,`test`.`t2`.`i2` AS `i2`,`test`.`t2`.`v2` AS `v2`,`test`.`t3`.`i3` AS `i3`,`test`.`t3`.`v3` AS `v3` from `test`.`t1` join `test`.`t2` join `test`.`t3` where `test`.`t3`.`v3` = 4 and `test`.`t1`.`i1` = `test`.`t3`.`i3` and `test`.`t2`.`i2` = `test`.`t3`.`i3` +drop table t1,t2,t3; +# +# MDEV-11958: LEFT JOIN with stored routine produces incorrect result +# +CREATE TABLE t (x INT); +INSERT INTO t VALUES(1),(NULL); +CREATE FUNCTION f (val INT, ret INT) RETURNS INT DETERMINISTIC RETURN IFNULL(val, ret); +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE IFNULL(t2.x,0)=0; +x x IFNULL(t2.x,0) f(t2.x,0) +NULL NULL 0 0 +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE IFNULL(t2.x,0)=0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on(`test`.`t2`.`x` = `test`.`t1`.`x`) where ifnull(`test`.`t2`.`x`,0) = 0 +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE f(t2.x,0)=0; +x x IFNULL(t2.x,0) f(t2.x,0) +NULL NULL 0 0 +explain extended +SELECT t1.x, t2.x, IFNULL(t2.x,0), f(t2.x,0) +FROM t t1 LEFT JOIN t t2 +ON t1.x = t2.x +WHERE f(t2.x,0)=0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`x` AS `x`,`test`.`t2`.`x` AS `x`,ifnull(`test`.`t2`.`x`,0) AS `IFNULL(t2.x,0)`,`f`(`test`.`t2`.`x`,0) AS `f(t2.x,0)` from `test`.`t` `t1` left join `test`.`t` `t2` on(`test`.`t2`.`x` = `test`.`t1`.`x`) where `f`(`test`.`t2`.`x`,0) = 0 +drop function f; +drop table t; +CREATE TABLE t1 ( +col1 DECIMAL(33,5) NULL DEFAULT NULL, +col2 DECIMAL(33,5) NULL DEFAULT NULL +); +CREATE TABLE t2 ( +col1 DECIMAL(33,5) NULL DEFAULT NULL, +col2 DECIMAL(33,5) NULL DEFAULT NULL, +col3 DECIMAL(33,5) NULL DEFAULT NULL +); +INSERT INTO t1 VALUES (2, 1.1), (2, 2.1); +INSERT INTO t2 VALUES (3, 3.1, 4), (1, 1, NULL); +CREATE FUNCTION f1 ( p_num DECIMAL(45,15), p_return DECIMAL(45,15)) +RETURNS decimal(33,5) +LANGUAGE SQL +DETERMINISTIC +CONTAINS SQL +SQL SECURITY INVOKER +BEGIN +IF p_num IS NULL THEN +RETURN p_return; +ELSE +RETURN p_num; +END IF; +END | +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; +col1 col1 col3 +2.00000 NULL NULL +2.00000 NULL NULL +EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE IFNULL(t2.col3,0) = 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where ifnull(`test`.`t2`.`col3`,0) = 0 +SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +col1 col1 col3 +2.00000 NULL NULL +2.00000 NULL NULL +EXPLAIN EXTENDED SELECT t1.col1, t2.col1, t2.col3 +FROM t1 LEFT OUTER JOIN t2 ON t1.col1 = t2.col2 +WHERE f1(t2.col3,0) = 0; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`col1` AS `col1`,`test`.`t2`.`col1` AS `col1`,`test`.`t2`.`col3` AS `col3` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`col2` = `test`.`t1`.`col1`) where `f1`(`test`.`t2`.`col3`,0) = 0 +DROP FUNCTION f1; +DROP TABLE t1,t2; +# +# MDEV-10397: Server crashes in key_copy with join_cache_level > 2 and join on BIT fields +# +CREATE TABLE t1 (b1 BIT NOT NULL); +INSERT INTO t1 VALUES (0),(1); +CREATE TABLE t2 (b2 BIT NOT NULL); +INSERT INTO t2 VALUES (0),(1); +set @save_join_cache_level= @@join_cache_level; +SET @@join_cache_level = 3; +SELECT t1.b1+'0' , t2.b2 + '0' FROM t1 LEFT JOIN t2 ON b1 = b2; +t1.b1+'0' t2.b2 + '0' +0 0 +1 1 +DROP TABLE t1, t2; +set @@join_cache_level= @save_join_cache_level; +# +# MDEV-14779: using left join causes incorrect results with materialization and derived tables +# +create table t1(id int); +insert into t1 values (1),(2); +create table t2(sid int, id int); +insert into t2 values (1,1),(2,2); +select * from t1 t +left join (select * from t2 where sid in (select max(sid) from t2 where 0=1 group by id)) r +on t.id=r.id ; +id sid id +1 NULL NULL +2 NULL NULL +drop table t1, t2; +# +# MDEV-16726: SELECT with STRAGHT JOIN containing NESTED RIGHT JOIN +# converted to INNER JOIN with first constant inner table +# +CREATE TABLE t1 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1), KEY v1 (v1,i1) +) engine=MyISAM; +INSERT INTO t1 VALUES +(8,3,'c','c'),(9,4,'z','z'),(10,3,'i','i'),(11,186,'x','x'), +(14,226,'m','m'),(15,133,'p','p'); +CREATE TABLE t2 ( +pk int PRIMARY KEY, i1 int, v1 varchar(1), v2 varchar(1) +) engine=MyISAM; +INSERT INTO t2 VALUES (10,6,'p','p'); +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(NULL, NULL)) where 0 order by NULL +EXPLAIN EXTENDED +SELECT STRAIGHT_JOIN t2.v2 +FROM +(t2,t1) +LEFT JOIN +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +Warnings: +Note 1003 select straight_join 'p' AS `v2` from `test`.`t1` join `test`.`t1` `tb1` left join `test`.`t1` `tb2` on(multiple equal(NULL, NULL)) where 0 order by NULL +SELECT STRAIGHT_JOIN DISTINCT t2.v2 +FROM +(t1 as tb1 LEFT JOIN t1 AS tb2 ON tb2.v1 = tb1.v2) +RIGHT JOIN +(t2,t1) +ON t1.pk = t2.pk AND t2.v2 = tb1.v1 +WHERE tb1.pk = 40 +ORDER BY tb1.i1; +v2 +DROP TABLE t1,t2; +# +# MDEV-19790 : IS NOT TRUE / IS NOT FALSE predicates over +# inner tables of outer joins +# +create table t1 (a int); +create table t2 (b int); +insert into t1 values (3), (7), (1); +insert into t2 values (7), (4), (3); +select * from t1 left join t2 on a=b; +a b +3 3 +7 7 +1 NULL +select * from t1 left join t2 on a=b where (b > 3) is not true; +a b +3 3 +1 NULL +explain extended select * from t1 left join t2 on a=b where (b > 3) is not true; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`b` = `test`.`t1`.`a`) where `test`.`t2`.`b` > 3 is not true +select * from t1 left join t2 on a=b where (b > 3) is not false; +a b +7 7 +1 NULL +explain extended select * from t1 left join t2 on a=b where (b > 3) is not false; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` left join `test`.`t2` on(`test`.`t2`.`b` = `test`.`t1`.`a`) where `test`.`t2`.`b` > 3 is not false +drop table t1,t2; +# end of 5.5 tests +# +# MDEV-19258: chained right joins all converted to inner joins +# +CREATE TABLE t1 ( +id int NOT NULL AUTO_INCREMENT, +timestamp bigint NOT NULL, +modifiedBy varchar(255) DEFAULT NULL, +PRIMARY KEY (id) +); +CREATE TABLE t2 ( +id int NOT NULL, +REV int NOT NULL, +REVTYPE tinyint DEFAULT NULL, +profile_id int DEFAULT NULL, +PRIMARY KEY (id,REV) +); +CREATE TABLE t3 ( +id int NOT NULL, +REV int NOT NULL, +person_id int DEFAULT NULL, +PRIMARY KEY (id,REV) +); +CREATE TABLE t4 ( +id int NOT NULL, +REV int NOT NULL, +PRIMARY KEY (id,REV) +); +INSERT INTO t1 VALUES +(1,1294391193890,'Cxqy$*9.kKeE'),(2,1294643906883,'rE4wqGV0gif@'), +(3,1294643927456,'L?3yt(%dY$Br'),(4,1294644343525,'WH&ObiZ$#2S4'), +(5,1294644616416,'YXnCbt?olUZ0'),(6,1294644954537,'8Npe4!(#lU@k'), +(7,1294645046659,'knc0GhXB1#ib'),(8,1294645183829,'w*oPpVfuS8^m'), +(9,1294645386701,'hwXR@3qVzrbU'),(10,1294645525982,'BeLW*Y9ndP0l'), +(11,1294645627723,'nTegib^)qZ$I'),(12,1294650860266,'u62C^Kzx3wH8'), +(13,1294657613745,'4&BkFjGa!qLg'),(14,1294660627161,')anpt312SCoh'), +(15,1294661023336,'LtJ2PX?*kTmx'),(16,1294662838066,'POGRr@?#ofpl'), +(17,1294663020989,'o.)1EOT2jnF7'),(18,1294663308065,'&TZ0F0LHE6.h'), +(19,1294664900039,'j)kSC%^In$9d'),(20,1294668904556,'97glN50)cAo.'), +(21,1294728056853,'lrKZxmw?I.Ek'),(22,1294728157174,'@P*SRg!pT.q?'), +(23,1294728327099,'W9gPrptF.)8n'),(24,1294728418481,'$q*c^sM&URd#'), +(25,1294728729620,'9*f4&bTPRtHo'),(26,1294728906014,')4VtTEnS7$oI'), +(27,1294732190003,'8dkNSPq2u3AQ'),(28,1294733205065,'SV2N6IoEf438'), +(29,1294741984927,'rBKj.0S^Ey%*'),(30,1294751748352,'j$2DvlBqk)Fw'), +(31,1294753902212,'C$N6OrEw8elz'),(32,1294758120598,'DCSVZw!rnxXq'), +(33,1294761769556,'OTS@QU8a6s5c'),(34,1294816845305,'IUE2stG0D3L5'), +(35,1294816966909,'Xd16yka.9nHe'),(36,1294817116302,'lOQHZpm%!8qb'), +(37,1294817374775,'^&pE3IhNf7ey'),(38,1294817538907,'oEn4#7C0Vhfp'), +(39,1294818482950,'bx54J*O0Va&?'),(40,1294819047024,'J%@a&1.qgdb?'), +(41,1294821826077,'C9kojr$L3Phz'),(42,1294825454458,'gG#BOnM80ZPi'), +(43,1294904129918,'F^!TrjM#zdvc'),(44,1294904254166,'Va&Tb)k0RvlM'), +(45,1294904414964,'dJjq0M6HvhR#'),(46,1294904505784,'nJmxg)ELqY(b'), +(47,1294904602835,'dhF#or$Vge!7'),(48,1294904684728,'?bIh5E3l!0em'), +(49,1294904877898,'Y*WflOdcxnk.'),(50,1294905002390,'*?H!lUgez5A.'), +(51,1294905096043,'wlEIY3n9uz!p'),(52,1294905404621,'T?qv3H6&hlQD'), +(53,1294905603922,'S@Bhys^Ti7bt'),(54,1294905788416,'KR?a5NVukz#l'), +(55,1294905993190,'A*&q4kWhED!o'),(56,1294906205254,'fT0%7z0DF6h*'), +(57,1294906319680,'LhzdW4?ivjR0'),(58,1294906424296,'h0KDlns%U*6T'), +(59,1294906623844,'b$CfB1noI6Ax'),(60,1294911258896,'#T1*LP!3$Oys'); +INSERT INTO t2 VALUES +(1,1,0,10209),(1,42480,1,10209),(1,61612,1,10209),(1,257545,1,10209), +(1,385332,1,10209),(1,1687999,1,10209),(3,1,0,10210),(3,617411,2,10210), +(4,11,0,14),(4,95149,1,10211),(4,607890,2,10211),(5,1,0,10212), +(6,1,0,10213),(6,93344,1,10213),(6,295578,1,10213),(6,295579,1,10213), +(6,295644,1,10213),(7,1,0,10214),(7,12,1,7),(7,688796,1,10214), +(7,1140433,1,10214),(7,1715227,1,10214),(8,1,0,10215),(8,74253,1,10215), +(8,93345,1,10215),(8,12,2,2),(9,1,0,10216),(9,93342,1,10216), +(9,122354,1,10216),(9,301499,2,10216),(10,11,0,5),(10,93343,1,10217), +(10,122355,1,10217),(10,123050,1,10217),(10,301500,2,10217),(11,1,0,10218), +(11,87852,1,10218),(11,605499,2,10218),(12,1,0,10219),(12,88024,1,10219), +(12,605892,2,10219),(13,1,0,10220); +INSERT INTO t3 VALUES +(1,1,300003),(1,117548,NULL),(2,1,300003),(2,117548,300006), +(3,1,300153),(3,117548,NULL),(4,1,300153),(4,117548,NULL), +(5,1,300153),(5,117548,NULL),(6,1,300182),(6,117548,NULL), +(7,1,300205),(7,117548,NULL),(8,1,300217),(8,117548,NULL), +(9,1,300290),(9,117548,NULL),(10,1,300290),(10,117548,NULL), +(11,1,300405),(11,117548,NULL),(12,1,300670),(12,117548,NULL), +(13,1,300670),(13,117548,NULL),(14,1,300006),(14,117548,NULL), +(15,1,300671),(15,117548,NULL),(16,1,300732),(16,117548,NULL); +INSERT INTO t4 VALUES +(300000,1),(300001,1),(300003,1),(300004,1), +(300005,1),(300005,688796),(300006,1),(300006,97697), +(300009,1),(300010,1),(300011,1),(300012,1),(300013,1), +(300014,1),(300015,1),(300016,1),(300017,1),(300018,1), +(300019,1),(300020,1),(300021,1),(300022,1),(300023,1), +(300024,1),(300025,1),(300026,1),(300027,1),(300028,1); +# This should have join order of t2,t3,t4,t1 +EXPLAIN EXTENDED SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id +INNER JOIN t3 ON t3.id=t2.profile_id +INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND +t2.REVTYPE=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 42 100.00 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.REV 1 100.00 Using where +1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t2.profile_id 1 100.00 Using where +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.person_id 1 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`timestamp` AS `timestamp`,`test`.`t1`.`modifiedBy` AS `modifiedBy`,`test`.`t2`.`id` AS `id`,`test`.`t2`.`REV` AS `REV`,`test`.`t2`.`REVTYPE` AS `REVTYPE`,`test`.`t2`.`profile_id` AS `profile_id`,`test`.`t3`.`id` AS `id`,`test`.`t3`.`REV` AS `REV`,`test`.`t3`.`person_id` AS `person_id`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`REV` AS `REV` from `test`.`t1` join `test`.`t2` join `test`.`t3` join `test`.`t4` where `test`.`t2`.`REVTYPE` = 2 and `test`.`t4`.`id` = `test`.`t3`.`person_id` and `test`.`t3`.`id` = `test`.`t2`.`profile_id` and `test`.`t1`.`id` = `test`.`t2`.`REV` and `test`.`t1`.`timestamp` < 1294664900039 and `test`.`t1`.`timestamp` > 1294644616416 +SELECT * +FROM t1 INNER JOIN t2 ON t2.REV=t1.id +INNER JOIN t3 ON t3.id=t2.profile_id +INNER JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 AND +t2.REVTYPE=2; +id timestamp modifiedBy id REV REVTYPE profile_id id REV person_id id REV +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 1 300003 300003 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 97697 +# This should have join order of t2,t3,t4,t1 with the same plan as above +# because all RIGHT JOIN operations are converted into INNER JOIN +EXPLAIN EXTENDED SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id +RIGHT JOIN t3 ON t3.id=t2.profile_id +RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 +AND t2.REVTYPE=2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 42 100.00 Using where +1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.REV 1 100.00 Using where +1 SIMPLE t3 ref PRIMARY PRIMARY 4 test.t2.profile_id 1 100.00 Using where +1 SIMPLE t4 ref PRIMARY PRIMARY 4 test.t3.person_id 1 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`id` AS `id`,`test`.`t1`.`timestamp` AS `timestamp`,`test`.`t1`.`modifiedBy` AS `modifiedBy`,`test`.`t2`.`id` AS `id`,`test`.`t2`.`REV` AS `REV`,`test`.`t2`.`REVTYPE` AS `REVTYPE`,`test`.`t2`.`profile_id` AS `profile_id`,`test`.`t3`.`id` AS `id`,`test`.`t3`.`REV` AS `REV`,`test`.`t3`.`person_id` AS `person_id`,`test`.`t4`.`id` AS `id`,`test`.`t4`.`REV` AS `REV` from `test`.`t4` join `test`.`t3` join `test`.`t2` join `test`.`t1` where `test`.`t2`.`REVTYPE` = 2 and `test`.`t1`.`id` = `test`.`t2`.`REV` and `test`.`t3`.`id` = `test`.`t2`.`profile_id` and `test`.`t4`.`id` = `test`.`t3`.`person_id` and `test`.`t1`.`timestamp` < 1294664900039 and `test`.`t1`.`timestamp` > 1294644616416 +SELECT * +FROM t1 RIGHT JOIN t2 ON t2.REV=t1.id +RIGHT JOIN t3 ON t3.id=t2.profile_id +RIGHT JOIN t4 ON t4.id=t3.person_id +WHERE t1.timestamp < 1294664900039 AND t1.timestamp > 1294644616416 +AND t2.REVTYPE=2; +id timestamp modifiedBy id REV REVTYPE profile_id id REV person_id id REV +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 1 300003 300003 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 1 +12 1294650860266 u62C^Kzx3wH8 8 12 2 2 2 117548 300006 300006 97697 +DROP TABLE t1,t2,t3,t4; +# end of 10.1 tests +# +# MDEV-25362: name resolution for subqueries in ON expressions +# +create table t1 (a int, b int); +create table t2 (c int, d int); +create table t3 (e int, f int); +create table t4 (g int, h int); +explain +select * +from +t1 left join +(t2 +join +t3 on +(t3.f=t1.a) +) on (t2.c=t1.a ); +ERROR 42S22: Unknown column 't1.a' in 'ON' +explain +select * +from +t1 left join +(t2 +join +t3 on +(t3.f=(select max(g) from t4 where t4.h=t1.a)) +) on (t2.c=t1.a ); +ERROR 42S22: Unknown column 't1.a' in 'WHERE' +drop table t1,t2,t3,t4; +create table t1 (a int); +insert into t1 values (1),(2); +create table t2 (b int); +insert into t2 values (1),(2); +create table t3 (c int); +insert into t3 values (1),(2); +select * from ( select * from t1 left join t2 +on b in (select x from t3 as sq1) +) as sq2; +ERROR 42S22: Unknown column 'x' in 'SELECT' +drop table t1,t2,t3; +# end of 10.2 tests +# +# MDEV-22866: Crash in join optimizer with constant outer join nest +# +CREATE TABLE t1 (a INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +CREATE TABLE t2 (b INT) ENGINE=MyISAM; +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (c INT, KEY(c)) ENGINE=MyISAM; +CREATE TABLE t4 (d INT, KEY(d)) ENGINE=MyISAM; +INSERT INTO t4 VALUES (5),(6); +CREATE TABLE t5 (e INT) ENGINE=MyISAM; +INSERT INTO t5 VALUES (7),(8); +CREATE TABLE t6 (f INT) ENGINE=MyISAM; +INSERT INTO t6 VALUES (9),(10); +SELECT * +FROM +t1 +LEFT JOIN ( +t2 LEFT JOIN ( +t3 JOIN +t4 ON t3.c = t4.d and t3.c >2 and t3.c<0 +) ON t2.b >= t4.d +) ON t1.a <= t2.b +LEFT JOIN t5 ON t2.b = t5.e +LEFT JOIN t6 ON t3.c = t6.f; +a b c d e f +1 3 NULL NULL NULL NULL +1 4 NULL NULL NULL NULL +2 3 NULL NULL NULL NULL +2 4 NULL NULL NULL NULL +drop table t1,t2,t3,t4,t5,t6; +# +# MDEV-17518: Range optimization doesn't use ON expressions from nested outer joins +# +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2(a int); +insert into t2 values (0),(1); +create table t3 (a int, b int, key(a)); +insert into t3 select A.a + B.a* 10 + C.a * 100, 12345 from t1 A, t1 B, t1 C; +# Uses range for table t3: +explain select * from t1 left join t3 on t1.a=t3.b and t3.a<5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 +1 SIMPLE t3 range a a 5 NULL 5 Using where +# This must use range for table t3, too: +explain select * from t1 left join (t3 join t2) on t1.a=t3.b and t3.a<5; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 +1 SIMPLE t3 range a a 5 NULL 5 Using where +# +# .. part 2: make sure condition selectivity can use the condition too. +# +alter table t3 drop key a; +set @tmp1=@@optimizer_use_condition_selectivity; +set @tmp2=@@use_stat_tables; +set @tmp3=@@histogram_size; +set use_stat_tables=preferably; +set optimizer_use_condition_selectivity=4; +set histogram_size=100; +analyze table t3 persistent for all; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +# t3.filtered is less than 100%: +explain extended select * from t1 left join t3 on t1.a=t3.b and t3.a<5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 +1 SIMPLE t3 ALL NULL NULL NULL NULL 1000 0.50 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` left join `test`.`t3` on(`test`.`t3`.`b` = `test`.`t1`.`a` and `test`.`t3`.`a` < 5) where 1 +# t3.filtered must less than 100%, too: +explain extended select * from t1 left join (t3 join t2) on t1.a=t3.b and t3.a<5; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t3 ALL NULL NULL NULL NULL 1000 0.50 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b`,`test`.`t2`.`a` AS `a` from `test`.`t1` left join (`test`.`t3` join `test`.`t2`) on(`test`.`t3`.`b` = `test`.`t1`.`a` and `test`.`t3`.`a` < 5) where 1 +drop table t1,t2,t3; +set optimizer_use_condition_selectivity= @tmp1; +set use_stat_tables= @tmp2; +set histogram_size= @tmp3; +# Another test +CREATE TABLE t1 (i1 int) ; +CREATE TABLE t2 (pk int NOT NULL PRIMARY KEY) ; +CREATE TABLE t3 (pk int NOT NULL, i1 int, PRIMARY KEY (pk)) ; +INSERT INTO t3 VALUES (2, NULL); +CREATE TABLE t4 (pk int NOT NULL, i1 int, PRIMARY KEY (pk), KEY i1 (i1)) ; +CREATE VIEW v4 AS SELECT * FROM t4; +SELECT 1 +FROM t3 RIGHT JOIN t1 ON t3.i1 = t1.i1 +LEFT JOIN v4 +RIGHT JOIN t2 ON v4.i1 = t2.pk ON t1.i1 = t2.pk +WHERE t3.pk IN (2); +1 +drop view v4; +drop table t1,t2,t3,t4; +# +# MDEV-28602 Wrong result with outer join, merged derived table and view +# +create table t1 ( +Election int(10) unsigned NOT NULL +); +insert into t1 (Election) values (1); +create table t2 ( +VoteID int(10), +ElectionID int(10), +UserID int(10) +); +insert into t2 (ElectionID, UserID) values (2, 30), (3, 30); +create view v1 as select * from t1 +left join ( select 'Y' AS Voted, ElectionID from t2 ) AS T +on T.ElectionID = t1.Election +limit 9; +select * from v1; +Election Voted ElectionID +1 NULL NULL +drop table t1, t2; +drop view v1; +# +# and another contrived example showing a bit of hierarchy +# +create table t10 (a int); +create table t20 (b int); +insert into t10 values (1),(2); +insert into t20 values (1),(3); +create view v10 as select *, 'U' as u from t10 left join (select 'Y' as y, t20.b from t20) dt1 on t10.a= dt1.b limit 3; +create table t30 (c int); +insert into t30 values (1),(3); +create view v20 as select * from t30 left join (select 'X' as x, v10.u, v10.y, v10.b from v10) dt2 on t30.c=dt2.b limit 6; +select * from v20 limit 9; +c x u y b +1 X U Y 1 +3 NULL NULL NULL NULL +drop view v10, v20; +drop table t10, t20, t30; +# +# More complex testcase +# +create table t2 (b int); +insert into t2 values (3),(7),(1); +create table t3 (c int); +insert into t3 values (3),(1); +create table t1 (a int); +insert into t1 values (1),(2),(7),(1); +select * from +( +select * from +(select 'Z' as z, t1.a from t1) dt1 +left join +(select 'Y' as y, t2.b from t2) dt2 +left join +(select 'X' as x, t3.c from t3) dt3 +on dt2.b=dt3.c +on dt1.a=dt2.b +limit 9 +) dt; +z a y b x c +Z 1 Y 1 X 1 +Z 2 NULL NULL NULL NULL +Z 7 Y 7 NULL NULL +Z 1 Y 1 X 1 +create view v3(x,c) as select * from (select 'X' as x, t3.c from t3) dt3; +create view v2(y,b) as select * from (select 'Y' as y, t2.b from t2) dt2; +create view v0(y,b,x,c) as select * from v2 left join v3 on v2.b=v3.c; +create view v1 as select 'Z' as z, t1.a, v0.* from t1 left join v0 on t1.a=v0.b limit 9; +select * from v1; +z a y b x c +Z 1 Y 1 X 1 +Z 2 NULL NULL NULL NULL +Z 7 Y 7 NULL NULL +Z 1 Y 1 X 1 +set statement join_cache_level=0 for +select * from v1; +z a y b x c +Z 1 Y 1 X 1 +Z 2 NULL NULL NULL NULL +Z 7 Y 7 NULL NULL +Z 1 Y 1 X 1 +drop view v0, v1, v2, v3; +drop table t1, t2, t3; +# end of 10.3 tests +# +# MDEV-37653 Unexpected result of prepared statement when use boolean value as parameters +# +create table t0(c0 real); +create table t1 like t0; +insert into t1 values (1); +insert into t0 values (1); +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is true); +c0 c0 +1 NULL +select t1.c0, t0.c0 from t1 left join t0 on 0 where not (t0.c0 is false); +c0 c0 +1 NULL +select t1.c0, t0.c0 from t1 left join t0 on false where (false or ((t0.c0 is true) in (false))); +c0 c0 +1 NULL +drop table t0, t1; +# end of 10.11 tests +SET optimizer_switch=@org_optimizer_switch; +set SQL_MODE= oracle; +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +create table t3 (c int, e int); +insert into t3 values (3,2),(10,3),(2,20); +create table t4 (d int); +insert into t4 values (3),(1),(20); +select t1.a, t4.d, t2.b, t3.c +from t1, t2, t3, t4 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +a d b c +3 3 NULL 3 +1 1 1 NULL +1 3 NULL NULL +2 3 NULL NULL +2 1 NULL NULL +3 1 NULL NULL +1 20 NULL NULL +2 20 NULL NULL +3 20 NULL NULL +explain extended +select t1.a, t4.d, t2.b, t3.c +from t1, t2, t3, t4 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t4 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t4"."d" AS "d","test"."t2"."b" AS "b","test"."t3"."c" AS "c" from "test"."t1" join "test"."t4" left join "test"."t2" on("test"."t4"."d" = "test"."t1"."a" and "test"."t2"."b" = "test"."t1"."a") left join "test"."t3" on("test"."t4"."d" = "test"."t1"."a" and "test"."t3"."c" = "test"."t1"."a") where 1 +select t1.a, t4.d, t2.b, t3.c +from t4, t3, t2, t1 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +a d b c +1 1 1 NULL +3 3 NULL 3 +1 3 NULL NULL +1 20 NULL NULL +2 3 NULL NULL +2 1 NULL NULL +2 20 NULL NULL +3 1 NULL NULL +3 20 NULL NULL +explain extended +select t1.a, t4.d, t2.b, t3.c +from t4, t3, t2, t1 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t4"."d" AS "d","test"."t2"."b" AS "b","test"."t3"."c" AS "c" from "test"."t4" join "test"."t1" left join "test"."t3" on("test"."t1"."a" = "test"."t4"."d" and "test"."t3"."c" = "test"."t4"."d") left join "test"."t2" on("test"."t1"."a" = "test"."t4"."d" and "test"."t2"."b" = "test"."t4"."d") where 1 +select t1.a, t4.d, t2.b, t3.c +from t2, t1, t4, t3 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +a d b c +3 3 NULL 3 +1 1 1 NULL +1 3 NULL NULL +2 3 NULL NULL +2 1 NULL NULL +3 1 NULL NULL +1 20 NULL NULL +2 20 NULL NULL +3 20 NULL NULL +explain extended +select t1.a, t4.d, t2.b, t3.c +from t2, t1, t4, t3 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t4 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t4"."d" AS "d","test"."t2"."b" AS "b","test"."t3"."c" AS "c" from "test"."t1" join "test"."t4" left join "test"."t2" on("test"."t4"."d" = "test"."t1"."a" and "test"."t2"."b" = "test"."t1"."a") left join "test"."t3" on("test"."t4"."d" = "test"."t1"."a" and "test"."t3"."c" = "test"."t1"."a") where 1 +select t1.a, t4.d, t2.b, t3.c +from t3, t4, t1, t2 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +a d b c +1 1 1 NULL +3 3 NULL 3 +1 3 NULL NULL +1 20 NULL NULL +2 3 NULL NULL +2 1 NULL NULL +2 20 NULL NULL +3 1 NULL NULL +3 20 NULL NULL +explain extended +select t1.a, t4.d, t2.b, t3.c +from t3, t4, t1, t2 +where +t1.a = t2.b(+) and +t1.a = t3.c(+) and +t4.d = t2.b(+) and +t4.d = t3.c(+); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t4 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using join buffer (flat, BNL join) +1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t4"."d" AS "d","test"."t2"."b" AS "b","test"."t3"."c" AS "c" from "test"."t4" join "test"."t1" left join "test"."t3" on("test"."t1"."a" = "test"."t4"."d" and "test"."t3"."c" = "test"."t4"."d") left join "test"."t2" on("test"."t1"."a" = "test"."t4"."d" and "test"."t2"."b" = "test"."t4"."d") where 1 +drop table t1, t2, t3, t4; +# +# tests of Iqbal Hassan +# (with 2 fixes) +# +CREATE TABLE tj1(a int, b int); +CREATE TABLE tj2(c int, d int); +CREATE TABLE tj3(e int, f int); +CREATE TABLE tj4(b int, c int); +INSERT INTO tj1 VALUES (1, 1); +INSERT INTO tj1 VALUES (2, 2); +INSERT INTO tj2 VALUES (2, 3); +INSERT INTO tj3 VALUES (1, 4); +# +# Basic test +# +SELECT * FROM tj1,tj2 WHERE tj1.a = tj2.c(+); +a b c d +2 2 2 3 +1 1 NULL NULL +# +# Compare marked with literal +# +SELECT * FROM tj1,tj2 WHERE tj1.a = tj2.c(+) AND tj2.d(+) > 4; +a b c d +1 1 NULL NULL +2 2 NULL NULL +explain extended +SELECT * FROM tj1,tj2 WHERE tj1.a = tj2.c(+) AND tj2.d(+) > 4; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE tj1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE tj2 ALL NULL NULL NULL NULL 1 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."tj1"."a" AS "a","test"."tj1"."b" AS "b","test"."tj2"."c" AS "c","test"."tj2"."d" AS "d" from "test"."tj1" left join "test"."tj2" on("test"."tj2"."c" = "test"."tj1"."a" and "test"."tj2"."d" > 4) where 1 +# +# Use both marked and unmarked field in the same condition +# +SELECT * FROM tj1,tj2 WHERE tj1.a = tj2.c(+) AND tj2.d = 3; +a b c d +2 2 2 3 +# +# Use both marked and unmarked field in OR condition +# +SELECT * FROM tj2,tj1 WHERE tj1.a = tj2.c(+) OR tj2.d=4; +ERROR HY000: Invalid usage of (+) operator: cycle dependencies +SELECT * FROM tj1,tj2,tj3 WHERE tj1.a = tj3.e(+) AND (tj1.a = tj2.c(+) OR tj2.d=4); +ERROR HY000: Invalid usage of (+) operator: cycle dependencies +# +# Use unmarked fields in OR condition +# +SELECT * FROM tj2,tj1 WHERE tj1.a = tj2.c(+) AND (tj2.d=3 OR tj2.d * 2=3); +c d a b +2 3 2 2 +# +# Use marked fields in OR condition when all fields are marked +# +SELECT * FROM tj1,tj2 WHERE tj1.a = tj2.c(+) AND (tj2.d(+)=3 OR tj2.c(+)=1); +a b c d +2 2 2 3 +1 1 NULL NULL +# +# Use more than one marked table per condition +# +SELECT * FROM tj1,tj2,tj3 WHERE tj1.a = tj2.c(+) + tj3.e(+); +ERROR HY000: Invalid usage of (+) operator: both tables tj2 and tj3 are of INNER type in the relation +# +# Use different tables per `AND` operand +# +SELECT * FROM tj1,tj2,tj3 WHERE tj1.a = tj2.c(+) AND tj1.a = tj3.e(+); +a b c d e f +1 1 NULL NULL 1 4 +2 2 2 3 NULL NULL +# +# Ensure table dependencies are properly resolved +# +SELECT * FROM tj1,tj2,tj3 WHERE tj1.a = tj3.e AND tj1.a + 1 = tj2.c(+); +a b c d e f +1 1 2 3 1 4 +SELECT * FROM tj1,tj2,tj3 WHERE tj1.a = tj2.c(+) AND tj2.c = tj3.e(+) + 1; +a b c d e f +2 2 2 3 1 4 +1 1 NULL NULL NULL NULL +SELECT * FROM tj1, tj2, tj3 WHERE tj1.a + tj3.e = tj2.c(+); +a b c d e f +1 1 2 3 1 4 +2 2 NULL NULL 1 4 +# +# Cyclic dependency of tables +# ORA-01416 two tables cannot be outer-joined to each other +# +SELECT * FROM tj1,tj2,tj3 WHERE tj1.a = tj2.c(+) AND tj2.c = tj3.e(+) + 1 AND tj3.e = tj1.a(+); +ERROR HY000: Invalid usage of (+) operator: cycle dependencies +# +# Table not referenced in where condition (must be cross-joined) +# +SELECT * FROM tj1, tj2, tj3 WHERE tj1.a + 1 = tj2.c(+); +a b c d e f +1 1 2 3 1 4 +2 2 NULL NULL 1 4 +# +# Alias +# +SELECT * FROM tj1, tj2 b WHERE tj1.a + 1 = b.c(+); +a b c d +1 1 2 3 +2 2 NULL NULL +# +# Subselect +# +SELECT * FROM tj1, (SELECT * from tj2) b WHERE tj1.a + 1 = b.c(+); +a b c d +1 1 2 3 +2 2 NULL NULL +SELECT * FROM tj1, (SELECT * FROM tj1, tj2 d WHERE tj1.a = d.c(+)) b WHERE tj1.a + 1 = b.c(+); +a b a b c d +1 1 2 2 2 3 +2 2 NULL NULL NULL NULL +# +# Single table +# +SELECT * FROM tj1 WHERE tj1.a(+) = 1; +a b +1 1 +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '"test"."tj1"."a" = 1' +# +# Self outer join +# +SELECT * FROM tj1 a, tj1 b WHERE a.a + 1 = b.a(+); +a b a b +1 1 2 2 +2 2 NULL NULL +# +# Self outer join without alias +# +SELECT * FROM tj1, tj2 WHERE tj1.a + 1 = tj1.a(+); +ERROR HY000: Invalid usage of (+) operator: cycle dependencies +# +# Outer join condition is independent of other tables +# In this case we need to restrict the marked table(s) to appear +# after the unmarked table(s) during topological sort. This test +# ensures that the topological sort is working correctly. +# +# correct result in is empty result set (tj2.c = 1 filters all out) +SELECT * FROM tj1, tj2 WHERE tj2.c(+) = 1; +a b c d +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '"test"."tj2"."c" = 1' +# one row (there is tj1.a = 1) +SELECT * FROM tj1, tj2 WHERE tj1.a(+) = 1; +a b c d +1 1 2 3 +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '"test"."tj1"."a" = 1' +# +# Outer join in 'IN' condition +# ORA-01719 +# +SELECT * FROM tj1, tj2 WHERE tj1.a IN (tj2.c(+), tj2.d(+)); +ERROR HY000: Invalid usage of (+) operator: used in OR, IN or ROW operation +SELECT * FROM tj1, tj2 WHERE tj1.a NOT IN (tj2.c(+), tj2.d(+)); +ERROR HY000: Invalid usage of (+) operator: used in OR, IN or ROW operation +# +# Outer join in 'IN' condition with a single expression +# This is also allowed in oracle since the expression is +# can be simplified to 'equal' or 'not equal' condition +# +SELECT * FROM tj1, tj2 WHERE tj1.a IN (tj2.c(+)); +a b c d +2 2 2 3 +1 1 NULL NULL +SELECT * FROM tj1, tj2 WHERE tj1.a NOT IN (tj2.c(+)); +a b c d +1 1 2 3 +2 2 NULL NULL +# +# Oracle outer join not in WHERE clause +# +SELECT * FROM tj1, tj2 WHERE tj1.a = tj2.c GROUP BY tj2.c(+); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +SELECT * FROM tj1, tj2 WHERE tj1.a = tj2.c GROUP BY tj2.c HAVING tj2.c(+) > 1; +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 ') > 1' at line 1 +SELECT * FROM tj1, tj2 WHERE tj1.a = tj2.c ORDER BY tj2.c(+); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +SELECT tj2.c(+) FROM tj2; +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 ') FROM tj2' at line 1 +# +# Mix ANSI and Oracle outer join +# ORA-25156 +SELECT * FROM tj1 LEFT JOIN tj2 ON tj2.c = 1 WHERE tj1.a = tj2.c(+); +ERROR HY000: Invalid usage of (+) operator: mixed with other type of join +SELECT * FROM tj1 INNER JOIN tj2 ON tj2.c = 1 WHERE tj1.a = tj2.c(+); +ERROR HY000: Invalid usage of (+) operator: mixed with other type of join +SELECT * FROM tj1 NATURAL JOIN tj2 WHERE tj1.a = tj2.c(+); +ERROR HY000: Invalid usage of (+) operator: mixed with other type of join +# +# View with oracle outer join +# +CREATE VIEW v1 AS SELECT * FROM tj1, tj2 WHERE tj1.a = tj2.c(+); +SELECT * FROM v1; +a b c d +2 2 2 3 +1 1 NULL NULL +# +# Cursor with oracle outer join +# +DECLARE +CURSOR c1 IS SELECT * FROM tj1, tj2 WHERE tj1.a = tj2.c(+); +BEGIN +FOR r1 IN c1 LOOP +SELECT r1.a || ' ' || r1.c; +END LOOP; +END +$$ +r1.a || ' ' || r1.c +2 2 +r1.a || ' ' || r1.c +1 +# +# Marking ROW type +# +DECLARE +v1 ROW (a INT, b INT); +BEGIN +SELECT * FROM tj1 WHERE tj1.a = v1.a(+); +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 '); +END' at line 4 +# +# Unspecified table used in WHERE clause that contains (+) +# +SELECT * FROM tj1, tj2 WHERE tj1.a = tj3.c(+); +ERROR 42S22: Unknown column 'tj3.c' in 'WHERE' +# +# '.' prefixed table name +# +SELECT * FROM tj1, tj2 WHERE tj1.a = .tj2.c(+); +a b c d +2 2 2 3 +1 1 NULL NULL +CREATE DATABASE db1; +USE db1; +CREATE TABLE tj1(a int, b int); +INSERT INTO tj1 VALUES (3, 3); +INSERT INTO tj1 VALUES (4, 4); +# +# DB qualifed ident with oracle outer join (aliased) +# +SELECT * FROM test.tj2 a, tj1 WHERE a.c(+) = tj1.a - 1; +c d a b +2 3 3 3 +NULL NULL 4 4 +# +# DB qualifed ident with oracle outer join (non-aliased) +# +SELECT * FROM test.tj2, tj1 WHERE test.tj2.c(+) = tj1.a - 1; +c d a b +2 3 3 3 +NULL NULL 4 4 +# +# DB qualifed ident with oracle outer join (aliased but use table name) +# +SELECT * FROM test.tj2 a, tj1 WHERE test.tj2.c(+) = tj1.a - 1; +ERROR 42S22: Unknown column 'test.tj2.c' in 'WHERE' +USE test; +# +# UPDATE with oracle outer join +# +UPDATE tj1, tj2 SET tj1.a = tj2.c WHERE tj1.a = tj2.c(+); +SELECT * FROM tj1; +a b +NULL 1 +2 2 +# +# DELETE with oracle outer join +# +DELETE tj1 FROM tj1, tj2 WHERE tj1.b(+) = tj2.c; +SELECT * FROM tj1; +a b +NULL 1 +DROP DATABASE db1; +DROP VIEW v1; +DROP TABLE tj4; +DROP TABLE tj3; +DROP TABLE tj2; +DROP TABLE tj1; +# +# End of iqbal-rsec tests +# +# +# Test from the MDEV comments +# +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +create table t3 (c int, e int); +insert into t3 values (3,2),(10,3),(2,20); +create table t4 (d int); +insert into t4 values (3),(1),(20); +select t1.a, t4.d, t2.b, t3.c from t1, t2, t3, t4 where t1.a = t2.b(+) and t1.a = t3.c(+) and t4.d = t2.b(+) and t4.d = t3.c(+); +a d b c +3 3 NULL 3 +1 1 1 NULL +1 3 NULL NULL +2 3 NULL NULL +2 1 NULL NULL +3 1 NULL NULL +1 20 NULL NULL +2 20 NULL NULL +3 20 NULL NULL +select t1.a, t4.d, t2.b, t3.c from t1, t2, t3, t4 where t1.a + t3.c = t2.b(+) and t1.a = t3.c(+) and t4.d = t2.b(+) and t4.d = t3.c(+); +a d b c +3 3 NULL 3 +1 3 NULL NULL +2 3 NULL NULL +1 1 NULL NULL +2 1 NULL NULL +3 1 NULL NULL +1 20 NULL NULL +2 20 NULL NULL +3 20 NULL NULL +select t1.a, t4.d, t2.b, t3.c from t1, t2, t3, t4 where (t2.b(+) in (t1.a, t1.a+1)) and t1.a = t3.c(+) and t4.d = t2.b(+) and t4.d = t3.c(+); +a d b c +3 3 NULL 3 +1 1 1 NULL +1 3 NULL NULL +2 3 NULL NULL +2 1 NULL NULL +3 1 NULL NULL +1 20 NULL NULL +2 20 NULL NULL +3 20 NULL NULL +drop tables t1, t2, t3, t4; +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +create table t3 (c int, f int); +insert into t3 values (3,2),(10,3),(2,20); +create table t4 (d int); +insert into t4 values (3),(1),(20); +create table t5 (e int); +insert into t5 values (3),(2),(20); +select t1.a, t2.b, t3.c, t4.d, t5.e from t1, t2, t3, t4, t5 where t1.a = t2.b(+) and t2.b = t3.c(+) and t1.a = t4.d(+) and t4.d=t5.e(+) and t3.c=t5.e(+); +a b c d e +1 1 NULL 1 NULL +2 2 2 NULL NULL +3 NULL NULL 3 NULL +select t1.a, t2.b, t3.c, t4.d, t5.e from t1, t2, t3, t4, t5 where t1.a = t2.b(+) and t2.b = t3.c(+) and t1.a = t4.d(+) and t4.d=t5.e(+) and 1=t5.e(+); +a b c d e +3 NULL NULL 3 NULL +1 1 NULL 1 NULL +2 2 2 NULL NULL +select t1.a, t2.b, t3.c, t4.d, t5.e from t1, t2, t3, t4, t5 where t1.a = t2.b(+) and t2.b = t3.c(+) and t1.a = t4.d(+) and t4.d=t5.e(+) and 3=t5.e(+); +a b c d e +3 NULL NULL 3 3 +1 1 NULL 1 NULL +2 2 2 NULL NULL +select t1.a, t2.b, t3.c, t4.d, t5.e from t1, (t2, t3), t4, t5 where t1.a = t2.b(+) and t2.b = t3.c(+) and t1.a = t4.d(+) and t4.d=t5.e(+) and 3=t5.e(+); +ERROR HY000: Invalid usage of (+) operator: mixed with other type of join +drop tables t1, t2, t3, t4, t5; +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +select t1.a, t2.b from t1, t2 where 1 = t2.b(+); +a b +1 1 +2 1 +3 1 +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '1 = "test"."t2"."b"' +select t1.a, t2.b from t2, t1 where 1 = t2.b(+); +a b +1 1 +2 1 +3 1 +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '1 = "test"."t2"."b"' +select t1.a,t2.b from t2,t1 where t2.b(+) in (1,2); +a b +1 2 +1 1 +2 2 +2 1 +3 2 +3 1 +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '"test"."t2"."b" in (1,2)' +select t2.b from t2 where 1 = t2.b(+); +b +1 +Warnings: +Warning 4237 Oracle outer join operator (+) ignored in '1 = "test"."t2"."b"' +drop tables t1, t2; +create table t1 (a int); +insert into t1 values (1),(2),(4),(5),(20),(21),(23); +create table t2 (b int); +insert into t2 values (1),(4),(6),(7),(8),(23); +create table t3 (c int); +insert into t3 values (4),(7),(9),(4),(6),(10),(11),(1); +create table t4 (d int); +insert into t4 values (1),(4),(10),(12),(20),(21),(23); +SELECT * FROM t1,t2,t3,t4 WHERE t1.a = t2.b(+) AND t1.a = t3.c(+) AND t2.b=t4.d(+) AND t3.c=t4.d(+); +a b c d +1 1 1 1 +4 4 4 4 +4 4 4 4 +23 23 NULL NULL +2 NULL NULL NULL +5 NULL NULL NULL +20 NULL NULL NULL +21 NULL NULL NULL +select * from t1, t2, t3 where (t1.a + t2.b = t3.c(+)); +a b c +1 6 7 +1 8 9 +2 7 9 +5 4 9 +2 4 6 +5 1 6 +2 8 10 +4 6 10 +4 7 11 +5 6 11 +1 1 NULL +1 4 NULL +1 7 NULL +1 23 NULL +2 1 NULL +2 6 NULL +2 23 NULL +4 1 NULL +4 4 NULL +4 8 NULL +4 23 NULL +5 7 NULL +5 8 NULL +5 23 NULL +20 1 NULL +20 4 NULL +20 6 NULL +20 7 NULL +20 8 NULL +20 23 NULL +21 1 NULL +21 4 NULL +21 6 NULL +21 7 NULL +21 8 NULL +21 23 NULL +23 1 NULL +23 4 NULL +23 6 NULL +23 7 NULL +23 8 NULL +23 23 NULL +# no tables mentioned +select * from t2, t3 where b = c(+); +b c +4 4 +7 7 +4 4 +6 6 +1 1 +8 NULL +23 NULL +# should be the same as above +select * from t2, t3 where t2.b = t3.c(+); +b c +4 4 +7 7 +4 4 +6 6 +1 1 +8 NULL +23 NULL +drop tables t1, t2, t3, t4; +# +# View creation and usage +# +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +create view v1 as +select t1.a, t2.b from t1, t2 where t1.a = t2.b(+); +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE VIEW "v1" AS select "t1"."a" AS "a","t2"."b" AS "b" from ("t1" left join "t2" on("t1"."a" = "t2"."b")) latin1 latin1_swedish_ci +select * from v1; +a b +2 2 +1 1 +3 NULL +select t1.a, t2.b from t1, t2 where t1.a = t2.b(+); +a b +2 2 +1 1 +3 NULL +usage without oracle sql mode +set SQL_MODE= ''; +select * from v1; +a b +2 2 +1 1 +3 NULL +select t1.a, t2.b from t1, t2 where t1.a = t2.b(+); +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ')' at line 1 +set SQL_MODE= oracle; +drop view v1; +drop table t1,t2; +# +# MDEV-36830: Oracle outer join syntax (+): outer join not converted to inner +# +create table t1 ( +a int not null, +b int not null +); +insert into t1 select seq,seq from seq_1_to_10; +create table t2 ( +a int not null, +b int not null +); +insert into t2 select seq,seq from seq_1_to_3; +# Must be converted to inner join: +explain extended +select * from t1, t2 +where +t1.a=1 and +t1.b=t2.b(+) and +t2.b=1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."b" AS "b","test"."t2"."a" AS "a","test"."t2"."b" AS "b" from "test"."t1" join "test"."t2" where "test"."t1"."a" = 1 and "test"."t2"."b" = 1 and "test"."t1"."b" = 1 +drop table t1,t2; +# +# MDEV-36838: Oracle outer join syntax (+): server crash on derived tables +# +select a.a +from (select 1 as a) a, +(select 2 as b) b +where a.a=b.b(+); +a +1 +# +# MDEV-36866: Oracle outer join syntax (+): query with checking for +# null of non-null column uses wrong query plan and returns wrong +# result +# +create table t1 (a int default NULL); +create table t2 (a int not null); +insert into t1 values (1), (2), (3), (4), (5), (6), (NULL); +insert into t2 values (1), (4), (5), (6), (7); +select t1.*,t2.* from t1,t2 where t1.a=t2.a and isnull(t2.a)=1; +a a +explain select t1.*,t2.* from t1,t2 where t1.a=t2.a and isnull(t2.a)=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1; +a a +2 NULL +3 NULL +NULL NULL +explain select t1.*,t2.* from t1 left join t2 on t1.a=t2.a where isnull(t2.a)=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 Using where; Using join buffer (flat, BNL join) +select t1.*,t2.* from t1,t2 where t1.a=t2.a(+) and isnull(t2.a)=1; +a a +2 NULL +3 NULL +NULL NULL +explain extended select t1.*,t2.* from t1,t2 where t1.a=t2.a(+) and isnull(t2.a)=1; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 7 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t2"."a" AS "a" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where "test"."t2"."a" is null = 1 +drop table t1,t2; +# +# Correct nullability test +# +create table t1 (a int not null, s varchar(10) not null); +create table t2 (a int not null, s varchar(10) not null); +insert into t1 values (1, 'one'); +insert into t1 values (2, 'two'); +insert into t2 values (2, 'two'); +insert into t2 values (3, 'three'); +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(t2.a); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Not exists; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where "test"."t2"."a" is null +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(t1.a+t2.a); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where "test"."t1"."a" + "test"."t2"."a" is null +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(coalesce(t2.s, 'null')); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on(multiple equal("test"."t1"."a", "test"."t2"."a")) where 0 +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(ifnull(t2.s, 'null')); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on(multiple equal("test"."t1"."a", "test"."t2"."a")) where 0 +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(coalesce(t2.s, null)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where coalesce("test"."t2"."s",NULL) is null +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(ifnull(t2.s, null)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where ifnull("test"."t2"."s",NULL) is null +# Our optimizer does not optimize out never-null-subselects under +# isnull() so we do not test it. The following test is to make +# sure that nullable one stay in the WHERE. +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(t2.a in (select a from t1)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY t1 ALL NULL NULL NULL NULL 2 100.00 +1 PRIMARY t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +2 MATERIALIZED t1 ALL NULL NULL NULL NULL 2 100.00 +Warnings: +Note 1003 /* select#1 */ select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where <"test"."t2"."a">(("test"."t2"."a","test"."t2"."a" in ( (/* select#2 */ select "test"."t1"."a" from "test"."t1" ), ("test"."t2"."a" in on distinct_key where "test"."t2"."a" = ""."a")))) is null +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(t2.a in (1, 2, 3)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on("test"."t2"."a" = "test"."t1"."a") where "test"."t2"."a" in (1,2,3) is null +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(t1.a in (1, 2, 3)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on(multiple equal("test"."t1"."a", "test"."t2"."a")) where 0 +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(isnull(t2.a)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on(multiple equal("test"."t1"."a", "test"."t2"."a")) where 0 +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(field(t2.a, 2, 23)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on(multiple equal("test"."t1"."a", "test"."t2"."a")) where 0 +explain extended +select * from t1,t2 where t1.a = t2.a (+) and +isnull(benchmark(10, t2.a)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t1"."s" AS "s","test"."t2"."a" AS "a","test"."t2"."s" AS "s" from "test"."t1" left join "test"."t2" on(multiple equal("test"."t1"."a", "test"."t2"."a")) where 0 +drop table t1, t2; +# +# MDEV-36895: Oracle outer join syntax (+): some NULLs missing from +# result of the query with derived tables and limit +# +create table t2 (b int); +insert into t2 values (3),(7),(1); +create table t3 (c int); +insert into t3 values (3),(1); +create table t1 (a int); +insert into t1 values (1),(2),(7),(1); +select * from +( +select * from +(select 'Z' as z, t1.a from t1) dt1 +left join +(select 'Y' as y, t2.b from t2) dt2 +left join +(select 'X' as x, t3.c from t3) dt3 +on dt2.b=dt3.c +on dt1.a=dt2.b +order by z, a, y, b, x, c +limit 9 +) dt; +z a y b x c +Z 1 Y 1 X 1 +Z 1 Y 1 X 1 +Z 2 NULL NULL NULL NULL +Z 7 Y 7 NULL NULL +select * from +( +select * from +(select 'Z' as z, t1.a from t1) dt1 +,(select * from +(select 'Y' as y, t2.b from t2) dt2 +, +(select 'X' as x, t3.c from t3) dt3 +where dt2.b=dt3.c(+) +) tdt2 +where dt1.a=tdt2.b(+) +order by z, a, y, b, x, c +limit 9 +) dt; +z a y b x c +Z 1 Y 1 X 1 +Z 1 Y 1 X 1 +Z 2 NULL NULL NULL NULL +Z 7 Y 7 NULL NULL +drop table t1, t2, t3; +# +# MDEV-37337: Oracle outer join syntax (+): IN equal to = allow (+) on right side +# +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +set SQL_MODE= oracle; +select t1.a, t2.b +from t1, t2 +where +t1.a = t2.b(+); +a b +2 2 +1 1 +3 NULL +select t1.a, t2.b +from t1, t2 +where +t1.a IN (t2.b(+)); +a b +2 2 +1 1 +3 NULL +explain extended +select t1.a, t2.b +from t1, t2 +where +t1.a IN (t2.b(+)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t2"."b" AS "b" from "test"."t1" left join "test"."t2" on("test"."t2"."b" = "test"."t1"."a") where 1 +select t1.a, t2.b +from t1, t2 +where +t1.a IN (t2.b(+), 29); +ERROR HY000: Invalid usage of (+) operator: used in OR, IN or ROW operation +DROP TABLE t1, t2; +create table t1 (a int); +insert into t1 values (1),(2),(3); +create table t2 (b int); +insert into t2 values (2),(1),(20); +set SQL_MODE= oracle; +select t1.a, t2.b +from t1, t2 +where +t1.a = t2.b(+); +a b +2 2 +1 1 +3 NULL +select t1.a, t2.b +from t1, t2 +where +t1.a IN (t2.b(+)); +a b +2 2 +1 1 +3 NULL +explain extended +select t1.a, t2.b +from t1, t2 +where +t1.a IN (t2.b(+)); +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) +Warnings: +Note 1003 select "test"."t1"."a" AS "a","test"."t2"."b" AS "b" from "test"."t1" left join "test"."t2" on("test"."t2"."b" = "test"."t1"."a") where 1 +select t1.a, t2.b +from t1, t2 +where +t1.a IN (t2.b(+), 29); +ERROR HY000: Invalid usage of (+) operator: used in OR, IN or ROW operation +DROP TABLE t1, t2; +# End of 12.1 tests +set optimizer_switch=@join_outer_reorder_tmp; diff --git a/mysql-test/main/join_outer_reorder.test b/mysql-test/main/join_outer_reorder.test new file mode 100644 index 0000000000000..94429ddb068d6 --- /dev/null +++ b/mysql-test/main/join_outer_reorder.test @@ -0,0 +1,108 @@ +# +# Tests for MDEV-36055 : Outer join reordering +# +--source include/have_sequence.inc + +# We need optimizer trace: +--source include/not_embedded.inc + +set @join_outer_reorder_tmp=@@optimizer_switch; +set optimizer_switch='reorder_outer_joins=on'; + +create table t1 (a int); +insert into t1 select seq from seq_1_to_10000; + +create table t2 ( + a int, + b int, + index(a) +); +insert into t2 +select + A.seq, + B.seq +from + seq_1_to_1000 A, + seq_1_to_10 B; + +create table t3 ( + a int, + b int, + index(a) +); +insert into t3 +select + A.seq, + A.seq +from + seq_1_to_1000 A; + +analyze table t1,t2,t3; + +set optimizer_trace=1; +explain +select * +from + t1 + left join t3 on t3.a=t1.a + left join t2 on t2.a=t1.a; + +--echo # This will show that t2 and t3 only depend on t1: +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; + +--echo # This will have same join order like previous EXPLAIN +--echo # as the optimizer considers the queries identical +explain +select * +from + t1 + left join t2 on t2.a=t1.a + left join t3 on t3.a=t1.a; + +--echo # This will show that t2 and t3 only depend on t1: +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; + +--echo # Make t3's ON expression depend on t2: +explain +select * +from + t1 + left join t2 on t2.a=t1.a + left join t3 on t3.a=t1.a and t3.b=t2.b; +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; + + +--echo # +--echo # Now, try a nested join: +--echo # +create table t4 ( + a int, + b int +); +insert into t4 values (1,1); + +explain +select * +from + t1 + left join (t2 join t4 as t4_2 on t2.b=t4_2.b) on t2.a=t1.a + left join (t3 join t4 as t4_3 on t3.b=t4_3.b) on t3.a=t1.a; +select json_pretty(json_extract(trace, '$**.table_dependencies')) as DEPS +from information_schema.optimizer_trace; +drop table t1,t2,t3,t4; + +# The below tests produce the same result regardless of the reorder_outer_joins +# setting. Which may mean there's not a lot of meaningful coverage but let's +# show we do not break outer join handling: +#set optimizer_switch='reorder_outer_joins=off'; +--source join_nested.test +--source join_outer.test + +# This produces one .result change where rows come in different order: +--source suite/compat/oracle/t/ora_outer_join.test + +set optimizer_switch=@join_outer_reorder_tmp; + diff --git a/mysql-test/main/json_equals.result b/mysql-test/main/json_equals.result index a9a828af8cfd9..2450774e21da0 100644 --- a/mysql-test/main/json_equals.result +++ b/mysql-test/main/json_equals.result @@ -65,7 +65,7 @@ select json_equals('{"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"ob select json_equals('{"obj":{"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"key": "value"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}', '{"obj":{"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"obj": {"key": "value"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}') as 32_levels; 32_levels -NULL +1 # # test values from different charset # (UTF-8 two-bytes vs. latin1 single high-byte) diff --git a/mysql-test/main/kill-2-master.opt b/mysql-test/main/kill-2.opt similarity index 100% rename from mysql-test/main/kill-2-master.opt rename to mysql-test/main/kill-2.opt diff --git a/mysql-test/main/kill-2.result b/mysql-test/main/kill-2.result index 0f9d069aaccd5..543ad4bdb4a64 100644 --- a/mysql-test/main/kill-2.result +++ b/mysql-test/main/kill-2.result @@ -4,10 +4,9 @@ create user foo@'127.0.0.1'; connect con1,127.0.0.1,foo,,; connection default; -select user from information_schema.processlist; +select user from information_schema.processlist where id=$con1_id; user foo -root kill user foo@'127.0.0.1'; drop user foo@'127.0.0.1'; # @@ -28,14 +27,16 @@ Id User Host db Command Time State Info Progress kill user a; kill user x; connection a; -show processlist; -Id User Host db Command Time State Info Progress -# root # test # # # # # -# a # NULL # # # # # -# b # test # # # # # +select user from information_schema.processlist where id in (connection_id(), $b_id, $default_id) order by user; +user +a +b +root kill user b; ERROR HY000: Operation KILL USER failed for b@% connection default; +disconnect a; +disconnect b; drop user a@'127.0.0.1'; drop user b@'127.0.0.1'; # diff --git a/mysql-test/main/kill-2.test b/mysql-test/main/kill-2.test index 9bc4fe03346c0..fee81a6390666 100644 --- a/mysql-test/main/kill-2.test +++ b/mysql-test/main/kill-2.test @@ -16,9 +16,10 @@ create user foo@'127.0.0.1'; --connect (con1,127.0.0.1,foo,,) +let $con1_id= `select connection_id()`; --connection default -select user from information_schema.processlist; +evalp select user from information_schema.processlist where id=$con1_id; kill user foo@'127.0.0.1'; let $wait_condition= @@ -31,6 +32,7 @@ drop user foo@'127.0.0.1'; --echo # --echo # KILL USER and missing privileges --echo # +let $default_id= `select connection_id()`; create user a@'127.0.0.1'; create user b@'127.0.0.1'; grant process on *.* to a@'127.0.0.1'; @@ -38,16 +40,18 @@ grant select on *.* to b@'127.0.0.1'; --connect a,127.0.0.1,a show grants; --connect b,127.0.0.1,b +let $b_id= `select connection_id()`; --replace_column 1 # 3 # 5 # 6 # 9 # show processlist; kill user a; # existing connection, but not visible to current_user kill user x; # not existing connection --connection a ---replace_column 1 # 3 # 5 # 6 # 7 # 8 # 9 # -show processlist; +evalp select user from information_schema.processlist where id in (connection_id(), $b_id, $default_id) order by user; --error ER_KILL_DENIED_ERROR kill user b; --connection default +--disconnect a +--disconnect b drop user a@'127.0.0.1'; drop user b@'127.0.0.1'; diff --git a/mysql-test/main/kill.result b/mysql-test/main/kill.result index 0f14698ef3d60..08f4119d30829 100644 --- a/mysql-test/main/kill.result +++ b/mysql-test/main/kill.result @@ -185,3 +185,22 @@ DROP TABLE t1, t2; # kill query id user 'foo'; ERROR 42S22: Unknown column 'user' in 'KILL' +# +# MDEV-36034 KILL or timeout inside derived table optimization causes an assert +# +CREATE TABLE t10(c int primary key, c2 int) engine=innodb; +CREATE TABLE t20(c INT) engine=innodb; +connect con1, localhost, root; +connection default; +set debug_sync='before_get_quick_record_count SIGNAL target_ready WAIT_FOR target_continue'; +explain format=json +update t20,(SELECT * FROM t10)t (a, c) +set t20.c=t.c+10 where t20.c = t.c and t.a >= 3; +connection con1; +set debug_sync='now WAIT_FOR target_ready'; +kill query $id; +connection default; +ERROR 70100: Query execution was interrupted +disconnect con1; +drop table t10, t20; +set debug_sync='reset'; diff --git a/mysql-test/main/kill.test b/mysql-test/main/kill.test index e89bdb22cd1ef..ddcb328dfee17 100644 --- a/mysql-test/main/kill.test +++ b/mysql-test/main/kill.test @@ -9,6 +9,8 @@ -- source include/count_sessions.inc -- source include/not_embedded.inc +-- source include/have_innodb.inc +-- source include/have_debug_sync.inc --disable_service_connection @@ -221,7 +223,6 @@ drop table t2; --echo # --echo # Test kill USER --echo # ---source include/count_sessions.inc grant ALL on test.* to test@localhost; grant ALL on test.* to test2@localhost; connect (con3, localhost, test,,); @@ -246,7 +247,6 @@ connection con4; --error 2013,2006,5014 select 1; connection default; ---source include/wait_until_count_sessions.inc --echo # --echo # MDEV-4911 - add KILL query id, and add query id information to @@ -320,3 +320,36 @@ DROP TABLE t1, t2; --error ER_BAD_FIELD_ERROR kill query id user 'foo'; --enable_service_connection + + +--echo # +--echo # MDEV-36034 KILL or timeout inside derived table optimization causes an assert +--echo # + +CREATE TABLE t10(c int primary key, c2 int) engine=innodb; +CREATE TABLE t20(c INT) engine=innodb; + +connect con1, localhost, root; +connection default; + +set debug_sync='before_get_quick_record_count SIGNAL target_ready WAIT_FOR target_continue'; +let $id=`select connection_id()`; + +send +explain format=json +update t20,(SELECT * FROM t10)t (a, c) + set t20.c=t.c+10 where t20.c = t.c and t.a >= 3; + +connection con1; +set debug_sync='now WAIT_FOR target_ready'; +evalp kill query $id; + +connection default; +--error ER_QUERY_INTERRUPTED +reap; + +disconnect con1; + +drop table t10, t20; + +set debug_sync='reset'; diff --git a/mysql-test/main/limit_rows_examined.result b/mysql-test/main/limit_rows_examined.result index cd2f00fcec8ba..0ced7eeb089c3 100644 --- a/mysql-test/main/limit_rows_examined.result +++ b/mysql-test/main/limit_rows_examined.result @@ -773,7 +773,6 @@ LIMIT ROWS EXAMINED 124; field1 field2 field3 field4 field5 Warnings: Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 124. The query result may be incomplete -Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 124. The query result may be incomplete SHOW STATUS LIKE 'Handler_read%'; Variable_name Value Handler_read_first 1 @@ -932,3 +931,14 @@ Warnings: Warning 1931 Query execution was interrupted. The query exceeded LIMIT ROWS EXAMINED 100. The query result may be incomplete DROP TABLE t1, t2; # End of 10.5 tests +# +# MDEV-22241: Assertion `0' failed in Protocol::end_statement after query with LIMIT ROWS EXAMINED +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1); +SELECT 1 FROM t1 +WHERE (1 IN (SELECT 8 UNION SELECT 5)) OR t1.a = 2 +LIMIT ROWS EXAMINED 1; +1 +DROP TABLE t1; +# End of 10.11 tests diff --git a/mysql-test/main/limit_rows_examined.test b/mysql-test/main/limit_rows_examined.test index e79f1fc036019..2fe7ef24fe8c6 100644 --- a/mysql-test/main/limit_rows_examined.test +++ b/mysql-test/main/limit_rows_examined.test @@ -658,3 +658,18 @@ SELECT COUNT(*) FROM t1 JOIN t2 ON (b = a) UNION DISTINCT SELECT COUNT(*) FROM t DROP TABLE t1, t2; --echo # End of 10.5 tests + +--echo # +--echo # MDEV-22241: Assertion `0' failed in Protocol::end_statement after query with LIMIT ROWS EXAMINED +--echo # + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (1); + +SELECT 1 FROM t1 +WHERE (1 IN (SELECT 8 UNION SELECT 5)) OR t1.a = 2 +LIMIT ROWS EXAMINED 1; + +DROP TABLE t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/lock.result b/mysql-test/main/lock.result index b5f379e857564..903b5739cdab0 100644 --- a/mysql-test/main/lock.result +++ b/mysql-test/main/lock.result @@ -1,4 +1,3 @@ -drop table if exists t1,t2,t3; CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`)) ENGINE=MyISAM; insert into t1 (id,id2) values (1,1),(1,2),(1,3); LOCK TABLE t1 WRITE; @@ -469,9 +468,7 @@ connection default; UNLOCK TABLES; DROP TABLE t1, t2; disconnect con2; -# # End of 6.0 tests. -# create table t1 (a int) engine=myisam; lock tables t1 write concurrent, t1 as t2 read; connect con1,localhost,root,,; diff --git a/mysql-test/main/lock.test b/mysql-test/main/lock.test index 41cc9f8061b9a..ccd2a017a38f9 100644 --- a/mysql-test/main/lock.test +++ b/mysql-test/main/lock.test @@ -2,14 +2,9 @@ # Testing of table locking # +--source include/no_view_protocol.inc --source include/have_partition.inc -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc - ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings CREATE TABLE t1 ( `id` int(11) NOT NULL default '0', `id2` int(11) NOT NULL default '0', `id3` int(11) NOT NULL default '0', `dummy1` char(30) default NULL, PRIMARY KEY (`id`,`id2`), KEY `index_id3` (`id3`)) ENGINE=MyISAM; insert into t1 (id,id2) values (1,1),(1,2),(1,3); LOCK TABLE t1 WRITE; @@ -566,14 +561,8 @@ UNLOCK TABLES; DROP TABLE t1, t2; disconnect con2; - ---echo # --echo # End of 6.0 tests. ---echo # -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc # # Test concurrent lock and read locks # This gave a warning: diff --git a/mysql-test/main/lock_multi.result b/mysql-test/main/lock_multi.result index 52196d835ec79..361e1c63bfdf7 100644 --- a/mysql-test/main/lock_multi.result +++ b/mysql-test/main/lock_multi.result @@ -1,5 +1,3 @@ -drop table if exists t1,t2; -drop DATABASE if exists mysqltest_1; connect locker,localhost,root,,; connect locker2,localhost,root,,; connect reader,localhost,root,,; @@ -176,9 +174,7 @@ disconnect con2; DROP DATABASE mysqltest_1; ERROR HY000: Can't drop database 'mysqltest_1'; database doesn't exist connection locker; -set sql_mode=""; -create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; -set sql_mode=default; +create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)); lock tables t1 write; connection writer; alter table t1 auto_increment=0; @@ -289,7 +285,6 @@ disconnect locker; disconnect locker2; disconnect reader; disconnect writer; -drop table if exists t1; create table t1 (i int); connect flush,localhost,root,,test,,; connection default; @@ -315,7 +310,6 @@ i j drop table t1; disconnect flush; disconnect insert; -drop table if exists t1; create table t1 (i int); connect flush,localhost,root,,test,,; connection default; @@ -329,7 +323,6 @@ connection flush; connection default; disconnect flush; drop table t1; -drop table if exists t1,t2; create table t1 (a int); flush status; lock tables t1 read; @@ -346,7 +339,6 @@ select @tlwa < @tlwb; @tlwa < @tlwb 1 End of 5.1 tests -drop table if exists t1; create table t1 (i int); connect flush,localhost,root,,test,,; connection default; @@ -362,7 +354,6 @@ disconnect flush; # # Test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock". # -drop table if exists t1; create table t1 (c1 int primary key, c2 int, c3 int); insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0); begin; @@ -390,8 +381,6 @@ drop table t1; # # Bug#47249 assert in MDL_global_lock::is_lock_type_compatible # -DROP TABLE IF EXISTS t1; -DROP VIEW IF EXISTS v1; # # Test 1: LOCK TABLES v1 WRITE, t1 READ; # @@ -426,8 +415,6 @@ DROP VIEW v1; # Test for bug #50913 "Deadlock between open_and_lock_tables_derived # and MDL". Also see additional coverage in mdl_sync.test. # -drop table if exists t1; -drop view if exists v1; connect con50913,localhost,root; connection default; create table t1 (i int); @@ -477,7 +464,6 @@ drop table t1; # These tests also provide function coverage for the # lock_wait_timeout server variable. # -DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id int); connect con2, localhost, root,,; SET SESSION lock_wait_timeout= 1; @@ -570,7 +556,6 @@ disconnect con3; # Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent # DDL workload". # -drop tables if exists t1, t2, t3; connect con1, localhost, root, , ; connect con2, localhost, root, , ; connection default; @@ -602,7 +587,6 @@ drop table t3; # even if the table to altered was temporary. # Bug found while working on the related bug #51240. # -DROP TABLE IF EXISTS t1; CREATE TABLE t1 (id INT); LOCK TABLE t1 WRITE; connect con1, localhost, root; diff --git a/mysql-test/main/lock_multi.test b/mysql-test/main/lock_multi.test index a9a9341b82d15..3ab3906a10838 100644 --- a/mysql-test/main/lock_multi.test +++ b/mysql-test/main/lock_multi.test @@ -1,13 +1,7 @@ -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - ---disable_warnings -drop table if exists t1,t2; -drop DATABASE if exists mysqltest_1; ---enable_warnings - # Test to see if select will get the lock ahead of low priority update +--source include/no_view_protocol.inc + --disable_ps2_protocol connect (locker,localhost,root,,); connect (locker2,localhost,root,,); @@ -326,11 +320,7 @@ DROP DATABASE mysqltest_1; # connection locker; # Disable warnings to allow test to run also without InnoDB -set sql_mode=""; ---disable_warnings -create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)) engine=innodb; ---enable_warnings -set sql_mode=default; +create table t1 (f1 int(12) unsigned not null auto_increment, primary key(f1)); lock tables t1 write; connection writer; send @@ -546,9 +536,6 @@ disconnect writer; # Test ALTER TABLE under LOCK TABLES and FLUSH TABLES WITH READ LOCK # ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (i int); connect (flush,localhost,root,,test,,); connection default; @@ -602,9 +589,6 @@ disconnect insert; # from a impending FLUSH TABLES WITH READ LOCK # ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (i int); connect (flush,localhost,root,,test,,); connection default; @@ -632,9 +616,6 @@ drop table t1; # Bug#30331 Table_locks_waited shows inaccurate values # ---disable_warnings -drop table if exists t1,t2; ---enable_warnings create table t1 (a int); flush status; lock tables t1 read; @@ -668,9 +649,6 @@ select @tlwa < @tlwb; # WITH READ LOCK # ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (i int); connect (flush,localhost,root,,test,,); connection default; @@ -697,9 +675,6 @@ disconnect flush; --echo # --echo # Test for bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock". --echo # ---disable_warnings -drop table if exists t1; ---enable_warnings create table t1 (c1 int primary key, c2 int, c3 int); insert into t1 values (1,1,0),(2,2,0),(3,3,0),(4,4,0),(5,5,0); begin; @@ -742,11 +717,6 @@ drop table t1; --echo # Bug#47249 assert in MDL_global_lock::is_lock_type_compatible --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; -DROP VIEW IF EXISTS v1; ---enable_warnings - --echo # --echo # Test 1: LOCK TABLES v1 WRITE, t1 READ; --echo # @@ -759,7 +729,6 @@ connect (con2,localhost,root); LOCK TABLES v1 WRITE, t1 READ; FLUSH TABLE t1; disconnect con2; ---source include/wait_until_disconnected.inc --echo # Connection 1 connection default; @@ -781,7 +750,6 @@ connect (con2,localhost,root); LOCK TABLES t1 WRITE, v1 READ; FLUSH TABLE t1; disconnect con2; ---source include/wait_until_disconnected.inc connection default; LOCK TABLES t1 WRITE; @@ -796,10 +764,6 @@ DROP VIEW v1; --echo # Test for bug #50913 "Deadlock between open_and_lock_tables_derived --echo # and MDL". Also see additional coverage in mdl_sync.test. --echo # ---disable_warnings -drop table if exists t1; -drop view if exists v1; ---enable_warnings connect (con50913,localhost,root); connection default; create table t1 (i int); @@ -870,10 +834,6 @@ drop table t1; --echo # lock_wait_timeout server variable. --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1 (id int); connect(con2, localhost, root,,); @@ -1012,9 +972,6 @@ disconnect con3; --echo # Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent --echo # DDL workload". --echo # ---disable_warnings -drop tables if exists t1, t2, t3; ---enable_warnings connect (con1, localhost, root, , ); connect (con2, localhost, root, , ); connection default; @@ -1063,10 +1020,6 @@ drop table t3; --echo # Bug found while working on the related bug #51240. --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - CREATE TABLE t1 (id INT); LOCK TABLE t1 WRITE; @@ -1079,7 +1032,3 @@ connection default; disconnect con1; UNLOCK TABLES; DROP TABLE t1; - - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/lock_multi_bug38499.result b/mysql-test/main/lock_multi_bug38499.result index de552ca08725a..5ce54174ee84b 100644 --- a/mysql-test/main/lock_multi_bug38499.result +++ b/mysql-test/main/lock_multi_bug38499.result @@ -3,7 +3,6 @@ SET @@global.sync_frm = OFF; connect locker,localhost,root,,; connect writer,localhost,root,,; connection default; -DROP TABLE IF EXISTS t1; CREATE TABLE t1( a INT, b INT ); CREATE TABLE t2( a INT, b INT ); INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4); @@ -31,3 +30,4 @@ DROP TABLE t1,t2; disconnect locker; disconnect writer; SET @@global.sync_frm = @odl_sync_frm; +# End of 5.0 tests diff --git a/mysql-test/main/lock_multi_bug38499.test b/mysql-test/main/lock_multi_bug38499.test index 9122b453eb298..2c934d77ce5b0 100644 --- a/mysql-test/main/lock_multi_bug38499.test +++ b/mysql-test/main/lock_multi_bug38499.test @@ -5,9 +5,6 @@ # The test can take hours with valgrind --source include/not_valgrind.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - SET @odl_sync_frm = @@global.sync_frm; SET @@global.sync_frm = OFF; @@ -15,9 +12,6 @@ connect (locker,localhost,root,,); connect (writer,localhost,root,,); --connection default ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings CREATE TABLE t1( a INT, b INT ); CREATE TABLE t2( a INT, b INT ); INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4); @@ -224,8 +218,4 @@ DROP TABLE t1,t2; SET @@global.sync_frm = @odl_sync_frm; -# End of 5.0 tests - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - +--echo # End of 5.0 tests diff --git a/mysql-test/main/lock_multi_bug38691.test b/mysql-test/main/lock_multi_bug38691.test index 745995f602634..c5285d9c7cb3a 100644 --- a/mysql-test/main/lock_multi_bug38691.test +++ b/mysql-test/main/lock_multi_bug38691.test @@ -7,9 +7,6 @@ # The test can take hours with valgrind --source include/not_valgrind.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - SET @odl_sync_frm = @@global.sync_frm; SET @@global.sync_frm = OFF; @@ -142,7 +139,3 @@ DROP TABLE t1, t2, t3; --disconnect writer SET @@global.sync_frm = @odl_sync_frm; - -# Wait till all disconnects are completed ---source include/wait_until_count_sessions.inc - diff --git a/mysql-test/main/lock_sync.result b/mysql-test/main/lock_sync.result index 8398b54b46550..0404741cd0bfe 100644 --- a/mysql-test/main/lock_sync.result +++ b/mysql-test/main/lock_sync.result @@ -734,22 +734,21 @@ SET DEBUG_SYNC="RESET"; # # Bug#57130 crash in Item_field::print during SHOW CREATE TABLE or VIEW # -DROP TABLE IF EXISTS t1; -DROP VIEW IF EXISTS v1; -DROP FUNCTION IF EXISTS f1; CREATE TABLE t1(a INT); CREATE FUNCTION f1() RETURNS INTEGER RETURN 1; CREATE VIEW v1 AS SELECT * FROM t1 WHERE f1() = 1; DROP FUNCTION f1; connect con2, localhost, root; connect con1, localhost, root; -SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped EXECUTE 2'; +SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped EXECUTE 3'; # Sending: SHOW CREATE VIEW v1; connection con2; SET DEBUG_SYNC= 'now WAIT_FOR opened'; SET DEBUG_SYNC= 'now SIGNAL dropped'; SET DEBUG_SYNC= 'now WAIT_FOR opened'; +SET DEBUG_SYNC= 'now SIGNAL dropped'; +SET DEBUG_SYNC= 'now WAIT_FOR opened'; # Sending: FLUSH TABLES t1; connection default; @@ -840,3 +839,37 @@ SET DEBUG_SYNC="RESET"; disconnect con1; disconnect con2; DROP TABLES t1, t2; +# +# MDEV-28567 Assertion `0' in open_tables upon function-related operation +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW UPDATE t2 SET b = 0; +CREATE TRIGGER tr2 BEFORE INSERT ON t2 FOR EACH ROW UPDATE t1 SET a = 6; +CREATE VIEW v1 AS SELECT * FROM t1; +SET AUTOCOMMIT=OFF; +SELECT * FROM t1; +a +connect con1,localhost,root,,test; +DROP TRIGGER tr1; +connection default; +INSERT INTO t2 SELECT * FROM t2; +SELECT f() FROM t2; +ERROR 42000: FUNCTION test.f does not exist +connect con2,localhost,root,,test; +set debug_sync= 'after_open_table_mdl_shared signal s1'; +ALTER VIEW v1 AS SELECT f() FROM t1; +connection con1; +CREATE FUNCTION f() RETURNS INT RETURN 1; +connection default; +set debug_sync= 'now wait_for s1'; +SELECT * FROM ( SELECT * FROM v1 ) sq; +COMMIT; +connection con2; +disconnect con1; +disconnect con2; +connection default; +DROP VIEW v1; +DROP FUNCTION IF EXISTS f; +DROP TABLE t1, t2; +set debug_sync= 'reset'; diff --git a/mysql-test/main/lock_sync.test b/mysql-test/main/lock_sync.test index ed958f1b084c1..442a24583ca05 100644 --- a/mysql-test/main/lock_sync.test +++ b/mysql-test/main/lock_sync.test @@ -12,10 +12,6 @@ # is fixed this test can't be run on embedded version of server. --source include/not_embedded.inc -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc - - --echo # --echo # Test how we handle locking in various cases when --echo # we read data from MyISAM tables. @@ -921,7 +917,6 @@ connection con1; --echo # Reaping: DROP EVENT t1 --reap disconnect con1; ---source include/wait_until_disconnected.inc connection default; DROP EVENT e2; @@ -932,12 +927,6 @@ SET DEBUG_SYNC="RESET"; --echo # Bug#57130 crash in Item_field::print during SHOW CREATE TABLE or VIEW --echo # ---disable_warnings -DROP TABLE IF EXISTS t1; -DROP VIEW IF EXISTS v1; -DROP FUNCTION IF EXISTS f1; ---enable_warnings - CREATE TABLE t1(a INT); CREATE FUNCTION f1() RETURNS INTEGER RETURN 1; CREATE VIEW v1 AS SELECT * FROM t1 WHERE f1() = 1; @@ -947,12 +936,15 @@ connect(con2, localhost, root); connect (con1, localhost, root); # Need to trigger this sync point at least twice in order to # get valgrind test failures without the patch -SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped EXECUTE 2'; +SET DEBUG_SYNC= 'open_tables_after_open_and_process_table SIGNAL opened WAIT_FOR dropped EXECUTE 3'; --echo # Sending: --send SHOW CREATE VIEW v1 connection con2; SET DEBUG_SYNC= 'now WAIT_FOR opened'; +# Increase the sync WAIT count to 3 to account for PATH resolution +SET DEBUG_SYNC= 'now SIGNAL dropped'; +SET DEBUG_SYNC= 'now WAIT_FOR opened'; SET DEBUG_SYNC= 'now SIGNAL dropped'; SET DEBUG_SYNC= 'now WAIT_FOR opened'; --echo # Sending: @@ -1028,7 +1020,6 @@ set debug_sync='RESET'; --echo # during metadata lock upgrade which happens when one tries --echo # to use LOCK TABLES ... READ LOCAL for InnoDB tables. ---enable_connect_log CREATE TABLE t1 (i INT) ENGINE=InnoDB; CREATE TABLE t2 (j INT) ENGINE=InnoDB; @@ -1074,8 +1065,122 @@ SET DEBUG_SYNC="RESET"; disconnect con1; disconnect con2; DROP TABLES t1, t2; ---disable_connect_log -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc +--echo # +--echo # MDEV-28567 Assertion `0' in open_tables upon function-related operation +--echo # +# To get MDL trace run this case like this: +# mtr --mysqld=--debug-dbug=d,mdl,query:i:o,/tmp/mdl.log ... +# Cleanup trace like this: +# sed -i -re '/(mysql|performance_schema|sys|mtr)\// d; /MDL_BACKUP_|MDL_INTENTION_/ d; /\/(t2|tr1|tr2)/ d' /tmp/mdl.log + +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT); +CREATE TRIGGER tr1 BEFORE INSERT ON t1 FOR EACH ROW UPDATE t2 SET b = 0; +CREATE TRIGGER tr2 BEFORE INSERT ON t2 FOR EACH ROW UPDATE t1 SET a = 6; +CREATE VIEW v1 AS SELECT * FROM t1; + +SET AUTOCOMMIT=OFF; +SELECT * FROM t1; +# T@6 +# Seized: test/t1 (MDL_SHARED_READ) + +--connect (con1,localhost,root,,test) +--send + DROP TRIGGER tr1; +# T@7 +# Seized: test/t1 (MDL_SHARED_NO_WRITE) +# Waiting: test/t1 (MDL_EXCLUSIVE) +# Waiting: test/t1 (MDL_SHARED_WRITE) +# Deadlock: test/t1 (MDL_SHARED_WRITE) + +--connection default +--error 0, ER_LOCK_DEADLOCK +INSERT INTO t2 SELECT * FROM t2; +# T@6 +# Released: test/t1 (MDL_SHARED_READ) +# T@7 +# Acquired: test/t1 (MDL_EXCLUSIVE) (good) +--error ER_SP_DOES_NOT_EXIST +SELECT f() FROM t2; +# T@6 +# Seized: test/f (MDL_SHARED) +# T@7 +# Released: test/t1 (MDL_EXCLUSIVE) +# Good1: continue T@6 below +# Bad1: continue T@8 below + +# Now we hold test/f, the below code creates concurrent +# waiting of 3 threads for test/f which leads to deadlock (Bad) + +# To achieve Good comment out 'now wait_for s1' below and run multiple times. + +--connect (con2,localhost,root,,test) +set debug_sync= 'after_open_table_mdl_shared signal s1'; +--send + ALTER VIEW v1 AS SELECT f() FROM t1; +# T@8 +# Good2: Waiting: test/v1 (MDL_EXCLUSIVE) +# Good2-3: continue T@7 below +# Good5: Acquired: test/v1 (MDL_EXCLUSIVE) +# Good5: Seized: test/v1 (MDL_EXCLUSIVE) +# Good5-6: continue T@7 below +# Good7: Seized: test/t1 (MDL_SHARED_READ) +# Good7: Waiting: test/f (MDL_SHARED) +# Good7-8: continue T@7 below +# Good9: Acquired: test/f (MDL_SHARED) +# Good9: Released: test/f (MDL_SHARED) +# Good9: Released: test/t1 (MDL_SHARED_READ) +# Good9: Released: test/v1 (MDL_EXCLUSIVE) +# Good9: command finished without error +# Bad1: Seized: test/v1 (MDL_EXCLUSIVE) +# Bad1: Seized: test/v1 (MDL_EXCLUSIVE) +# Bad1: Seized: test/t1 (MDL_SHARED_READ) +# Bad1-2: continue T@6 below +# Bad4: Waiting: test/f (MDL_SHARED) +# Bad4: Deadlock: test/f (MDL_SHARED) +# Bad4: command finished with error + +--connection con1 +--reap +--send +CREATE FUNCTION f() RETURNS INT RETURN 1; +# T@7 +# Good3: Waiting: test/f (MDL_EXCLUSIVE) +# Good3-4: continue T@6 below +# Good6: Acquired: test/f (MDL_EXCLUSIVE) +# Good6-7: continue T@8 above +# Good8: Released: test/f (MDL_EXCLUSIVE) +# Good8-9: continue T@8 above +# Bad3: Waiting: test/f (MDL_EXCLUSIVE) +# Bad3-4: continue T@8 above + +--connection default +set debug_sync= 'now wait_for s1'; +--disable_result_log +SELECT * FROM ( SELECT * FROM v1 ) sq; +--enable_result_log +# T@6 +# Good1: Seized: test/v1 (MDL_SHARED_READ) +# Good1-2: continue T@8 above +# Good4: Seized: test/t1 (MDL_SHARED_READ) +# Bad2: Waiting: test/v1 (MDL_SHARED_READ) +# Bad2-3: continue T@7 above + +# Cleanup +COMMIT; +# Good4: Released: test/t1 (MDL_SHARED_READ) +# Good4: Released: test/v1 (MDL_SHARED_READ) +# Good4: Released: test/f (MDL_SHARED) +# Good4-5: continue T@8 above + +--connection con2 +--error 0, ER_SP_DOES_NOT_EXIST +--reap +--disconnect con1 +--disconnect con2 +--connection default +DROP VIEW v1; +DROP FUNCTION IF EXISTS f; +DROP TABLE t1, t2; +set debug_sync= 'reset'; diff --git a/mysql-test/main/lock_tables_lost_commit.result b/mysql-test/main/lock_tables_lost_commit.result index 769e9734c7abe..d5bd9adf82e67 100644 --- a/mysql-test/main/lock_tables_lost_commit.result +++ b/mysql-test/main/lock_tables_lost_commit.result @@ -1,7 +1,6 @@ connect con1,localhost,root,,; connect con2,localhost,root,,; connection con1; -DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT) ENGINE=innodb; LOCK TABLES t1 WRITE; INSERT INTO t1 VALUES(10); @@ -13,3 +12,4 @@ a DROP TABLE t1; connection default; disconnect con2; +# End of 4.1 tests diff --git a/mysql-test/main/lock_tables_lost_commit.test b/mysql-test/main/lock_tables_lost_commit.test index 754c8f3c378f2..d125c50167d40 100644 --- a/mysql-test/main/lock_tables_lost_commit.test +++ b/mysql-test/main/lock_tables_lost_commit.test @@ -2,17 +2,11 @@ --source include/have_innodb.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - connect (con1,localhost,root,,); connect (con2,localhost,root,,); connection con1; ---disable_warnings -DROP TABLE IF EXISTS t1; CREATE TABLE t1(a INT) ENGINE=innodb; ---enable_warnings LOCK TABLES t1 WRITE; INSERT INTO t1 VALUES(10); disconnect con1; @@ -27,7 +21,4 @@ DROP TABLE t1; connection default; disconnect con2; -# End of 4.1 tests - -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc +--echo # End of 4.1 tests diff --git a/mysql-test/main/lock_user.result b/mysql-test/main/lock_user.result index 24fff2105abf1..fdde0beb3ffc5 100644 --- a/mysql-test/main/lock_user.result +++ b/mysql-test/main/lock_user.result @@ -129,6 +129,7 @@ connection default; # account is locked # alter user user1@localhost account lock; +change_user user1,,; ERROR HY000: Access denied, this account is locked # # MDEV-24098 SHOW CREATE USER invalid for both PASSWORD EXPIRE and diff --git a/mysql-test/main/lock_view.test b/mysql-test/main/lock_view.test index 4a2c66edfbebc..536b4c4fbb04f 100644 --- a/mysql-test/main/lock_view.test +++ b/mysql-test/main/lock_view.test @@ -94,5 +94,7 @@ connection default; exec $MYSQL_DUMP --no-autocommit=0 test v1 -uu1 --compact; drop view v1; drop table t1; +--disable_warnings drop user u1@localhost; +--enable_warnings --enable_service_connection diff --git a/mysql-test/main/long_unique.result b/mysql-test/main/long_unique.result index 272500a4a8e65..dcf5c06c81acc 100644 --- a/mysql-test/main/long_unique.result +++ b/mysql-test/main/long_unique.result @@ -42,8 +42,8 @@ Ignored NO MyISAM file: DATADIR/test/t1 Record format: Packed Character set: ? (0) -Data records: 10 Deleted blocks: 0 -Recordlength: 12 +Data records: 10 Deleted blocks: 0 +Recordlength: 12 table description: Key Start Len Index Type @@ -130,8 +130,8 @@ insert into t1 values(1),(2),(3),(4),(5),(8),(7); MyISAM file: DATADIR/test/t1 Record format: Packed Character set: ? (0) -Data records: 7 Deleted blocks: 0 -Recordlength: 12 +Data records: 7 Deleted blocks: 0 +Recordlength: 12 table description: Key Start Len Index Type @@ -365,8 +365,8 @@ t1 0 e 1 e A NULL NULL NULL YES HASH NO MyISAM file: DATADIR/test/t1 Record format: Packed Character set: latin1_swedish_ci (8) -Data records: 8 Deleted blocks: 0 -Recordlength: 3040 +Data records: 8 Deleted blocks: 0 +Recordlength: 3040 table description: Key Start Len Index Type @@ -722,8 +722,8 @@ t1 0 b 4 h A NULL NULL NULL YES HASH NO MyISAM file: DATADIR/test/t1 Record format: Packed Character set: latin1_swedish_ci (8) -Data records: 9 Deleted blocks: 0 -Recordlength: 5059 +Data records: 9 Deleted blocks: 0 +Recordlength: 5059 table description: Key Start Len Index Type diff --git a/mysql-test/main/long_unique_bugs.result b/mysql-test/main/long_unique_bugs.result index cb299879ce781..e5c758ce0ca7f 100644 --- a/mysql-test/main/long_unique_bugs.result +++ b/mysql-test/main/long_unique_bugs.result @@ -843,3 +843,11 @@ insert into t (a) values (1); update t set a=2; drop table t; # End of 10.6 tests +# +# MDEV-37404 InnoDB: Failing assertion: node->pcur->rel_pos == BTR_PCUR_ON +# +create table t(c int primary key, c2 blob unique) engine=innodb; +insert into t values (0, ''); +replace into t values (0, '123'); +drop table t; +# End of 10.11 tests diff --git a/mysql-test/main/long_unique_bugs.test b/mysql-test/main/long_unique_bugs.test index fff5079cb3e1a..6827a91d75b4d 100644 --- a/mysql-test/main/long_unique_bugs.test +++ b/mysql-test/main/long_unique_bugs.test @@ -767,3 +767,13 @@ update t set a=2; drop table t; --echo # End of 10.6 tests + +--echo # +--echo # MDEV-37404 InnoDB: Failing assertion: node->pcur->rel_pos == BTR_PCUR_ON +--echo # +create table t(c int primary key, c2 blob unique) engine=innodb; +insert into t values (0, ''); +replace into t values (0, '123'); +drop table t; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/long_unique_bugs_replication.result b/mysql-test/main/long_unique_bugs_replication.result index 39b0ebe26d23d..ab6674f886f6f 100644 --- a/mysql-test/main/long_unique_bugs_replication.result +++ b/mysql-test/main/long_unique_bugs_replication.result @@ -9,20 +9,64 @@ insert into t1 values (2,2); update t1 set a1 = 'd' limit 1; update t1 set a1 = 'd2' where i1= 2; connection slave; +connection slave; +select * from t1; +i1 a1 +1 d +2 d2 connection master; drop table t1; +connection slave; +connection master; # # MDEV-32093 long uniques break old->new replication # -connection slave; create table t1 (id int not null, b1 varchar(255) not null, b2 varchar(2550) not null, unique (id), unique key (b1,b2) using hash) default charset utf8mb3; set global slave_exec_mode=idempotent; binlog 'aRf2ZA8BAAAA/AAAAAABAAAAAAQAMTAuNS4xNS1NYXJpYURCLWxvZwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABpF/ZkEzgNAAgAEgAEBAQEEgAA5AAEGggAAAAICAgCAAAACgoKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEwQADQgICAoKCgFRmTlk'; binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw=='; binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A==bBf2ZBcBAAAANAAAAMwHAAAAAHEAAAAAAAEABP/wj6QAAAEAYgEAZa6/VU0JAAAANteqUw=='; binlog 'bBf2ZBMBAAAANAAAAHUkAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AaTGFIg==bBf2ZBgBAAAASAAAAL0kAAAAAHEAAAAAAAEABP//8I+kAAABAGIBAGWuv1VNCQAAAPBuWwAAAQBiAQBlrr9VTQkAAADxS9Lu'; -drop table t1; +connection slave; +select * from t1; +id b1 b2 +23406 b e +connection master; set global slave_exec_mode=default; +drop table t1; +# +# End of 10.4 tests +# +# Idempotent scenario, which triggers REPLACE code to be used in the +# event, i.e. duplicated record will be deleted and then re-inserted. +create table t1 (i1 int, a1 text, unique key i1 (a1)) engine=myisam; +connection slave; +connection slave; +set @save_slave_exec_mode= @@slave_exec_mode; +set global slave_exec_mode = idempotent; +insert into t1 values (1,1); +connection master; +insert into t1 values (2,1); +connection slave; +connection slave; +select * from t1; +i1 a1 +2 1 +connection master; +insert into t1 values (3,3); +update t1 set a1 = 'd' limit 1; +update t1 set a1 = 'd2' where i1= 3; +connection slave; +connection slave; +select * from t1; +i1 a1 +2 d +3 d2 +set global slave_exec_mode = @save_slave_exec_mode; +connection master; +drop table t1; +connection slave; +connection master; # # End of 10.4 tests # diff --git a/mysql-test/main/long_unique_bugs_replication.test b/mysql-test/main/long_unique_bugs_replication.test index 4a13326614f0d..02abf0f2ea9b6 100644 --- a/mysql-test/main/long_unique_bugs_replication.test +++ b/mysql-test/main/long_unique_bugs_replication.test @@ -16,17 +16,21 @@ update t1 set a1 = 'd' limit 1; update t1 set a1 = 'd2' where i1= 2; sync_slave_with_master; - +connection slave; +select * from t1; connection master; drop table t1; +sync_slave_with_master; +connection master; + + --echo # --echo # MDEV-32093 long uniques break old->new replication --echo # # this is technically a bug in replication, but it needs an old master # so we'll run it as a non-replicated test with BINLOG command -sync_slave_with_master; create table t1 (id int not null, b1 varchar(255) not null, b2 varchar(2550) not null, unique (id), unique key (b1,b2) using hash) default charset utf8mb3; set global slave_exec_mode=idempotent; @@ -40,10 +44,46 @@ binlog 'bBf2ZBMBAAAANAAAAJgHAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AeqMD4A== ### UPDATE t1 WHERE (42127, 'b', 'e', 39952170926) SET (23406, 'b', 'e', 39952170926) binlog 'bBf2ZBMBAAAANAAAAHUkAAAAAHEAAAAAAAEABHRlc3QAAnQxAAQDDw8IBP0C4h0AaTGFIg==bBf2ZBgBAAAASAAAAL0kAAAAAHEAAAAAAAEABP//8I+kAAABAGIBAGWuv1VNCQAAAPBuWwAAAQBiAQBlrr9VTQkAAADxS9Lu'; -drop table t1; +sync_slave_with_master; +select * from t1; +connection master; set global slave_exec_mode=default; +drop table t1; + +--echo # +--echo # End of 10.4 tests +--echo # + +--echo # Idempotent scenario, which triggers REPLACE code to be used in the +--echo # event, i.e. duplicated record will be deleted and then re-inserted. +create table t1 (i1 int, a1 text, unique key i1 (a1)) engine=myisam; + +sync_slave_with_master; +connection slave; +set @save_slave_exec_mode= @@slave_exec_mode; +set global slave_exec_mode = idempotent; +insert into t1 values (1,1); +connection master; +insert into t1 values (2,1); +sync_slave_with_master; +connection slave; +select * from t1; +connection master; +insert into t1 values (3,3); +update t1 set a1 = 'd' limit 1; +update t1 set a1 = 'd2' where i1= 3; +sync_slave_with_master; + +connection slave; +select * from t1; +set global slave_exec_mode = @save_slave_exec_mode; +connection master; +drop table t1; +sync_slave_with_master; +connection master; --echo # --echo # End of 10.4 tests --echo # + --source include/rpl_end.inc diff --git a/mysql-test/main/lowercase_fs_off.result b/mysql-test/main/lowercase_fs_off.result index e70c29593c90c..368ba572fc9e6 100644 --- a/mysql-test/main/lowercase_fs_off.result +++ b/mysql-test/main/lowercase_fs_off.result @@ -20,6 +20,7 @@ drop user 'sample'@'localhost'; drop database if exists d1; disconnect master; connection default; +# End of 4.1 tests CREATE DATABASE d1; USE d1; CREATE TABLE T1(f1 INT); diff --git a/mysql-test/main/lowercase_fs_off.test b/mysql-test/main/lowercase_fs_off.test index 54de923ddaffa..3afeb320316c0 100644 --- a/mysql-test/main/lowercase_fs_off.test +++ b/mysql-test/main/lowercase_fs_off.test @@ -3,6 +3,7 @@ # i.e. lower_case_filesystem=OFF # -- source include/have_case_sensitive_file_system.inc +-- source include/have_lowercase0.inc -- source include/not_embedded.inc -- source include/have_perfschema.inc @@ -22,16 +23,14 @@ create database d2; --error ER_DBACCESS_DENIED_ERROR create database D1; disconnect sample; ---source include/wait_until_disconnected.inc connection master; drop user 'sample'@'localhost'; drop database if exists d1; disconnect master; ---source include/wait_until_disconnected.inc connection default; -# End of 4.1 tests +--echo # End of 4.1 tests # # Bug#41049 does syntax "grant" case insensitive? diff --git a/mysql-test/main/lowercase_table.test b/mysql-test/main/lowercase_table.test index fcd98f32fb57e..85f9bbe4da087 100644 --- a/mysql-test/main/lowercase_table.test +++ b/mysql-test/main/lowercase_table.test @@ -1,3 +1,4 @@ +--source include/have_lowercase1.inc # # Test of --lower-case-table-names # diff --git a/mysql-test/main/lowercase_table4.result b/mysql-test/main/lowercase_table4.result index 422c2744af878..8ff0c07783f70 100644 --- a/mysql-test/main/lowercase_table4.result +++ b/mysql-test/main/lowercase_table4.result @@ -73,8 +73,8 @@ Create Table CREATE TABLE `Product_Order` ( PRIMARY KEY (`No`), KEY `Product_Category` (`Product_Category`,`Product_Id`), KEY `Customer_Id` (`Customer_Id`), - CONSTRAINT `product_order_ibfk_1` FOREIGN KEY (`Product_Category`, `Product_Id`) REFERENCES `Product` (`Category`, `Id`) ON UPDATE CASCADE, - CONSTRAINT `product_order_ibfk_2` FOREIGN KEY (`Customer_Id`) REFERENCES `Customer` (`Id`) + CONSTRAINT `1` FOREIGN KEY (`Product_Category`, `Product_Id`) REFERENCES `Product` (`Category`, `Id`) ON UPDATE CASCADE, + CONSTRAINT `2` FOREIGN KEY (`Customer_Id`) REFERENCES `Customer` (`Id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci SHOW CREATE TABLE Product; Table Product @@ -93,7 +93,7 @@ Create Table CREATE TABLE `Customer` ( SELECT * FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA='test'; CONSTRAINT_CATALOG def CONSTRAINT_SCHEMA test -CONSTRAINT_NAME product_order_ibfk_1 +CONSTRAINT_NAME 1 UNIQUE_CONSTRAINT_CATALOG def UNIQUE_CONSTRAINT_SCHEMA test UNIQUE_CONSTRAINT_NAME PRIMARY @@ -104,7 +104,7 @@ TABLE_NAME Product_Order REFERENCED_TABLE_NAME Product CONSTRAINT_CATALOG def CONSTRAINT_SCHEMA test -CONSTRAINT_NAME product_order_ibfk_2 +CONSTRAINT_NAME 2 UNIQUE_CONSTRAINT_CATALOG def UNIQUE_CONSTRAINT_SCHEMA test UNIQUE_CONSTRAINT_NAME PRIMARY diff --git a/mysql-test/main/lowercase_table_grant.test b/mysql-test/main/lowercase_table_grant.test index 2f98f570e29ef..2a791c1a4bb18 100644 --- a/mysql-test/main/lowercase_table_grant.test +++ b/mysql-test/main/lowercase_table_grant.test @@ -1,5 +1,6 @@ # Don't test with embedded server -- source include/not_embedded.inc +-- source include/have_lowercase1.inc # Test of grants when lower_case_table_names is on use mysql; diff --git a/mysql-test/main/lowercase_table_qcache.test b/mysql-test/main/lowercase_table_qcache.test index ceff271935325..4304ba0acdc86 100644 --- a/mysql-test/main/lowercase_table_qcache.test +++ b/mysql-test/main/lowercase_table_qcache.test @@ -2,6 +2,7 @@ # # Test of query cache with --lower-case-table-names # +-- source include/have_lowercase1.inc -- source include/no_view_protocol.inc set @save_query_cache_size=@@query_cache_size; diff --git a/mysql-test/main/lowercase_utf8.test b/mysql-test/main/lowercase_utf8.test index 01b154598fd06..726967f89e296 100644 --- a/mysql-test/main/lowercase_utf8.test +++ b/mysql-test/main/lowercase_utf8.test @@ -1,3 +1,4 @@ +--source include/have_lowercase1.inc # # Bug#25830 SHOW TABLE STATUS behaves differently depending on table name # diff --git a/mysql-test/main/lowercase_view.test b/mysql-test/main/lowercase_view.test index 52aae7b2b3c04..f22e76e6d6ac6 100644 --- a/mysql-test/main/lowercase_view.test +++ b/mysql-test/main/lowercase_view.test @@ -1,3 +1,5 @@ +--source include/have_lowercase1.inc + --disable_warnings drop table if exists t1Aa,t2Aa,v1Aa,v2Aa; drop view if exists t1Aa,t2Aa,v1Aa,v2Aa; diff --git a/mysql-test/main/mariadb-import.result b/mysql-test/main/mariadb-import.result index 5d1dda0759191..75bfae7040a4d 100644 --- a/mysql-test/main/mariadb-import.result +++ b/mysql-test/main/mariadb-import.result @@ -225,7 +225,7 @@ child CREATE TABLE `child` ( `c` char(4) DEFAULT NULL, UNIQUE KEY `c` (`c`), KEY `par_ind` (`parent_id`), - CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE, + CONSTRAINT `1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`) ON DELETE CASCADE, CONSTRAINT `CONSTRAINT_1` CHECK (`c` >= 'a') ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci drop database db2; @@ -262,6 +262,7 @@ db2.parent: Records: 2 Deleted: 0 Skipped: 0 Warnings: 0 drop database db2; create database db2; use db2; +set rand_seed1=1, rand_seed2=2; create table vec (id int auto_increment primary key, v vector(5) not null, vector index (v)) ENGINE=InnoDB; insert vec(v) values (x'e360d63ebe554f3fcdbc523f4522193f5236083d'), @@ -386,3 +387,39 @@ use test; mariadb-import: Path 'MYSQLTEST_VARDIR/tmp/non_existing' specified by option '--dir' does not exist # Test too many threads, builtin limit 256 Too many connections, max value for --parallel is 256 +# MDEV-37483 mariadb-dump --dir doesn't convert db names +create database `con_schöne_grüße`; +create table `con_schöne_grüße`.t(a int) select 1 as a; +create database `com1`; +create table `com1`.t(b int) select 2 as b; +create database `con/bar`; +create table `con/bar`.t select 3 as c; +create database `con@fame`; +create table `con@fame`.t (d int) select 4 as d; +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; +com1@@@ +con@002fbar +con@fame +con_sch@0j@00b6ne_gr@0j@00bc@0j@1re +# +# Check if expected tables were correctly restored +# +select * from `con_schöne_grüße`.t; +a +1 +select * from `com1`.t; +b +2 +select * from `con/bar`.t; +c +3 +select * from `con@fame`.t; +d +4 +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; diff --git a/mysql-test/main/mariadb-import.test b/mysql-test/main/mariadb-import.test index b5867374180d5..c3d967218b6b1 100644 --- a/mysql-test/main/mariadb-import.test +++ b/mysql-test/main/mariadb-import.test @@ -106,6 +106,7 @@ drop database db2; drop database db2; create database db2; use db2; +set rand_seed1=1, rand_seed2=2; # Test with vector/fulltext/spatial indexes create table vec (id int auto_increment primary key, v vector(5) not null, @@ -128,6 +129,14 @@ create spatial index idx_geom on locations (geom); insert into locations (geom) values (ST_GeomFromText('POINT(40.785091 -73.968285)')); --mkdir $MYSQLTEST_VARDIR/tmp/dump --exec $MYSQL_DUMP --dir=$MYSQLTEST_VARDIR/tmp/dump db2 + +# vector index uses randomization when building the index +# so unless one sets rand_seed variables, results are inherently +# non-repeatable +--append_file $MYSQLTEST_VARDIR/tmp/dump/db2/vec.sql +set rand_seed1=1, rand_seed2=2; +EOF + --echo # use --verbose to see "Adding secondary indexes" in the output --replace_result $MYSQLTEST_VARDIR vardir --exec $MYSQL_IMPORT --verbose --dir $MYSQLTEST_VARDIR/tmp/dump --database=db2 @@ -226,3 +235,43 @@ use test; --exec $MYSQL_IMPORT --dir $MYSQLTEST_VARDIR/tmp/dump --parallel=300 2>&1 --rmdir $MYSQLTEST_VARDIR/tmp/dump + +--echo # MDEV-37483 mariadb-dump --dir doesn't convert db names + +create database `con_schöne_grüße`; +create table `con_schöne_grüße`.t(a int) select 1 as a; +create database `com1`; +create table `com1`.t(b int) select 2 as b; +create database `con/bar`; +create table `con/bar`.t select 3 as c; +create database `con@fame`; +create table `con@fame`.t (d int) select 4 as d; + +--mkdir $MYSQLTEST_VARDIR/tmp/dump +--exec $MYSQL_DUMP --dir=$MYSQLTEST_VARDIR/tmp/dump --all-databases + +--move_file $MYSQLTEST_VARDIR/tmp/dump/con@0040fame $MYSQLTEST_VARDIR/tmp/dump/con@fame + +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; + +--exec $MYSQL_IMPORT --dir $MYSQLTEST_VARDIR/tmp/dump --silent + +--lowercase_result +--list_files $MYSQLTEST_VARDIR/tmp/dump co* + +--echo # +--echo # Check if expected tables were correctly restored +--echo # + +select * from `con_schöne_grüße`.t; +select * from `com1`.t; +select * from `con/bar`.t; +select * from `con@fame`.t; + +drop database `con_schöne_grüße`; +drop database `com1`; +drop database `con/bar`; +drop database `con@fame`; diff --git a/mysql-test/main/master_retry_count_basic.result b/mysql-test/main/master_retry_count_basic.result index b274d285b32d6..3e8b33326aba6 100644 --- a/mysql-test/main/master_retry_count_basic.result +++ b/mysql-test/main/master_retry_count_basic.result @@ -1,14 +1,7 @@ -# Use `--master-retry-count` when not specified -CHANGE MASTER 'named' TO master_host='example.com'; -CHANGE MASTER TO master_host='127.0.0.1', master_ssl_verify_server_cert=0; -SELECT Connection_name, Master_Retry_Count -FROM information_schema.SLAVE_STATUS; -Connection_name Master_Retry_Count - 1 -named 1 -# Replace when specified -CHANGE MASTER 'named' TO master_retry_count=11; -CHANGE MASTER TO master_retry_count=10; +# Replace `--master-retry-count` when specified +CHANGE MASTER 'named' TO master_retry_count=11, master_host='example.com'; +CHANGE MASTER TO master_retry_count=10, +master_host='127.0.0.1', master_ssl_verify_server_cert=0; SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; Connection_name Master_Retry_Count @@ -49,17 +42,17 @@ FROM information_schema.SLAVE_STATUS; Connection_name Master_Retry_Count 10 named 11 -# 0 internally means "not specified" +# 0 does not mean "not specified" CHANGE MASTER TO master_retry_count=0; CHANGE MASTER 'named' TO master_retry_count=0; SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; Connection_name Master_Retry_Count - 10 -named 11 + 0 +named 0 # Truncates decimals -CHANGE MASTER TO master_retry_count=0.5; -CHANGE MASTER 'named' TO master_retry_count=0.5; +CHANGE MASTER TO master_retry_count=10.75; +CHANGE MASTER 'named' TO master_retry_count=11.25; SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; Connection_name Master_Retry_Count @@ -68,12 +61,11 @@ named 11 # Caps values (such as UINT64_MAX + 1) to `--master-retry-count`'s max CHANGE MASTER TO master_retry_count=18446744073709551616; CHANGE MASTER 'named' TO master_retry_count=18446744073709551616; -SELECT Connection_name -FROM information_schema.SLAVE_STATUS -WHERE Master_Retry_Count IN (4294967295, 18446744073709551615); -Connection_name - -named +SELECT Connection_name, Master_Retry_Count +FROM information_schema.SLAVE_STATUS; +Connection_name Master_Retry_Count + 18446744073709551615 +named 18446744073709551615 # Negative CHANGE MASTER TO master_retry_count=-1; 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 '-1' at line 1 diff --git a/mysql-test/main/master_retry_count_basic.test b/mysql-test/main/master_retry_count_basic.test index 8e7fc110ed53c..1aaf61d9fc6c9 100644 --- a/mysql-test/main/master_retry_count_basic.test +++ b/mysql-test/main/master_retry_count_basic.test @@ -1,18 +1,15 @@ # MDEV-25674: Test the `Master_Retry_Count` field of -# CHANGE MASTER [name] TO and SHOW SLAVE [name] STATUS & co. (no feature testing) -# Two connections tests that the field is now per-connection. +# `CHANGE MASTER [name] TO` and `SHOW SLAVE [name] STATUS` & co.. +# feature testing is in `multi_source.connects_tried` and +# `--master-retry-count` testing is in `main.change_master_default`. +# The use of two connections tests that the field is now per-connection. --source include/have_perfschema.inc ---echo # Use `--master-retry-count` when not specified -CHANGE MASTER 'named' TO master_host='example.com'; -CHANGE MASTER TO master_host='127.0.0.1', master_ssl_verify_server_cert=0; -SELECT Connection_name, Master_Retry_Count - FROM information_schema.SLAVE_STATUS; - ---echo # Replace when specified -CHANGE MASTER 'named' TO master_retry_count=11; +--echo # Replace `--master-retry-count` when specified +CHANGE MASTER 'named' TO master_retry_count=11, master_host='example.com'; # Default master does not replace named master -CHANGE MASTER TO master_retry_count=10; +CHANGE MASTER TO master_retry_count=10, + master_host='127.0.0.1', master_ssl_verify_server_cert=0; # check-testcase SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; @@ -46,24 +43,23 @@ CHANGE MASTER 'named' TO master_user='root'; SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; ---echo # 0 internally means "not specified" +--echo # 0 does not mean "not specified" CHANGE MASTER TO master_retry_count=0; CHANGE MASTER 'named' TO master_retry_count=0; SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; --echo # Truncates decimals -CHANGE MASTER TO master_retry_count=0.5; -CHANGE MASTER 'named' TO master_retry_count=0.5; +CHANGE MASTER TO master_retry_count=10.75; +CHANGE MASTER 'named' TO master_retry_count=11.25; SELECT Connection_name, Master_Retry_Count FROM information_schema.SLAVE_STATUS; --echo # Caps values (such as UINT64_MAX + 1) to `--master-retry-count`'s max CHANGE MASTER TO master_retry_count=18446744073709551616; CHANGE MASTER 'named' TO master_retry_count=18446744073709551616; -SELECT Connection_name - FROM information_schema.SLAVE_STATUS - WHERE Master_Retry_Count IN (4294967295, 18446744073709551615); +SELECT Connection_name, Master_Retry_Count + FROM information_schema.SLAVE_STATUS; --echo # Negative --error ER_PARSE_ERROR diff --git a/mysql-test/main/max_password_errors.result b/mysql-test/main/max_password_errors.result index 9ee7d0d448d74..ba74a88503a58 100644 --- a/mysql-test/main/max_password_errors.result +++ b/mysql-test/main/max_password_errors.result @@ -25,8 +25,11 @@ connect(localhost,u,bad_pass,test,MASTER_PORT,MASTER_SOCKET); connect con1, localhost, u, bad_pass; ERROR 28000: Access denied for user 'u'@'localhost' (using password: YES) connect con1, localhost, u, good_pass; +change_user u,bad_pass,; ERROR 28000: Access denied for user 'u'@'localhost' (using password: YES) +change_user u,bad_pass,; ERROR 28000: Access denied for user 'u'@'localhost' (using password: YES) +change_user u,good_pass,; ERROR HY000: User is blocked because of too many credential errors; unblock with 'ALTER USER / FLUSH PRIVILEGES' disconnect con1; connection default; diff --git a/mysql-test/main/max_session_mem_used.result b/mysql-test/main/max_session_mem_used.result new file mode 100644 index 0000000000000..90c6bbb45eb5b --- /dev/null +++ b/mysql-test/main/max_session_mem_used.result @@ -0,0 +1,139 @@ +# +# MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in +# Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) +# +CREATE TABLE t1 (a INT); +SELECT * FROM t1; +a +ALTER TABLE x MODIFY xx INT; +ERROR 42S02: Table 'test.x' doesn't exist +SET SESSION max_session_mem_used= 8192; +LOCK TABLE t1 WRITE; +ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT; +SET SESSION max_session_mem_used = DEFAULT; +UNLOCK TABLES; +DROP TABLE t1; +# +# MDEV-27978 wrong option name in error when exceeding max_session_mem_used +# +SET SESSION max_session_mem_used = 8192; +SELECT * FROM information_schema.processlist; +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET SESSION max_session_mem_used = DEFAULT; +set max_session_mem_used = 50000; +select * from seq_1_to_1000; +set max_session_mem_used = 8192; +select * from seq_1_to_1000; +set max_session_mem_used = DEFAULT; +# +# MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself +# +CREATE TEMPORARY TABLE t1 (a INT,b INT); +INSERT INTO t1 VALUES (1,1),(2,2); +SET max_session_mem_used=8192; +SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1; +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET max_session_mem_used=DEFAULT; +DROP TABLE t1; +# +# MDEV-23824 SIGSEGV in end_io_cache on REPAIR LOCAL TABLE for Aria table +# +CREATE TABLE t1 (i INT) ENGINE=Aria; +INSERT INTO t1 VALUES (1); +SET max_session_mem_used=50000; +REPAIR LOCAL TABLE t1 USE_FRM; +REPAIR LOCAL TABLE t1; +DROP TABLE t1; +SET max_session_mem_used=default; +# +# MDEV-38005 Assertion `(yyvsp[-3].simple_string) < (yyvsp[-1].simple_string)' failed +# +SET max_session_mem_used=1; +Warnings: +Warning 1292 Truncated incorrect max_session_mem_used value: '1' +CREATE TABLE t SELECT 1000000000000000000000000000000000000000000000000000000000000000000000000000000001 AS c; +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET max_session_mem_used=default; +# End of 10.6 tests +# +# MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params +# +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func()) +BEGIN +SELECT x; +END; +// +SET SESSION max_session_mem_used=8192; +CALL p0(); +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET @@max_session_mem_used=DEFAULT; +CALL p0(); +ERROR 42000: FUNCTION test.func does not exist +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE `func`() +# with func() defined +CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT +BEGIN +RETURN x; +END; +// +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func()) +BEGIN +SELECT x; +END; +// +SET SESSION max_session_mem_used=8192; +CALL p0(); +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET @@max_session_mem_used=DEFAULT; +CALL p0(); +x +10 +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE `func`() +# with multiple functions +CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT +BEGIN +RETURN x; +END; +// +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2()) +BEGIN +SELECT x, y; +END; +// +SET SESSION max_session_mem_used=8192; +CALL p0(); +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET @@max_session_mem_used=DEFAULT; +CALL p0(); +x y +10 10 +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE `func`() +def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE `func2`() +# with function and constant default param +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10) +BEGIN +SELECT x, y, z; +END; +// +SET SESSION max_session_mem_used=8192; +CALL p0(); +ERROR HY000: The MariaDB server is running with the --max-session-mem-used=8192 option so it cannot execute this statement +SET @@max_session_mem_used=DEFAULT; +CALL p0(); +x y z +10 10 10 +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; +SPECIFIC_CATALOG SPECIFIC_SCHEMA SPECIFIC_NAME ORDINAL_POSITION PARAMETER_MODE PARAMETER_NAME DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE DATETIME_PRECISION CHARACTER_SET_NAME COLLATION_NAME DTD_IDENTIFIER ROUTINE_TYPE PARAMETER_DEFAULT +def test p0 1 IN x int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE `func`() +def test p0 2 IN y int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE `func2`() +def test p0 3 IN z int NULL NULL 10 0 NULL NULL NULL int(11) PROCEDURE 10 +DROP PROCEDURE p0; +DROP FUNCTION func; +DROP FUNCTION func2; +# End of 11.8 tests diff --git a/mysql-test/main/max_session_mem_used.test b/mysql-test/main/max_session_mem_used.test new file mode 100644 index 0000000000000..d05c05b9987bf --- /dev/null +++ b/mysql-test/main/max_session_mem_used.test @@ -0,0 +1,188 @@ +# memory usage is sensitive to valgrind/ps-protocol/embedded +source include/not_msan.inc; +# We cannot use valgrind build as it uses more memory than normal build +source include/not_valgrind_build.inc; +source include/no_protocol.inc; +source include/not_embedded.inc; +source include/have_64bit.inc; +source include/have_sequence.inc; + +--echo # +--echo # MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in +--echo # Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) +--echo # + +CREATE TABLE t1 (a INT); +SELECT * FROM t1; + +--error ER_NO_SUCH_TABLE +ALTER TABLE x MODIFY xx INT; + +SET SESSION max_session_mem_used= 8192; +--error 0,ER_OPTION_PREVENTS_STATEMENT +LOCK TABLE t1 WRITE; + +--disable_warnings +--error 0,ER_OPTION_PREVENTS_STATEMENT +ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT; +--enable_warnings + +SET SESSION max_session_mem_used = DEFAULT; +UNLOCK TABLES; +DROP TABLE t1; + +--echo # +--echo # MDEV-27978 wrong option name in error when exceeding max_session_mem_used +--echo # +SET SESSION max_session_mem_used = 8192; +--error ER_OPTION_PREVENTS_STATEMENT +SELECT * FROM information_schema.processlist; +SET SESSION max_session_mem_used = DEFAULT; + +# +# errors caused by max_session_mem_used +# +--disable_result_log +set max_session_mem_used = 50000; +--error 0,ER_OPTION_PREVENTS_STATEMENT +select * from seq_1_to_1000; +set max_session_mem_used = 8192; +--error 0,ER_OPTION_PREVENTS_STATEMENT +select * from seq_1_to_1000; +--enable_result_log +# We may not be able to execute any more queries with this connection +# because of too little memory + +set max_session_mem_used = DEFAULT; + +--echo # +--echo # MDEV-35828: Assertion fails in alloc_root() when memory causes it to call itself +--echo # +CREATE TEMPORARY TABLE t1 (a INT,b INT); +INSERT INTO t1 VALUES (1,1),(2,2); + +SET max_session_mem_used=8192; + +--error ER_OPTION_PREVENTS_STATEMENT +SELECT * FROM (t1 AS t2 LEFT JOIN t1 AS t3 USING (a)),t1; + +SET max_session_mem_used=DEFAULT; +DROP TABLE t1; + +--echo # +--echo # MDEV-23824 SIGSEGV in end_io_cache on REPAIR LOCAL TABLE for Aria table +--echo # + +CREATE TABLE t1 (i INT) ENGINE=Aria; +INSERT INTO t1 VALUES (1); +SET max_session_mem_used=50000; +--disable_result_log +REPAIR LOCAL TABLE t1 USE_FRM; +REPAIR LOCAL TABLE t1; +--enable_result_log +DROP TABLE t1; +SET max_session_mem_used=default; + +--echo # +--echo # MDEV-38005 Assertion `(yyvsp[-3].simple_string) < (yyvsp[-1].simple_string)' failed +--echo # +SET max_session_mem_used=1; +--error ER_OPTION_PREVENTS_STATEMENT +CREATE TABLE t SELECT 1000000000000000000000000000000000000000000000000000000000000000000000000000000001 AS c; +SET max_session_mem_used=default; + +--echo # End of 10.6 tests + +--echo # +--echo # MDEV-37489: SIGSEGV in get_param_default_value | store_schema_params +--echo # + +--DELIMITER // +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func()) +BEGIN + SELECT x; +END; +// +--DELIMITER ; + +SET SESSION max_session_mem_used=8192; +--ERROR ER_OPTION_PREVENTS_STATEMENT +CALL p0(); + +SET @@max_session_mem_used=DEFAULT; +--ERROR ER_SP_DOES_NOT_EXIST +CALL p0(); + +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; + +--echo # with func() defined +--DELIMITER // +CREATE FUNCTION func(x INT DEFAULT 10) RETURNS INT +BEGIN + RETURN x; +END; +// + +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func()) +BEGIN + SELECT x; +END; +// +--DELIMITER ; + +SET SESSION max_session_mem_used=8192; +--ERROR ER_OPTION_PREVENTS_STATEMENT +CALL p0(); + +SET @@max_session_mem_used=DEFAULT; +CALL p0(); + +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; + +--echo # with multiple functions +--DELIMITER // +CREATE FUNCTION func2(x INT DEFAULT 10) RETURNS INT +BEGIN + RETURN x; +END; +// + +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2()) +BEGIN + SELECT x, y; +END; +// +--DELIMITER ; + +SET SESSION max_session_mem_used=8192; +--ERROR ER_OPTION_PREVENTS_STATEMENT +CALL p0(); + +SET @@max_session_mem_used=DEFAULT; +CALL p0(); + +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; + +--echo # with function and constant default param +--DELIMITER // +CREATE OR REPLACE PROCEDURE p0 (x INT DEFAULT func(), y INT DEFAULT func2(), z INT DEFAULT 10) +BEGIN + SELECT x, y, z; +END; +// +--DELIMITER ; + +SET SESSION max_session_mem_used=8192; +--ERROR ER_OPTION_PREVENTS_STATEMENT +CALL p0(); + +SET @@max_session_mem_used=DEFAULT; +CALL p0(); + +SELECT * FROM information_schema.PARAMETERS where specific_name = 'p0'; + +DROP PROCEDURE p0; +DROP FUNCTION func; +DROP FUNCTION func2; + +--echo # End of 11.8 tests diff --git a/mysql-test/main/mdev-34413-icp-reverse-order.result b/mysql-test/main/mdev-34413-icp-reverse-order.result index 6b88bc140601a..d920174c72353 100644 --- a/mysql-test/main/mdev-34413-icp-reverse-order.result +++ b/mysql-test/main/mdev-34413-icp-reverse-order.result @@ -225,8 +225,8 @@ a b c 3 3 3 SELECT * FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME LIKE '%icp%'; VARIABLE_NAME VARIABLE_VALUE -HANDLER_ICP_ATTEMPTS 6 -HANDLER_ICP_MATCH 6 +HANDLER_ICP_ATTEMPTS 5 +HANDLER_ICP_MATCH 5 select * from t1 where a >= 3 and a <= 7 order by a desc, b desc; a b c 7 7 7 @@ -247,8 +247,8 @@ a b c 3 3 3 SELECT * FROM information_schema.SESSION_STATUS WHERE VARIABLE_NAME LIKE '%icp%'; VARIABLE_NAME VARIABLE_VALUE -HANDLER_ICP_ATTEMPTS 6 -HANDLER_ICP_MATCH 6 +HANDLER_ICP_ATTEMPTS 5 +HANDLER_ICP_MATCH 5 drop table t1; create table t1 ( pk int primary key, diff --git a/mysql-test/main/mdev-35765.result b/mysql-test/main/mdev-35765.result new file mode 100644 index 0000000000000..9a3de115b837b --- /dev/null +++ b/mysql-test/main/mdev-35765.result @@ -0,0 +1,20 @@ +# +# MDEV-35765 ST_OVERLAPS returns true despite dim(originalInput1) <> dim(originalInput2) +# +DROP table if EXISTS t1; +Warnings: +Note 1051 Unknown table 'test.t1' +DROP table if EXISTS t2; +Warnings: +Note 1051 Unknown table 'test.t2' +CREATE TABLE t1(geom geometry NOT NULL); +CREATE TABLE t2(geom geometry NOT NULL); +INSERT INTO t1 (geom) VALUES(ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t2 (geom) VALUES(ST_GeomFromText('LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)')); +SELECT ST_OVERLAPS(t1.geom, t2.geom) FROM t1, t2; +ST_OVERLAPS(t1.geom, t2.geom) +0 +DROP TABLE t1, t2; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/mdev-35765.test b/mysql-test/main/mdev-35765.test new file mode 100644 index 0000000000000..f9d04cff1f4b3 --- /dev/null +++ b/mysql-test/main/mdev-35765.test @@ -0,0 +1,14 @@ +--echo # +--echo # MDEV-35765 ST_OVERLAPS returns true despite dim(originalInput1) <> dim(originalInput2) +--echo # +DROP table if EXISTS t1; +DROP table if EXISTS t2; +CREATE TABLE t1(geom geometry NOT NULL); +CREATE TABLE t2(geom geometry NOT NULL); +INSERT INTO t1 (geom) VALUES(ST_GeomFromText('POLYGON ((0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t2 (geom) VALUES(ST_GeomFromText('LINESTRING (1 1, 1 2, 2 2, 2 1, 1 1)')); +SELECT ST_OVERLAPS(t1.geom, t2.geom) FROM t1, t2; +DROP TABLE t1, t2; +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/mysql-test/main/mdev375.test b/mysql-test/main/mdev375.test index f489d232be8a5..b20e161f4c0bf 100644 --- a/mysql-test/main/mdev375.test +++ b/mysql-test/main/mdev375.test @@ -4,6 +4,8 @@ --source include/not_embedded.inc --disable_service_connection +let $count_sessions=1; +--source include/wait_until_count_sessions.inc set @save_log_warnings=@@log_warnings, @save_max_connections=@@max_connections; SET GLOBAL log_warnings=4; SET GLOBAL max_connections=10; diff --git a/mysql-test/main/mdev_32854.result b/mysql-test/main/mdev_32854.result new file mode 100644 index 0000000000000..389f18c1410b9 --- /dev/null +++ b/mysql-test/main/mdev_32854.result @@ -0,0 +1,465 @@ +SET @json_doc_obj_lev45_valid='{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }'; +SET @json_doc_arr_lev45_valid='[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'; +CREATE TABLE t1 (val JSON); +INSERT INTO t1 VALUES (@json_doc_arr_lev45_valid), ('[1, 2, 10,3, [4, 5, 6, [7, 8, 9]]]'); +SELECT JSON_ARRAY(@json_doc_arr_lev45_valid, 1, 2, 3); +JSON_ARRAY(@json_doc_arr_lev45_valid, 1, 2, 3) +["[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]", 1, 2, 3] +SELECT JSON_ARRAY (@json_doc_obj_lev45_valid, '{"key1":1, "key2":2}'); +JSON_ARRAY (@json_doc_obj_lev45_valid, '{"key1":1, "key2":2}') +["{ \"level1\": { \"level2\": { \"level3\": { \"level4\": { \"level5\": { \"level6\": { \"level7\": { \"level8\": { \"level9\": { \"level10\": { \"level11\": { \"level12\": { \"level13\": { \"level14\": { \"level15\": { \"level16\": { \"level17\": { \"level18\": { \"level19\": { \"level20\": { \"level21\": { \"level22\": { \"level23\": { \"level24\": { \"level25\": { \"level26\": { \"level27\": { \"level28\": { \"level29\": { \"level30\": { \"level31\": { \"level32\": { \"level33\": { \"level34\": { \"level35\": { \"level36\": { \"level37\": { \"level38\": { \"level39\": { \"level40\": { \"level41\": { \"level42\": { \"level43\": { \"level44\": { \"level45\": \"This is level 45\" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }", "{\"key1\":1, \"key2\":2}"] +SELECT JSON_ARRAYAGG(val) FROM t1; +JSON_ARRAYAGG(val) +[[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]],[1, 2, 10,3, [4, 5, 6, [7, 8, 9]]]] +SELECT JSON_ARRAY_APPEND(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result; +result +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45, false]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_ARRAY_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result; +result +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, false, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_ARRAY_INTERSECT(@json_doc_arr_lev45_valid, '[1, [2, [3]]]'); +JSON_ARRAY_INTERSECT(@json_doc_arr_lev45_valid, '[1, [2, [3]]]') +[1] +SELECT JSON_COMPACT(@json_doc_obj_lev45_valid); +JSON_COMPACT(@json_doc_obj_lev45_valid) +{"level1":{"level2":{"level3":{"level4":{"level5":{"level6":{"level7":{"level8":{"level9":{"level10":{"level11":{"level12":{"level13":{"level14":{"level15":{"level16":{"level17":{"level18":{"level19":{"level20":{"level21":{"level22":{"level23":{"level24":{"level25":{"level26":{"level27":{"level28":{"level29":{"level30":{"level31":{"level32":{"level33":{"level34":{"level35":{"level36":{"level37":{"level38":{"level39":{"level40":{"level41":{"level42":{"level43":{"level44":{"level45":"This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +SELECT JSON_COMPACT(@json_doc_arr_lev45_valid); +JSON_COMPACT(@json_doc_arr_lev45_valid) +[1,[2,[3,[4,[5,[6,[7,[8,[9,[10,[11,[12,[13,[14,[15,[16,[17,[18,[19,[20,[21,[22,[23,[24,[25,[26,[27,[28,[29,[30,[31,[32,[33,[34,[35,[36,[37,[38,[39,[40,[41,[42,[43,[44,[45,45,45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_CONTAINS(@json_doc_obj_lev45_valid, ' { "level45": "This is level 45" }', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_CONTAINS(@json_doc_obj_lev45_valid, ' { "level45": "This is level 45" }', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level2 +1 +SELECT JSON_CONTAINS(@json_doc_arr_lev45_valid, '[45, 45, 45]', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_CONTAINS(@json_doc_arr_lev45_valid, '[45, 45, 45]', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +1 +SELECT JSON_CONTAINS_PATH(@json_doc_arr_lev45_valid, 'all', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_CONTAINS_PATH(@json_doc_arr_lev45_valid, 'all', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +1 +SELECT JSON_CONTAINS_PATH(@json_doc_obj_lev45_valid, 'all', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_CONTAINS_PATH(@json_doc_obj_lev45_valid, 'all', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26. +1 +SELECT JSON_DEPTH(@json_doc_arr_lev45_valid); +JSON_DEPTH(@json_doc_arr_lev45_valid) +46 +SELECT JSON_DEPTH(@json_doc_obj_lev45_valid); +JSON_DEPTH(@json_doc_obj_lev45_valid) +46 +SELECT JSON_DETAILED(@json_doc_obj_lev45_valid); +JSON_DETAILED(@json_doc_obj_lev45_valid) +{ + "level1": + { + "level2": + { + "level3": + { + "level4": + { + "level5": + { + "level6": + { + "level7": + { + "level8": + { + "level9": + { + "level10": + { + "level11": + { + "level12": + { + "level13": + { + "level14": + { + "level15": + { + "level16": + { + "level17": + { + "level18": + { + "level19": + { + "level20": + { + "level21": + { + "level22": + { + "level23": + { + "level24": + { + "level25": + { + "level26": + { + "level27": + { + "level28": + { + "level29": + { + "level30": + { + "level31": + { + "level32": + { + "level33": + { + "level34": + { + "level35": + { + "level36": + { + "level37": + { + "level38": + { + "level39": + { + "level40": + { + "level41": + { + "level42": + { + "level43": + { + "level44": + { + "level45": "This is level 45" + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } +} +SELECT JSON_DETAILED(@json_doc_arr_lev45_valid); +JSON_DETAILED(@json_doc_arr_lev45_valid) +[ + 1, + [ + 2, + [ + 3, + [ + 4, + [ + 5, + [ + 6, + [ + 7, + [ + 8, + [ + 9, + [ + 10, + [ + 11, + [ + 12, + [ + 13, + [ + 14, + [ + 15, + [ + 16, + [ + 17, + [ + 18, + [ + 19, + [ + 20, + [ + 21, + [ + 22, + [ + 23, + [ + 24, + [ + 25, + [ + 26, + [ + 27, + [ + 28, + [ + 29, + [ + 30, + [ + 31, + [ + 32, + [ + 33, + [ + 34, + [ + 35, + [ + 36, + [ + 37, + [ + 38, + [ + 39, + [ + 40, + [ + 41, + [ + 42, + [ + 43, + [ + 44, + [ + 45, + 45, + 45 + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] + ] +] +SELECT JSON_EQUALS(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid); +JSON_EQUALS(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid) +1 +SELECT JSON_EQUALS(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid); +JSON_EQUALS(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid) +1 +SELECT JSON_EXISTS(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_EXISTS(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +1 +SELECT JSON_EXISTS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_EXISTS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level2 +1 +SELECT JSON_EXTRACT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_EXTRACT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +[45, 45, 45] +SELECT JSON_EXTRACT(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_EXTRACT(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level +{"level45": "This is level 45"} +SELECT JSON_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][3]', 46); +JSON_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][3]', 46) +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, [45, 46], 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_KEY_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_KEY_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.lev +[{"key": "level45", "value": "This is level 45"}] +SELECT JSON_KEYS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_KEYS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28. +["level45"] +SELECT JSON_LENGTH(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +JSON_LENGTH(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level2 +1 +SELECT JSON_LENGTH(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_LENGTH(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +1 +SELECT JSON_LOOSE(@json_doc_obj_lev45_valid); +JSON_LOOSE(@json_doc_obj_lev45_valid) +{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +SELECT JSON_LOOSE(@json_doc_arr_lev45_valid); +JSON_LOOSE(@json_doc_arr_lev45_valid) +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_MERGE(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}'); +JSON_MERGE(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}') +{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, "key1": "val1", "key2": "val2"} +SELECT JSON_MERGE(@json_doc_arr_lev45_valid, '[1, 2, 3]'); +JSON_MERGE(@json_doc_arr_lev45_valid, '[1, 2, 3]') +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], 1, 2, 3] +SELECT JSON_MERGE_PATCH(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}'); +JSON_MERGE_PATCH(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}') +{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}, "key1": "val1", "key2": "val2"} +SELECT JSON_MERGE_PATCH(@json_doc_arr_lev45_valid, '[1, 2, 3]'); +JSON_MERGE_PATCH(@json_doc_arr_lev45_valid, '[1, 2, 3]') +[1, 2, 3] +SELECT JSON_MERGE_PRESERVE(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid); +JSON_MERGE_PRESERVE(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid) +{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": ["This is level 45", "This is level 45"]}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +SELECT JSON_MERGE_PRESERVE(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid); +JSON_MERGE_PRESERVE(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid) +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]], 1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_NORMALIZE(@json_doc_arr_lev45_valid); +JSON_NORMALIZE(@json_doc_arr_lev45_valid) +[1.0E0,[2.0E0,[3.0E0,[4.0E0,[5.0E0,[6.0E0,[7.0E0,[8.0E0,[9.0E0,[1.0E1,[1.1E1,[1.2E1,[1.3E1,[1.4E1,[1.5E1,[1.6E1,[1.7E1,[1.8E1,[1.9E1,[2.0E1,[2.1E1,[2.2E1,[2.3E1,[2.4E1,[2.5E1,[2.6E1,[2.7E1,[2.8E1,[2.9E1,[3.0E1,[3.1E1,[3.2E1,[3.3E1,[3.4E1,[3.5E1,[3.6E1,[3.7E1,[3.8E1,[3.9E1,[4.0E1,[4.1E1,[4.2E1,[4.3E1,[4.4E1,[4.5E1,4.5E1,4.5E1]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_OBJECT('level1', @json_doc_obj_lev45_valid); +JSON_OBJECT('level1', @json_doc_obj_lev45_valid) +{"level1": "{ \"level1\": { \"level2\": { \"level3\": { \"level4\": { \"level5\": { \"level6\": { \"level7\": { \"level8\": { \"level9\": { \"level10\": { \"level11\": { \"level12\": { \"level13\": { \"level14\": { \"level15\": { \"level16\": { \"level17\": { \"level18\": { \"level19\": { \"level20\": { \"level21\": { \"level22\": { \"level23\": { \"level24\": { \"level25\": { \"level26\": { \"level27\": { \"level28\": { \"level29\": { \"level30\": { \"level31\": { \"level32\": { \"level33\": { \"level34\": { \"level35\": { \"level36\": { \"level37\": { \"level38\": { \"level39\": { \"level40\": { \"level41\": { \"level42\": { \"level43\": { \"level44\": { \"level45\": \"This is level 45\" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }"} +SELECT JSON_OBJECT_FILTER_KEYS(@json_doc_obj_lev45_valid, '["level1"]'); +JSON_OBJECT_FILTER_KEYS(@json_doc_obj_lev45_valid, '["level1"]') +{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +SELECT JSON_OBJECT_TO_ARRAY(@json_doc_obj_lev45_valid); +JSON_OBJECT_TO_ARRAY(@json_doc_obj_lev45_valid) +[["level1", {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": {"level42": {"level43": {"level44": {"level45": "This is level 45"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}]] +CREATE TABLE t2 (val1 VARCHAR(10), val2 JSON); +INSERT INTO t2 VALUES('level0', @json_doc_obj_lev45_valid); +SELECT JSON_OBJECTAGG(val1, val2) FROM t2; +JSON_OBJECTAGG(val1, val2) +{"level0":{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }} +SELECT JSON_OVERLAPS(@json_doc_obj_lev45_valid,'{ "level44": { "level45": "This is level 45" } }'); +JSON_OVERLAPS(@json_doc_obj_lev45_valid,'{ "level44": { "level45": "This is level 45" } }') +0 +SELECT JSON_QUERY(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_QUERY(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +[45, 45, 45] +SELECT JSON_QUOTE(@json_doc_obj_lev45_valid); +JSON_QUOTE(@json_doc_obj_lev45_valid) +"{ \"level1\": { \"level2\": { \"level3\": { \"level4\": { \"level5\": { \"level6\": { \"level7\": { \"level8\": { \"level9\": { \"level10\": { \"level11\": { \"level12\": { \"level13\": { \"level14\": { \"level15\": { \"level16\": { \"level17\": { \"level18\": { \"level19\": { \"level20\": { \"level21\": { \"level22\": { \"level23\": { \"level24\": { \"level25\": { \"level26\": { \"level27\": { \"level28\": { \"level29\": { \"level30\": { \"level31\": { \"level32\": { \"level33\": { \"level34\": { \"level35\": { \"level36\": { \"level37\": { \"level38\": { \"level39\": { \"level40\": { \"level41\": { \"level42\": { \"level43\": { \"level44\": { \"level45\": \"This is level 45\" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }" +SELECT JSON_QUOTE(@json_doc_arr_lev45_valid); +JSON_QUOTE(@json_doc_arr_lev45_valid) +"[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]" +SET @json_removed= JSON_REMOVE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39'); +SET @json_removed= JSON_REMOVE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +SELECT @json_removed; +@json_removed +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SET @json_schema= '{"type": "object", "properties": { "level1": { "type": "object", "properties": { "level2": { "type": "object", "properties": { "level3": { "type": "object", "properties": { "level4": { "type": "object", "properties": { "level5": { "type": "object", "properties": { "level6": { "type": "object", "properties": { "level7": { "type": "object", "properties": { "level8": { "type": "object", "properties": { "level9": { "type": "object", "properties": { "level10": { "type": "object", "properties": { "level11": { "type": "object", "properties": { "level12": { "type": "object", "properties": { "level13": { "type": "object", "properties": { "level14": { "type": "object", "properties": { "level15": { "type": "object", "properties": { "level16": { "type": "object", "properties": { "level17": { "type": "object", "properties": { "level18": { "type": "object", "properties": { "level19": { "type": "object", "properties": { "level20": { "type": "object", "properties": { "level21": { "type": "object", "properties": { "level22": { "type": "object", "properties": { "level23": { "type": "object", "properties": { "level24": { "type": "object", "properties": { "level25": { "type": "object", "properties": { "level26": { "type": "object", "properties": { "level27": { "type": "object", "properties": { "level28": { "type": "object", "properties": { "level29": { "type": "object", "properties": { "level30": { "type": "object", "properties": { "level31": { "type": "object", "properties": { "level32": { "type": "object", "properties": { "level33": { "type": "object", "properties": { "level34": { "type": "object", "properties": { "level35": { "type": "object", "properties": { "level36": { "type": "object", "properties": { "level37": { "type": "object", "properties": { "level38": { "type": "object", "properties": { "level39": { "type": "object", "properties": { "level40": { "type": "object", "properties": { "level41": { "type": "object", "properties": { "level42": { "type": "object", "properties": { "level43": { "type": "object", "properties": { "level44": { "type": "object", "properties": { "level45": { "type": "string", "const": "This is level 45" } }, "required": ["level45"] } }, "required": ["level44"] } }, "required": ["level43"] } }, "required": ["level42"] } }, "required": ["level41"] } }, "required": ["level40"] } }, "required": ["level39"] } }, "required": ["level38"] } }, "required": ["level37"] } }, "required": ["level36"] } }, "required": ["level35"] } }, "required": ["level34"] } }, "required": ["level33"] } }, "required": ["level32"] } }, "required": ["level31"] } }, "required": ["level30"] } }, "required": ["level29"] } }, "required": ["level28"] } }, "required": ["level27"] } }, "required": ["level26"] } }, "required": ["level25"] } }, "required": ["level24"] } }, "required": ["level23"] } }, "required": ["level22"] } }, "required": ["level21"] } }, "required": ["level20"] } }, "required": ["level19"] } }, "required": ["level18"] } }, "required": ["level17"] } }, "required": ["level16"] } }, "required": ["level15"] } }, "required": ["level14"] } }, "required": ["level13"] } }, "required": ["level12"] } }, "required": ["level11"] } }, "required": ["level10"] } }, "required": ["level9"] } }, "required": ["level8"] } }, "required": ["level7"] } }, "required": ["level6"] } }, "required": ["level5"] } }, "required": ["level4"] } }, "required": ["level3"] } }, "required": ["level2"] } }, "required": ["level1"] }'; +SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid) AS found_path; +found_path +1 +SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid2); +JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid2) +NULL +SELECT JSON_SEARCH(@json_doc_obj_lev45_valid,'one', 'This is level 45'); +JSON_SEARCH(@json_doc_obj_lev45_valid,'one', 'This is level 45') +"$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44.level45" +SET @json_updated = JSON_SET(@json_doc_obj_lev45_valid, +'$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41', +'Updated value'); +SELECT @json_updated; +@json_updated +{"level1": {"level2": {"level3": {"level4": {"level5": {"level6": {"level7": {"level8": {"level9": {"level10": {"level11": {"level12": {"level13": {"level14": {"level15": {"level16": {"level17": {"level18": {"level19": {"level20": {"level21": {"level22": {"level23": {"level24": {"level25": {"level26": {"level27": {"level28": {"level29": {"level30": {"level31": {"level32": {"level33": {"level34": {"level35": {"level36": {"level37": {"level38": {"level39": {"level40": {"level41": "Updated value"}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +SELECT JSON_TYPE(@json_doc_obj_lev45_valid); +JSON_TYPE(@json_doc_obj_lev45_valid) +OBJECT +SELECT JSON_TYPE(@json_doc_arr_lev45_valid); +JSON_TYPE(@json_doc_arr_lev45_valid) +ARRAY +SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_obj_lev45_valid)); +JSON_UNQUOTE(JSON_QUOTE(@json_doc_obj_lev45_valid)) +{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } +SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_arr_lev45_valid)); +JSON_UNQUOTE(JSON_QUOTE(@json_doc_arr_lev45_valid)) +[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]] +SELECT JSON_VALID(@json_doc_obj_lev45_valid); +JSON_VALID(@json_doc_obj_lev45_valid) +1 +SELECT JSON_VALID(@json_doc_arr_lev45_valid); +JSON_VALID(@json_doc_arr_lev45_valid) +1 +SELECT JSON_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44.level45'); +JSON_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28 +This is level 45 +SELECT JSON_VALUE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +JSON_VALUE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]') +45 +DROP TABLE t1 ,t2; +# +# MDEV-37082: Sig 11 in json_normalize_sort +# +CREATE TABLE t (a JSON)Engine=InnoDB; +INSERT INTO t VALUES (CONCAT (REPEAT('{"v":',5000),'1',REPEAT('}',5000))); +INSERT INTO t VALUES (CONCAT (REPEAT('[',5000),'1',REPEAT(']',5000))); +SELECT JSON_EQUALS (a,a) FROM t; +JSON_EQUALS (a,a) +1 +1 +DROP TABLE t; diff --git a/mysql-test/main/mdev_32854.test b/mysql-test/main/mdev_32854.test new file mode 100644 index 0000000000000..e68f3af8ff3d5 --- /dev/null +++ b/mysql-test/main/mdev_32854.test @@ -0,0 +1,127 @@ +SET @json_doc_obj_lev45_valid='{ "level1": { "level2": { "level3": { "level4": { "level5": { "level6": { "level7": { "level8": { "level9": { "level10": { "level11": { "level12": { "level13": { "level14": { "level15": { "level16": { "level17": { "level18": { "level19": { "level20": { "level21": { "level22": { "level23": { "level24": { "level25": { "level26": { "level27": { "level28": { "level29": { "level30": { "level31": { "level32": { "level33": { "level34": { "level35": { "level36": { "level37": { "level38": { "level39": { "level40": { "level41": { "level42": { "level43": { "level44": { "level45": "This is level 45" } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } } }'; + +SET @json_doc_arr_lev45_valid='[1, [2, [3, [4, [5, [6, [7, [8, [9, [10, [11, [12, [13, [14, [15, [16, [17, [18, [19, [20, [21, [22, [23, [24, [25, [26, [27, [28, [29, [30, [31, [32, [33, [34, [35, [36, [37, [38, [39, [40, [41, [42, [43, [44, [45, 45, 45]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]'; + +CREATE TABLE t1 (val JSON); +INSERT INTO t1 VALUES (@json_doc_arr_lev45_valid), ('[1, 2, 10,3, [4, 5, 6, [7, 8, 9]]]'); + +SELECT JSON_ARRAY(@json_doc_arr_lev45_valid, 1, 2, 3); +SELECT JSON_ARRAY (@json_doc_obj_lev45_valid, '{"key1":1, "key2":2}'); + +SELECT JSON_ARRAYAGG(val) FROM t1; + +SELECT JSON_ARRAY_APPEND(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result; + +SELECT JSON_ARRAY_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]', false) AS result; + +SELECT JSON_ARRAY_INTERSECT(@json_doc_arr_lev45_valid, '[1, [2, [3]]]'); + +SELECT JSON_COMPACT(@json_doc_obj_lev45_valid); +SELECT JSON_COMPACT(@json_doc_arr_lev45_valid); + +SELECT JSON_CONTAINS(@json_doc_obj_lev45_valid, ' { "level45": "This is level 45" }', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +SELECT JSON_CONTAINS(@json_doc_arr_lev45_valid, '[45, 45, 45]', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); + +SELECT JSON_CONTAINS_PATH(@json_doc_arr_lev45_valid, 'all', '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +SELECT JSON_CONTAINS_PATH(@json_doc_obj_lev45_valid, 'all', '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); + +SELECT JSON_DEPTH(@json_doc_arr_lev45_valid); +SELECT JSON_DEPTH(@json_doc_obj_lev45_valid); + +SELECT JSON_DETAILED(@json_doc_obj_lev45_valid); +SELECT JSON_DETAILED(@json_doc_arr_lev45_valid); + +SELECT JSON_EQUALS(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid); +SELECT JSON_EQUALS(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid); + +SELECT JSON_EXISTS(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +SELECT JSON_EXISTS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); + +SELECT JSON_EXTRACT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +SELECT JSON_EXTRACT(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); + +SELECT JSON_INSERT(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][3]', 46); + +SELECT JSON_KEY_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); + +SELECT JSON_KEYS(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); + +SELECT JSON_LENGTH(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44'); +SELECT JSON_LENGTH(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); + +SELECT JSON_LOOSE(@json_doc_obj_lev45_valid); +SELECT JSON_LOOSE(@json_doc_arr_lev45_valid); + +SELECT JSON_MERGE(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}'); +SELECT JSON_MERGE(@json_doc_arr_lev45_valid, '[1, 2, 3]'); + +SELECT JSON_MERGE_PATCH(@json_doc_obj_lev45_valid, '{"key1":"val1", "key2":"val2"}'); +SELECT JSON_MERGE_PATCH(@json_doc_arr_lev45_valid, '[1, 2, 3]'); + +SELECT JSON_MERGE_PRESERVE(@json_doc_obj_lev45_valid, @json_doc_obj_lev45_valid); +SELECT JSON_MERGE_PRESERVE(@json_doc_arr_lev45_valid, @json_doc_arr_lev45_valid); + +SELECT JSON_NORMALIZE(@json_doc_arr_lev45_valid); + +SELECT JSON_OBJECT('level1', @json_doc_obj_lev45_valid); + +SELECT JSON_OBJECT_FILTER_KEYS(@json_doc_obj_lev45_valid, '["level1"]'); + +SELECT JSON_OBJECT_TO_ARRAY(@json_doc_obj_lev45_valid); + +CREATE TABLE t2 (val1 VARCHAR(10), val2 JSON); +INSERT INTO t2 VALUES('level0', @json_doc_obj_lev45_valid); + +SELECT JSON_OBJECTAGG(val1, val2) FROM t2; + +SELECT JSON_OVERLAPS(@json_doc_obj_lev45_valid,'{ "level44": { "level45": "This is level 45" } }'); + +SELECT JSON_QUERY(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); + +SELECT JSON_QUOTE(@json_doc_obj_lev45_valid); +SELECT JSON_QUOTE(@json_doc_arr_lev45_valid); + +SET @json_removed= JSON_REMOVE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39'); +SET @json_removed= JSON_REMOVE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); +SELECT @json_removed; + +SET @json_schema= '{"type": "object", "properties": { "level1": { "type": "object", "properties": { "level2": { "type": "object", "properties": { "level3": { "type": "object", "properties": { "level4": { "type": "object", "properties": { "level5": { "type": "object", "properties": { "level6": { "type": "object", "properties": { "level7": { "type": "object", "properties": { "level8": { "type": "object", "properties": { "level9": { "type": "object", "properties": { "level10": { "type": "object", "properties": { "level11": { "type": "object", "properties": { "level12": { "type": "object", "properties": { "level13": { "type": "object", "properties": { "level14": { "type": "object", "properties": { "level15": { "type": "object", "properties": { "level16": { "type": "object", "properties": { "level17": { "type": "object", "properties": { "level18": { "type": "object", "properties": { "level19": { "type": "object", "properties": { "level20": { "type": "object", "properties": { "level21": { "type": "object", "properties": { "level22": { "type": "object", "properties": { "level23": { "type": "object", "properties": { "level24": { "type": "object", "properties": { "level25": { "type": "object", "properties": { "level26": { "type": "object", "properties": { "level27": { "type": "object", "properties": { "level28": { "type": "object", "properties": { "level29": { "type": "object", "properties": { "level30": { "type": "object", "properties": { "level31": { "type": "object", "properties": { "level32": { "type": "object", "properties": { "level33": { "type": "object", "properties": { "level34": { "type": "object", "properties": { "level35": { "type": "object", "properties": { "level36": { "type": "object", "properties": { "level37": { "type": "object", "properties": { "level38": { "type": "object", "properties": { "level39": { "type": "object", "properties": { "level40": { "type": "object", "properties": { "level41": { "type": "object", "properties": { "level42": { "type": "object", "properties": { "level43": { "type": "object", "properties": { "level44": { "type": "object", "properties": { "level45": { "type": "string", "const": "This is level 45" } }, "required": ["level45"] } }, "required": ["level44"] } }, "required": ["level43"] } }, "required": ["level42"] } }, "required": ["level41"] } }, "required": ["level40"] } }, "required": ["level39"] } }, "required": ["level38"] } }, "required": ["level37"] } }, "required": ["level36"] } }, "required": ["level35"] } }, "required": ["level34"] } }, "required": ["level33"] } }, "required": ["level32"] } }, "required": ["level31"] } }, "required": ["level30"] } }, "required": ["level29"] } }, "required": ["level28"] } }, "required": ["level27"] } }, "required": ["level26"] } }, "required": ["level25"] } }, "required": ["level24"] } }, "required": ["level23"] } }, "required": ["level22"] } }, "required": ["level21"] } }, "required": ["level20"] } }, "required": ["level19"] } }, "required": ["level18"] } }, "required": ["level17"] } }, "required": ["level16"] } }, "required": ["level15"] } }, "required": ["level14"] } }, "required": ["level13"] } }, "required": ["level12"] } }, "required": ["level11"] } }, "required": ["level10"] } }, "required": ["level9"] } }, "required": ["level8"] } }, "required": ["level7"] } }, "required": ["level6"] } }, "required": ["level5"] } }, "required": ["level4"] } }, "required": ["level3"] } }, "required": ["level2"] } }, "required": ["level1"] }'; +SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid) AS found_path; +SELECT JSON_SCHEMA_VALID(@json_schema, @json_doc_obj_lev45_valid2); + + +SELECT JSON_SEARCH(@json_doc_obj_lev45_valid,'one', 'This is level 45'); + +SET @json_updated = JSON_SET(@json_doc_obj_lev45_valid, + '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41', + 'Updated value'); +SELECT @json_updated; + +SELECT JSON_TYPE(@json_doc_obj_lev45_valid); +SELECT JSON_TYPE(@json_doc_arr_lev45_valid); + +SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_obj_lev45_valid)); +SELECT JSON_UNQUOTE(JSON_QUOTE(@json_doc_arr_lev45_valid)); + +SELECT JSON_VALID(@json_doc_obj_lev45_valid); +SELECT JSON_VALID(@json_doc_arr_lev45_valid); + +SELECT JSON_VALUE(@json_doc_obj_lev45_valid, '$.level1.level2.level3.level4.level5.level6.level7.level8.level9.level10.level11.level12.level13.level14.level15.level16.level17.level18.level19.level20.level21.level22.level23.level24.level25.level26.level27.level28.level29.level30.level31.level32.level33.level34.level35.level36.level37.level38.level39.level40.level41.level42.level43.level44.level45'); +SELECT JSON_VALUE(@json_doc_arr_lev45_valid, '$[1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1][1]'); + +DROP TABLE t1 ,t2; + +--echo # +--echo # MDEV-37082: Sig 11 in json_normalize_sort +--echo # + +--source include/have_innodb.inc + +CREATE TABLE t (a JSON)Engine=InnoDB; + +INSERT INTO t VALUES (CONCAT (REPEAT('{"v":',5000),'1',REPEAT('}',5000))); +INSERT INTO t VALUES (CONCAT (REPEAT('[',5000),'1',REPEAT(']',5000))); + +SELECT JSON_EQUALS (a,a) FROM t; + +DROP TABLE t; diff --git a/mysql-test/main/mdl.result b/mysql-test/main/mdl.result index dd3d923936682..284fd78901240 100644 --- a/mysql-test/main/mdl.result +++ b/mysql-test/main/mdl.result @@ -28,9 +28,9 @@ WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_BACKUP_DML Backup lock -MDL_SHARED_WRITE Table metadata lock test t1 -MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 MDL_INTENTION_EXCLUSIVE Schema metadata lock test +MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 +MDL_SHARED_WRITE Table metadata lock test t1 UNLOCK TABLES; LOCK TABLES t3 WRITE, t1 WRITE CONCURRENT; SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info @@ -38,9 +38,9 @@ WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; LOCK_MODE LOCK_TYPE TABLE_SCHEMA TABLE_NAME MDL_BACKUP_DDL Backup lock MDL_BACKUP_DML Backup lock -MDL_SHARED_WRITE Table metadata lock test t1 -MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 MDL_INTENTION_EXCLUSIVE Schema metadata lock test +MDL_SHARED_NO_READ_WRITE Table metadata lock test t3 +MDL_SHARED_WRITE Table metadata lock test t1 UNLOCK TABLES; LOCK TABLES t1 WRITE, mysql.user WRITE; SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info diff --git a/mysql-test/main/mdl.test b/mysql-test/main/mdl.test index 6b0c769014e0a..1d5402c6ad883 100644 --- a/mysql-test/main/mdl.test +++ b/mysql-test/main/mdl.test @@ -20,10 +20,12 @@ SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.me WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t1 WRITE CONCURRENT, t3 WRITE; +--sorted_result SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; LOCK TABLES t3 WRITE, t1 WRITE CONCURRENT; +--sorted_result SELECT LOCK_MODE, LOCK_TYPE, TABLE_SCHEMA, TABLE_NAME FROM information_schema.metadata_lock_info WHERE TABLE_NAME NOT LIKE 'innodb_%_stats'; UNLOCK TABLES; diff --git a/mysql-test/main/mdl_sync.result b/mysql-test/main/mdl_sync.result index 280fd1df1a03e..8e44c415507b6 100644 --- a/mysql-test/main/mdl_sync.result +++ b/mysql-test/main/mdl_sync.result @@ -1,9 +1,7 @@ -SET DEBUG_SYNC= 'RESET'; connect con1,localhost,root,,test,,; connect con2,localhost,root,,test,,; connect con3,localhost,root,,test,,; connection default; -drop table if exists t1,t2,t3; create table t1 (i int); create table t2 (i int); connection: default @@ -3046,3 +3044,23 @@ disconnect con1; connection default; DROP VIEW v1; SET debug_sync='reset'; +# +# MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode +# +create table t (c int) engine=innodb; +set debug_sync='get_schema_column SIGNAL waiting WAIT_FOR go'; +select column_name from information_schema.columns +where table_schema='test' and table_name='t'; +connect con1,localhost,root; +set debug_sync= 'now WAIT_FOR waiting'; +lock table t write; +set statement lock_wait_timeout=0 for alter table t discard tablespace; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +unlock tables; +set debug_sync='now SIGNAL go'; +disconnect con1; +connection default; +column_name +c +drop table t; +set debug_sync= 'reset'; diff --git a/mysql-test/main/mdl_sync.test b/mysql-test/main/mdl_sync.test index c55a11331d969..bcf4f0a62c2d6 100644 --- a/mysql-test/main/mdl_sync.test +++ b/mysql-test/main/mdl_sync.test @@ -3,18 +3,8 @@ # --source include/have_debug_sync.inc --source include/have_metadata_lock_info.inc - -# We need InnoDB tables for some of the tests. --source include/have_innodb.inc - -# Save the initial number of concurrent sessions. ---source include/count_sessions.inc - - -# Clean up resources used in this test case. ---disable_warnings -SET DEBUG_SYNC= 'RESET'; ---enable_warnings +--source include/no_view_protocol.inc # # Test the case of when a exclusive lock request waits for a @@ -27,10 +17,6 @@ connect (con3,localhost,root,,test,,); connection default; ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings - create table t1 (i int); create table t2 (i int); @@ -4010,7 +3996,6 @@ DROP TABLE t1; disconnect con1; - --echo # --echo # MDEV-28567 Assertion `0' in open_tables upon function-related operation --echo # @@ -4062,6 +4047,25 @@ connection default; DROP VIEW v1; SET debug_sync='reset'; -# Check that all connections opened by test cases in this file are really -# gone so execution of other tests won't be affected by their presence. ---source include/wait_until_count_sessions.inc + +--echo # +--echo # MDEV-30364 Assertion MDL_EXCLUSIVE on DISCARD TABLESPACE in LOCK TABLE mode +--echo # +create table t (c int) engine=innodb; +set debug_sync='get_schema_column SIGNAL waiting WAIT_FOR go'; +send select column_name from information_schema.columns +where table_schema='test' and table_name='t'; + +--connect con1,localhost,root +set debug_sync= 'now WAIT_FOR waiting'; +lock table t write; +--error ER_LOCK_WAIT_TIMEOUT +set statement lock_wait_timeout=0 for alter table t discard tablespace; +unlock tables; +set debug_sync='now SIGNAL go'; +--disconnect con1 + +--connection default +reap; +drop table t; +set debug_sync= 'reset'; diff --git a/mysql-test/main/merge_alter-master.opt b/mysql-test/main/merge_alter-master.opt new file mode 100644 index 0000000000000..4d69f3359db5c --- /dev/null +++ b/mysql-test/main/merge_alter-master.opt @@ -0,0 +1 @@ +--timezone=GMT-3 diff --git a/mysql-test/main/merge_alter.result b/mysql-test/main/merge_alter.result new file mode 100644 index 0000000000000..823931d2ccdc0 --- /dev/null +++ b/mysql-test/main/merge_alter.result @@ -0,0 +1,77 @@ +SET timestamp=1000000000; +RESET MASTER; +CREATE TABLE t (i1 int, i2 int, pk int) ; +CREATE TABLE t3 LIKE t ; +ALTER TABLE t3 ENGINE = MERGE UNION (t1,t2); +insert into t values(1,1,1); +flush logs; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/; +/*!40019 SET @@session.max_delayed_threads=0*/; +/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/; +DELIMITER /*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup +ROLLBACK/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Gtid list [] +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000001 +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-1 ddl thread_id=# +/*M!100101 SET @@session.skip_parallel_replication=0*//*!*/; +/*M!100001 SET @@session.gtid_domain_id=0*//*!*/; +/*M!100001 SET @@session.server_id=1*//*!*/; +/*M!100001 SET @@session.gtid_seq_no=1*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid= +use `test`/*!*/; +SET TIMESTAMP=1000000000/*!*/; +SET @@session.pseudo_thread_id=#/*!*/; +SET @@session.foreign_key_checks=1, @@session.sql_auto_is_null=0, @@session.unique_checks=1, @@session.autocommit=1, @@session.check_constraint_checks=1, @@session.sql_if_exists=0, @@session.explicit_defaults_for_timestamp=1, @@session.system_versioning_insert_history=0/*!*/; +SET @@session.sql_mode=1411383296/*!*/; +SET @@session.auto_increment_increment=1, @@session.auto_increment_offset=1/*!*/; +/*!\C latin1 *//*!*/; +SET @@session.character_set_client=X,@@session.collation_connection=X,@@session.collation_server=X/*!*/; +SET @@session.lc_time_names=0/*!*/; +SET @@session.collation_database=DEFAULT/*!*/; +CREATE TABLE t (i1 int, i2 int, pk int) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-2 ddl thread_id=# +/*M!100001 SET @@session.gtid_seq_no=2*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid= +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t3 LIKE t +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-3 ddl thread_id=# +/*M!100001 SET @@session.gtid_seq_no=3*//*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid= +SET TIMESTAMP=1000000000/*!*/; +ALTER TABLE t3 ENGINE = MERGE UNION (t1,t2) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX GTID 0-1-4 thread_id=# +/*M!100001 SET @@session.gtid_seq_no=4*//*!*/; +START TRANSACTION +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid= +SET TIMESTAMP=1000000000/*!*/; +insert into t values(1,1,1) +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 xid= +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id # end_log_pos # CRC32 XXX Rotate to master-bin.000002 pos: 4 +DELIMITER ; +# End of log file +ROLLBACK /* added by mysqlbinlog */; +/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/; +/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/; +drop table t,t3; diff --git a/mysql-test/main/merge_alter.test b/mysql-test/main/merge_alter.test new file mode 100644 index 0000000000000..8094fd4e9f9ab --- /dev/null +++ b/mysql-test/main/merge_alter.test @@ -0,0 +1,20 @@ +--source include/have_binlog_format_mixed.inc + +# MDEV-37903 ALTER TABLE ... ENGINE=MRG_MyISAM is not binlogged as DDL + +# Fix timestamp to avoid varying results. +SET timestamp=1000000000; + +RESET MASTER; + +CREATE TABLE t (i1 int, i2 int, pk int) ; +CREATE TABLE t3 LIKE t ; +ALTER TABLE t3 ENGINE = MERGE UNION (t1,t2); +insert into t values(1,1,1); + +flush logs; +let $MYSQLD_DATADIR= `select @@datadir`; +--replace_regex /server id [0-9]*/server id #/ /server v [^ ]*/server v #.##.##/ /exec_time=[0-9]*/exec_time=#/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ /collation_server=[0-9]+/collation_server=X/ /character_set_client=[a-zA-Z0-9]+/character_set_client=X/ /collation_connection=[0-9]+/collation_connection=X/ /xid=\d*/xid=/ +--exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000001 + +drop table t,t3; diff --git a/mysql-test/main/multi_update.result b/mysql-test/main/multi_update.result index 4ca76a8cbca88..50a9fa2ece0f5 100644 --- a/mysql-test/main/multi_update.result +++ b/mysql-test/main/multi_update.result @@ -954,6 +954,7 @@ select * from t2; log triggered triggered +disconnect a; drop table t1,t2, t3; drop user foo; create table t1 (a int, b int); diff --git a/mysql-test/main/multi_update.test b/mysql-test/main/multi_update.test index 3561ff4337516..c00c56bd6e292 100644 --- a/mysql-test/main/multi_update.test +++ b/mysql-test/main/multi_update.test @@ -921,6 +921,7 @@ insert t3 values (2); update t1 left join t3 on t1.id = t3.id set t1.v1 = 'hello'; select * from t2; +disconnect a; drop table t1,t2, t3; drop user foo; diff --git a/mysql-test/main/myisam.result b/mysql-test/main/myisam.result index 0d977c70425a3..7aefd32988ecb 100644 --- a/mysql-test/main/myisam.result +++ b/mysql-test/main/myisam.result @@ -2407,8 +2407,8 @@ KEY (c2) MyISAM file: MYSQLD_DATADIR/test/t1 Record format: Packed Character set: ? (0) -Data records: 0 Deleted blocks: 0 -Recordlength: 94 +Data records: 0 Deleted blocks: 0 +Recordlength: 94 table description: Key Start Len Index Type @@ -2696,8 +2696,8 @@ KEY (d) MyISAM file: MYSQLD_DATADIR/test/t1 Record format: Fixed length Character set: latin1_swedish_ci (8) -Data records: 0 Deleted blocks: 0 -Recordlength: 13 +Data records: 0 Deleted blocks: 0 +Recordlength: 13 table description: Key Start Len Index Type diff --git a/mysql-test/main/myisam_explain_non_select_all.result b/mysql-test/main/myisam_explain_non_select_all.result index 0f1fed4c5ab00..62b21afb84cda 100644 --- a/mysql-test/main/myisam_explain_non_select_all.result +++ b/mysql-test/main/myisam_explain_non_select_all.result @@ -3208,7 +3208,7 @@ JOIN t1 AS a12 ON a12.c1 = a11.c1 id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL Impossible WHERE Warnings: -Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where 0) +Note 1003 /* select#1 */ update `test`.`t3` set `test`.`t3`.`c3` = (/* select#2 */ select count(NULL) from `test`.`t1` `a11` straight_join `test`.`t2` `a21` join `test`.`t1` `a12` where multiple equal(NULL, NULL, `test`.`a21`.`c2`)) DROP TABLE t1, t2, t3; #73 CREATE TABLE t1 (id INT); diff --git a/mysql-test/main/myisam_icp_debug.result b/mysql-test/main/myisam_icp_debug.result index cb45a0e227438..f242f30cc82d3 100644 --- a/mysql-test/main/myisam_icp_debug.result +++ b/mysql-test/main/myisam_icp_debug.result @@ -1,4 +1,3 @@ -drop table if exists t0,t1,t2; create table t0(a int primary key); insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); create table t1(a int primary key); diff --git a/mysql-test/main/myisam_recover.test b/mysql-test/main/myisam_recover.test index 65062eb1e96f0..2001db6a2506c 100644 --- a/mysql-test/main/myisam_recover.test +++ b/mysql-test/main/myisam_recover.test @@ -1,5 +1,3 @@ ---source include/count_sessions.inc - call mtr.add_suppression("Table 't1' is marked as crashed and should be repaired"); set @save_table_definition_cache=@@table_definition_cache; @@ -162,6 +160,3 @@ disconnect con2; --echo # Cleanup drop table t1, t2; - -# Wait till all disconnects are completed --- source include/wait_until_count_sessions.inc diff --git a/mysql-test/main/mysql-bug41486.result b/mysql-test/main/mysql-bug41486.result index d5760dcb1b9f8..009e1463a4fd9 100644 --- a/mysql-test/main/mysql-bug41486.result +++ b/mysql-test/main/mysql-bug41486.result @@ -1,4 +1,3 @@ -DROP TABLE IF EXISTS t1; SET @old_max_allowed_packet= @@global.max_allowed_packet; SET @@global.max_allowed_packet = 2 * 1024 * 1024 + 1024; connect con1, localhost, root,,; diff --git a/mysql-test/main/mysql-bug41486.test b/mysql-test/main/mysql-bug41486.test index e7b0acc19355e..d75290285f3cb 100644 --- a/mysql-test/main/mysql-bug41486.test +++ b/mysql-test/main/mysql-bug41486.test @@ -11,10 +11,6 @@ -- source include/not_embedded.inc ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings - # Have to change the global variable as the session variable is # read-only. SET @old_max_allowed_packet= @@global.max_allowed_packet; @@ -45,7 +41,6 @@ DROP TABLE t1; # Cleanup disconnect con1; ---source include/wait_until_disconnected.inc remove_file $outfile; connection default; SET @@global.max_allowed_packet = @old_max_allowed_packet; diff --git a/mysql-test/main/mysql-bug45236.test b/mysql-test/main/mysql-bug45236.test index efc10ed19ea20..02f708cd65881 100644 --- a/mysql-test/main/mysql-bug45236.test +++ b/mysql-test/main/mysql-bug45236.test @@ -39,7 +39,6 @@ DROP TABLE t1; # Cleanup disconnect con1; ---source include/wait_until_disconnected.inc remove_file $outfile; connection default; SET @@global.max_allowed_packet = @old_max_allowed_packet; diff --git a/mysql-test/main/mysql-interactive.result b/mysql-test/main/mysql-interactive.result index 0eb3a53cac754..cd083339ace29 100644 --- a/mysql-test/main/mysql-interactive.result +++ b/mysql-test/main/mysql-interactive.result @@ -10,6 +10,8 @@ Your MariaDB connection id is X Server version: Y Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. +Help others discover MariaDB. Star it on GitHub: https://github.com/MariaDB/server + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> delimiter $ @@ -40,6 +42,8 @@ Your MariaDB connection id is X Server version: Y Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. +Help others discover MariaDB. Star it on GitHub: https://github.com/MariaDB/server + Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> create database db1; diff --git a/mysql-test/main/mysql.result b/mysql-test/main/mysql.result index 1cf877f8f96e0..6331386b5616a 100644 --- a/mysql-test/main/mysql.result +++ b/mysql-test/main/mysql.result @@ -1,6 +1,5 @@ set GLOBAL sql_mode=""; set LOCAL sql_mode=""; -drop table if exists t1,t2,t3; create table t1(a int); insert into t1 values(1); ERROR at line 9: DELIMITER must be followed by a 'delimiter' character or string diff --git a/mysql-test/main/mysql.test b/mysql-test/main/mysql.test index fd70987ab7722..3b88b00adf4c9 100644 --- a/mysql-test/main/mysql.test +++ b/mysql-test/main/mysql.test @@ -7,10 +7,6 @@ set GLOBAL sql_mode=""; set LOCAL sql_mode=""; ---disable_warnings -drop table if exists t1,t2,t3; ---enable_warnings - # # Test the "delimiter" functionality # Bug#9879 @@ -796,7 +792,9 @@ create user ser@localhost identified by "ass"; --echo MYSQL --ssl-verify-server-cert -e "\\s" --replace_regex /^.[^S].*// /\b[-A-Z_0-9]+,/XXX,/ --exec $MYSQL -user -pass --ssl-verify-server-cert -e "\\s" +--disable_warnings drop user ser@localhost; +--enable_warnings --echo # --echo # MDEV-32473 --disable-ssl doesn't disable it diff --git a/mysql-test/main/mysql_client_test.result b/mysql-test/main/mysql_client_test.result index 18e5c8718dc8e..ba3b9cd8a8f7a 100644 --- a/mysql-test/main/mysql_client_test.result +++ b/mysql-test/main/mysql_client_test.result @@ -262,3 +262,9 @@ SET @@global.collation_server= @save_collation_server; SET @@global.character_set_client= @save_character_set_client; SET @@global.collation_connection= @save_collation_connection; FOUND 1 /Aborted connection.*'u' host: '192.0.2.1' real ip: '(localhost|::1)'/ in mysqld.1.err +# +# MDEV-36269: Improve error handling for SOURCE command +# Test that SOURCE on an existent directory returns a clear error +# +ERROR at line 1: Can't read from a directory '.' +End of 10.11 tests diff --git a/mysql-test/main/mysql_client_test.test b/mysql-test/main/mysql_client_test.test index d620f4c707885..f99aecace80d3 100644 --- a/mysql-test/main/mysql_client_test.test +++ b/mysql-test/main/mysql_client_test.test @@ -63,3 +63,13 @@ SET @@global.collation_connection= @save_collation_connection; let SEARCH_FILE=$MYSQLTEST_VARDIR/log/mysqld.1.err; let SEARCH_PATTERN= Aborted connection.*'u' host: '192.0.2.1' real ip: '(localhost|::1)'; source include/search_pattern_in_file.inc; + +--echo # +--echo # MDEV-36269: Improve error handling for SOURCE command +--echo # Test that SOURCE on an existent directory returns a clear error +--echo # + +--error 1 +--exec $MYSQL -e "source ." 2>&1 + +--echo End of 10.11 tests diff --git a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result index 69b753896790e..8dee3afbf673d 100644 --- a/mysql-test/main/mysql_tzinfo_to_sql_symlink.result +++ b/mysql-test/main/mysql_tzinfo_to_sql_symlink.result @@ -105,9 +105,9 @@ execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_t execute immediate if(@wsrep_cannot_replicate_tz, concat('ALTER TABLE time_zone_transition_type ENGINE=', @time_zone_transition_type_engine, ', ORDER BY Time_zone_id, Transition_type_id'), 'do 0'); SET session alter_algorithm=@old_alter_alg; Warnings: -Warning 4200 The variable '@@alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release +Warning 4200 The setting 'alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: -Warning 4200 The variable '@@alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release +Warning 4200 The setting 'alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release SELECT COUNT(*) FROM time_zone; COUNT(*) 2 @@ -166,9 +166,9 @@ SET SESSION SQL_LOG_BIN=@save_sql_log_bin; execute immediate if(@wsrep_is_on, 'SET SESSION WSREP_ON=@save_wsrep_on', 'do 0'); SET session alter_algorithm=@old_alter_alg; Warnings: -Warning 4200 The variable '@@alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release +Warning 4200 The setting 'alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: -Warning 4200 The variable '@@alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release +Warning 4200 The setting 'alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release SELECT COUNT(*) FROM time_zone; COUNT(*) 2 @@ -490,9 +490,9 @@ execute immediate if(@wsrep_is_on, 'SET SESSION WSREP_ON=@save_wsrep_on', 'do 0' # set sql_mode=only_full_group_by; Warnings: -Warning 4200 The variable '@@alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release +Warning 4200 The setting 'alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release Warnings: -Warning 4200 The variable '@@alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release +Warning 4200 The setting 'alter_algorithm' is ignored. It only exists for compatibility with old installations and will be removed in a future release SELECT COUNT(*) FROM time_zone; COUNT(*) 2 diff --git a/mysql-test/main/mysql_upgrade-28915.result b/mysql-test/main/mysql_upgrade-28915.result index 8e5ff2846f521..d3571abf8f5bf 100644 --- a/mysql-test/main/mysql_upgrade-28915.result +++ b/mysql-test/main/mysql_upgrade-28915.result @@ -28,6 +28,7 @@ proc CREATE TABLE `proc` ( `db_collation` char(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL, `body_utf8` longblob DEFAULT NULL, `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE', + `path` text CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL DEFAULT 'CURRENT_SCHEMA', PRIMARY KEY (`db`,`name`,`type`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Stored Procedures' SHOW CREATE TABLE mysql.event; @@ -248,6 +249,7 @@ proc CREATE TABLE `proc` ( `db_collation` char(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL, `body_utf8` longblob DEFAULT NULL, `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE', + `path` text CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL DEFAULT 'CURRENT_SCHEMA', PRIMARY KEY (`db`,`name`,`type`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Stored Procedures' SHOW CREATE TABLE mysql.event; @@ -514,6 +516,7 @@ Create Table CREATE TABLE `proc` ( `db_collation` char(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_bin DEFAULT NULL, `body_utf8` longblob DEFAULT NULL, `aggregate` enum('NONE','GROUP') NOT NULL DEFAULT 'NONE', + `path` text CHARACTER SET utf8mb3 COLLATE utf8mb3_bin NOT NULL DEFAULT 'CURRENT_SCHEMA', PRIMARY KEY (`db`,`name`,`type`) ) ENGINE=Aria DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_general_ci PAGE_CHECKSUM=1 TRANSACTIONAL=1 COMMENT='Stored Procedures' SHOW CREATE TABLE mysql.event; diff --git a/mysql-test/main/mysql_upgrade.result b/mysql-test/main/mysql_upgrade.result index 9b20a5b871308..8903dcf7a7bc9 100644 --- a/mysql-test/main/mysql_upgrade.result +++ b/mysql-test/main/mysql_upgrade.result @@ -1159,11 +1159,13 @@ connection default; GRANT SELECT ON mysql.* TO very_long_user_name_number_1; GRANT SELECT ON mysql.* TO very_long_user_name_number_2; GRANT ALL ON *.* TO even_longer_user_name_number_3_to_test_the_grantor_and_definer_field_length@localhost WITH GRANT OPTION; +change_user even_longer_user_name_number_3_to_test_the_grantor_and_definer_field_length,,; GRANT INSERT ON mysql.user TO very_long_user_name_number_1; GRANT INSERT ON mysql.user TO very_long_user_name_number_2; GRANT UPDATE (User) ON mysql.db TO very_long_user_name_number_1; GRANT UPDATE (User) ON mysql.db TO very_long_user_name_number_2; CREATE PROCEDURE test.pr() BEGIN END; +change_user root,,; Phase 1/8: Checking and upgrading mysql database Processing databases mysql @@ -2370,7 +2372,8 @@ name dl # Check that mysql_upgrade can be run on mysqldump # of mysql schema from previous versions # -call mtr.add_suppression("innodb_(table|index)_stats has length mismatch in the column name table_name"); +call mtr.add_suppression("InnoDB: Fetch of persistent statistics requested for table `mysql`\\.`gtid_slave_pos` but the required system tables mysql\\.innodb_table_stats and mysql\\.innodb_index_stats are not present or have unexpected structure"); +call mtr.add_suppression("InnoDB: Unexpected length of mysql\\.innodb_table_stats\\.table_name"); call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20."); # # Upgrade from version 5.5 diff --git a/mysql-test/main/mysql_upgrade.test b/mysql-test/main/mysql_upgrade.test index 66e7ceea84fe7..463a6c94cd1ed 100644 --- a/mysql-test/main/mysql_upgrade.test +++ b/mysql-test/main/mysql_upgrade.test @@ -9,6 +9,10 @@ let majorminor=`select substring_index(version(), '.', 2)`; # for major upgrade test, see below let major=`select substring_index(version(), '.', 1) - (version() like '%.0.%')`; +if (`select version() like '%.%.0-%'`) { + --skip cannot test minor upgrade for previews +} + set sql_mode=""; call mtr.add_suppression("Incorrect definition of table mysql.column_stats:.*"); @@ -528,7 +532,8 @@ SELECT * FROM mysql.plugin WHERE name='unix_socket'; --echo # # The warning appears during mysql_upgrade, before the schema becomes consistent -call mtr.add_suppression("innodb_(table|index)_stats has length mismatch in the column name table_name"); +call mtr.add_suppression("InnoDB: Fetch of persistent statistics requested for table `mysql`\\.`gtid_slave_pos` but the required system tables mysql\\.innodb_table_stats and mysql\\.innodb_index_stats are not present or have unexpected structure"); +call mtr.add_suppression("InnoDB: Unexpected length of mysql\\.innodb_table_stats\\.table_name"); # This comes from opening 10.6 sys.host_summary view that uses sys.format_time function, # on still inconsistent mysql.proc, in older versions call mtr.add_suppression("Column count of mysql.proc is wrong. Expected 21, found 20."); diff --git a/mysql-test/main/mysqlbinlog.result b/mysql-test/main/mysqlbinlog.result index 51f8d4d199fe4..760d6fcca3167 100644 --- a/mysql-test/main/mysqlbinlog.result +++ b/mysql-test/main/mysqlbinlog.result @@ -690,9 +690,10 @@ SELECT * FROM t1; a b 1 root@localhost connection default; +disconnect unsecure; DROP DATABASE mysqltest1; DROP USER untrusted@localhost; -Bug#32580 mysqlbinlog cannot read binlog event with user variables +# Bug#32580 mysqlbinlog cannot read binlog event with user variables connection default; USE test; SET BINLOG_FORMAT = STATEMENT; diff --git a/mysql-test/main/mysqlbinlog.test b/mysql-test/main/mysqlbinlog.test index 3fd6a409cac38..b1ebf16223a78 100644 --- a/mysql-test/main/mysqlbinlog.test +++ b/mysql-test/main/mysqlbinlog.test @@ -4,6 +4,7 @@ -- source include/have_log_bin.inc -- source include/binlog_start_pos.inc +-- source include/count_sessions.inc --disable_query_log CALL mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); @@ -365,16 +366,19 @@ echo mysql mysqltest1 -uuntrusted < var/tmp/bug31611.sql; error 1; exec $MYSQL mysqltest1 -uuntrusted < $MYSQLTEST_VARDIR/tmp/bug31611.sql; --remove_file $MYSQLTEST_VARDIR/tmp/bug31611.sql + connection unsecure; error ER_TABLEACCESS_DENIED_ERROR; INSERT INTO t1 VALUES (1,USER()); SELECT * FROM t1; connection default; +disconnect unsecure; DROP DATABASE mysqltest1; +--source include/wait_until_count_sessions.inc DROP USER untrusted@localhost; ---echo Bug#32580 mysqlbinlog cannot read binlog event with user variables +--echo # Bug#32580 mysqlbinlog cannot read binlog event with user variables # Testing that various kinds of events can be read and restored properly. diff --git a/mysql-test/main/mysqld--help-aria.test b/mysql-test/main/mysqld--help-aria.test index 4f0da28204041..6dab8e7f1afb0 100644 --- a/mysql-test/main/mysqld--help-aria.test +++ b/mysql-test/main/mysqld--help-aria.test @@ -6,7 +6,7 @@ flush tables; --let $args=--table-cache=5 --max-connections=10 --log-warnings=1 --silent-startup --lower-case-table-names=1 --help --verbose --exec $MYSQLD_CMD $args > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /^.*failed to retrieve the MAC address\n// +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /\[Warning] failed to retrieve the MAC address\n// --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --echo # @@ -14,7 +14,7 @@ flush tables; --echo # --exec $MYSQLD_CMD $args --datadir=$MYSQL_TMP_DIR/help > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /^.*failed to retrieve the MAC address\n// +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /\[Warning] failed to retrieve the MAC address\n// --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --echo # @@ -23,7 +23,7 @@ flush tables; --mkdir $MYSQL_TMP_DIR/help --exec $MYSQLD_CMD $args --datadir=$MYSQL_TMP_DIR/help > $MYSQL_TMP_DIR/mysqld--help2.txt 2> $MYSQL_TMP_DIR/mysqld--help2.err ---replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /^.*failed to retrieve the MAC address\n// +--replace_regex /mysqld/mariadbd/ /\d\d\d\d-\d*-\d* *\d*:\d*:\d* \d* // /\[Warning] failed to retrieve the MAC address\n// --cat_file $MYSQL_TMP_DIR/mysqld--help2.err --list_files $MYSQL_TMP_DIR/help diff --git a/mysql-test/main/mysqld--help.result b/mysql-test/main/mysqld--help.result index 8b4e9b242c0f4..cb87a7ba8f1e6 100644 --- a/mysql-test/main/mysqld--help.result +++ b/mysql-test/main/mysqld--help.result @@ -78,6 +78,10 @@ The following specify which files/extra groups are read (specified before remain tables such as in the statement INSERT INTO t_myisam SELECT * FROM t_innodb; otherwise, slaves may diverge from the master + --binlog-directory=name + Directory path (absolute or relative to datadir) where + binlog files are stored. If this is used, must not + specify a directory path for --log-bin --binlog-do-db=name Tells the master it should log updates for the specified database, and exclude all others not explicitly mentioned --binlog-expire-logs-seconds=# @@ -135,6 +139,17 @@ The following specify which files/extra groups are read (specified before remain removed in a future release. Deprecated, will be removed in a future release. (Defaults to on; use --skip-binlog-optimize-thread-scheduling to disable.) + --binlog-row-event-fragment-threshold=# + When a Rows_log_event exceeds this threshold, it will be + fragmented into multiple Partial_rows_log_event events in + the binary log, each of this configured maximum size. + That is, all Partial_rows_log_events up to the last in + the group will be this configured maximum size, and the + last event will take the remaining size. This is relevant + for events that would surpass slave_max_allowed_packet + when sending to the slave, and thereby a sensible value + would reflect the slave's configured + slave_max_allowed_packet --binlog-row-event-max-size=# The maximum size of a row-based binary log event in bytes. Rows will be grouped into events smaller than this @@ -165,6 +180,10 @@ The following specify which files/extra groups are read (specified before remain non-transactional engines for the binary log. If you often use statements updating a great number of rows, you can increase this to get more performance + --binlog-storage-engine=name + Use a more efficient binlog implementation integrated + with the storage engine. Only available for supporting + engines --block-encryption-mode=name Default block encryption mode for AES_ENCRYPT() and AES_DECRYPT() functions. One of: aes-128-ecb, aes-192-ecb, @@ -460,8 +479,7 @@ The following specify which files/extra groups are read (specified before remain while even numbers are used for linked buffers --keep-files-on-create Don't overwrite stale .MYD and .MYI even if no directory - is specified. Deprecated, will be removed in a future - release. + is specified --key-buffer-size=# The size of the buffer used for index blocks for MyISAM tables. Increase this to get faster index handling --key-cache-age-threshold=# @@ -501,7 +519,10 @@ The following specify which files/extra groups are read (specified before remain the only option you need for specifying log files. Sets names for --log-bin, --log-bin-index, --relay-log, --relay-log-index, --general-log-file, - --log-slow-query-file, --log-error-file, and --pid-file + --log-slow-query-file, --log-error-file, and --pid-file. + If log-basename includes a path, the path will apply for + all above variables except pid-file that will use it + without the path --log-bin[=name] Log update queries in binary format. Optional argument should be name for binary log. If not given 'datadir'/'log-basename'-bin or 'datadir'/mysql-bin will @@ -620,13 +641,68 @@ The following specify which files/extra groups are read (specified before remain If set to 1 table names are stored in lowercase on disk and table names will be case-insensitive. Should be set to 2 if you are using a case insensitive file system + --master-connect-retry=# + The DEFAULT value for the CHANGE MASTER option + MASTER_CONNECT_RETRY, the interval in integer seconds + between each try to connect to the master + --master-heartbeat-period=name + The DEFAULT value for the CHANGE MASTER option + MASTER_HEARTBEAT_PERIOD, the interval in DECIMAL(10, 3) + seconds between replication heartbeats; the autoset value + is @@slave_net_timeout/2 calculated on use (Automatically + configured unless set explicitly) --master-info-file=name The location and name of the file that remembers the master and where the I/O replication thread is in the master's binlogs. Defaults to master.info --master-retry-count=# - The number of tries the slave will make to connect to the + The DEFAULT value for the CHANGE MASTER option + MASTER_RETRY_COUNT, the number of tries to connect to the master before giving up + --master-ssl The DEFAULT value for the CHANGE MASTER option + MASTER_SSL, which is whether to use TLS to connect to the + master + (Defaults to on; use --skip-master-ssl to disable.) + --master-ssl-ca=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_CA, an optional path to a Certificate + Authorities' certificates file for TLS replication + --master-ssl-capath=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_CAPATH, an optional path to a directory of + Certificate Authority's certificate files for TLS + replication, + --master-ssl-cert=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_CERT, an optional path to the master's + certificate for TLS replication + --master-ssl-cipher=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_CIPHER, a list of permitted ciphers for TLS + replication + --master-ssl-crl=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_CRL, an optional path to a revoked + certificates file for TLS replication + --master-ssl-crlpath=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_CRLPATH, an optional path to a directory of + revoked certificate files for TLS replication + --master-ssl-key=name + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_KEY, an optional path to the master's private + key for TLS replication + --master-ssl-verify-server-cert + The DEFAULT value for the CHANGE MASTER option + MASTER_SSL_VERIFY_SERVER_CERT, which is whether to + validate the master's certificate in TLS replication + (Defaults to on; use --skip-master-ssl-verify-server-cert to disable.) + --master-use-gtid=name + The DEFAULT value for the CHANGE MASTER option + MASTER_USE_GTID, which specifies which GTID record (or + neither) to start replicating from; the autoset value is + Slave_Pos, or No if that master does not support GTIDs + (Automatically configured unless set explicitly) --master-verify-checksum Force checksum verification of logged events in the binary log before sending them to slaves or printing them @@ -716,6 +792,11 @@ The following specify which files/extra groups are read (specified before remain Unused. Deprecated, will be removed in a future release. --metadata-locks-hash-instances=# Unused. Deprecated, will be removed in a future release. + --metadata-locks-instances=# + Number of fast lanes to create for metadata locks. Can be + used to improve DML scalability by eliminating + MDL_lock::rwlock load. Use 1 to disable MDL fast lanes. + Supported MDL namespaces: BACKUP --mhnsw-default-distance=name Distance function to build the vector index for. One of: euclidean, cosine @@ -775,23 +856,21 @@ The following specify which files/extra groups are read (specified before remain --net-write-timeout=# Number of seconds to wait for a block to be written to a connection before aborting the write + --new-mode=name Used to introduce new behavior to existing MariaDB + versions. No currently supported values. --note-verbosity=name Verbosity level for note-warnings given to the user. See also @@sql_notes. Any combination of: basic, unusable_keys, explain, or ALL to set all combinations - --old Use compatible behavior from previous MariaDB version. - Deprecated, will be removed in a future release. Please - use --old-mode instead. --old-mode=name Used to emulate old behavior from earlier MariaDB or MySQL versions. Any combination of: NO_DUP_KEY_WARNINGS_WITH_IGNORE, NO_PROGRESS_INFO, ZERO_DATE_TIME_CAST, UTF8_IS_UTF8MB3, IGNORE_INDEX_ONLY_FOR_JOIN, COMPAT_5_1_CHECKSUM, NO_NULL_COLLATION_IDS, LOCK_ALTER_TABLE_COPY, - OLD_FLUSH_STATUS, SESSION_USER_IS_USER, or ALL to set all - combinations - --old-passwords Use old password encryption method (needed for 4.0 and - older clients) + OLD_FLUSH_STATUS, SESSION_USER_IS_USER, 2_DIGIT_YEAR, or + ALL to set all combinations + --old-passwords Unused. Deprecated, will be removed in a future release. --old-style-user-limits Enable old-style user limits (before 5.0.3, user resources were counted per each user+host vs. per @@ -823,13 +902,14 @@ The following specify which files/extra groups are read (specified before remain storage as part of an index scan --optimizer-join-limit-pref-ratio=# For queries with JOIN and ORDER BY LIMIT : make the - optimizer consider a join order that allows to short-cut - execution after producing #LIMIT matches if that promises - N times speedup. (A conservative setting here would be is - a high value, like 100 so the short-cutting plan is used - if it promises a speedup of 100x or more). Short-cutting - plans are inherently risky so the default is 0 which - means do not consider this optimization + optimizer consider a join order that allows it to + short-cut execution after producing #LIMIT matches if + that promises N times speedup. (A conservative setting + here would be is a high value, like 100 so the + short-cutting plan is used if it promises a speedup of + 100x or more). Short-cutting plans are inherently risky + so the default is 0 which means do not consider this + optimization --optimizer-key-compare-cost=# Cost of checking a key against the end key condition --optimizer-key-copy-cost=# @@ -853,6 +933,9 @@ The following specify which files/extra groups are read (specified before remain heuristic, thus perform exhaustive search: 1 - prune plans based on cost and number of retrieved rows eq_ref: 2 - prune also if we find an eq_ref chain + --optimizer-record-context + Controls storing of optmizer context of all the tables + that are referenced in a query --optimizer-row-copy-cost=# Cost of copying a row from the engine or the join cache to the SQL layer @@ -895,7 +978,8 @@ The following specify which files/extra groups are read (specified before remain condition_pushdown_for_derived, split_materialized, condition_pushdown_for_subquery, rowid_filter, condition_pushdown_from_having, not_null_range_scan, - hash_join_cardinality, cset_narrowing, sargable_casefold + hash_join_cardinality, cset_narrowing, sargable_casefold, + reorder_outer_joins --optimizer-trace=name Controls tracing of the Optimizer: optimizer_trace=option=val[,option=val...], where option @@ -923,6 +1007,8 @@ The following specify which files/extra groups are read (specified before remain Cost of checking the row against the WHERE clause. Increasing this will have the optimizer to prefer plans with less row combinations + --path=name Comma-separated list of schema names that defines the + search order for stored routines --performance-schema Enable the performance schema --performance-schema-accounts-size=# @@ -1309,10 +1395,6 @@ The following specify which files/extra groups are read (specified before remain be removed in a future release. --safe-user-create Don't allow new user creation by the user who has no write privileges to the mysql.user table - --secure-auth Disallow authentication for accounts that have old - (pre-4.1) passwords. Deprecated, will be removed in a - future release. - (Defaults to on; use --skip-secure-auth to disable.) --secure-file-priv=name Limit LOAD DATA, SELECT ... OUTFILE, and LOAD_FILE() to files within specified directory @@ -1467,9 +1549,10 @@ The following specify which files/extra groups are read (specified before remain --slave-type-conversions=name Set of slave type conversions that are enabled. If the variable is empty, no conversions are allowed and it is - expected that the types match exactly. Any combination - of: ALL_LOSSY, ALL_NON_LOSSY, or ALL to set all - combinations + expected that the types match exactly. In this case one + will also not get any warnings about missing columns on + the slave. Any combination of: ALL_LOSSY, ALL_NON_LOSSY, + ERROR_IF_MISSING_FIELD, or ALL to set all combinations --slow-launch-time=# If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be @@ -1679,6 +1762,7 @@ binlog-checksum CRC32 binlog-commit-wait-count 0 binlog-commit-wait-usec 100000 binlog-direct-non-transactional-updates FALSE +binlog-directory (No default value) binlog-expire-logs-seconds 0 binlog-file-cache-size 16384 binlog-format MIXED @@ -1688,11 +1772,13 @@ binlog-gtid-index-span-min 65536 binlog-large-commit-threshold 134217728 binlog-legacy-event-pos FALSE binlog-optimize-thread-scheduling TRUE +binlog-row-event-fragment-threshold 1073741824 binlog-row-event-max-size 8192 binlog-row-image FULL binlog-row-metadata NO_LOG binlog-space-limit 0 binlog-stmt-cache-size 32768 +binlog-storage-engine (No default value) block-encryption-mode aes-128-ecb bulk-insert-buffer-size 8388608 character-set-client-handshake TRUE @@ -1814,8 +1900,20 @@ log-warnings 2 long-query-time 10 low-priority-updates FALSE lower-case-table-names 1 +master-connect-retry 60 +master-heartbeat-period auto master-info-file master.info master-retry-count 100000 +master-ssl TRUE +master-ssl-ca +master-ssl-capath +master-ssl-cert +master-ssl-cipher +master-ssl-crl +master-ssl-crlpath +master-ssl-key +master-ssl-verify-server-cert TRUE +master-use-gtid ? master-verify-checksum FALSE max-allowed-packet 16777216 max-binlog-cache-size 18446744073709547520 @@ -1847,6 +1945,7 @@ max-write-lock-count 18446744073709551615 memlock FALSE metadata-locks-cache-size 1024 metadata-locks-hash-instances 8 +metadata-locks-instances 8 mhnsw-default-distance euclidean mhnsw-default-m 6 mhnsw-ef-search 20 @@ -1867,8 +1966,8 @@ net-buffer-length 16384 net-read-timeout 30 net-retry-count 10 net-write-timeout 60 +new-mode note-verbosity basic,explain -old FALSE old-mode UTF8_IS_UTF8MB3 old-passwords FALSE old-style-user-limits FALSE @@ -1885,6 +1984,7 @@ optimizer-key-next-find-cost 0.082347 optimizer-max-sel-arg-weight 32000 optimizer-max-sel-args 16000 optimizer-prune-level 2 +optimizer-record-context FALSE optimizer-row-copy-cost 0.060866 optimizer-row-lookup-cost 0.130839 optimizer-row-next-find-cost 0.045916 @@ -1898,6 +1998,7 @@ optimizer-trace optimizer-trace-max-mem-size 1048576 optimizer-use-condition-selectivity 4 optimizer-where-cost 0.032 +path CURRENT_SCHEMA performance-schema FALSE performance-schema-accounts-size -1 performance-schema-consumer-events-stages-current FALSE @@ -1944,7 +2045,7 @@ performance-schema-max-rwlock-instances -1 performance-schema-max-socket-classes 10 performance-schema-max-socket-instances -1 performance-schema-max-sql-text-length 1024 -performance-schema-max-stage-classes 160 +performance-schema-max-stage-classes 170 performance-schema-max-statement-classes 227 performance-schema-max-statement-stack 10 performance-schema-max-table-handles -1 @@ -2002,7 +2103,6 @@ rpl-semi-sync-slave-enabled FALSE rpl-semi-sync-slave-kill-conn-timeout 5 rpl-semi-sync-slave-trace-level 32 safe-user-create FALSE -secure-auth TRUE secure-file-priv (No default value) secure-timestamp NO server-id 1 diff --git a/mysql-test/main/mysqld--help.test b/mysql-test/main/mysqld--help.test index fc9a5504a6fc9..be27f8b62dda1 100644 --- a/mysql-test/main/mysqld--help.test +++ b/mysql-test/main/mysqld--help.test @@ -2,8 +2,6 @@ # mysqld --help # --source include/not_embedded.inc ---source include/not_asan.inc ---source include/not_ubsan.inc --source include/have_perfschema.inc --source include/have_profiling.inc --source include/platform.inc @@ -40,9 +38,9 @@ perl; test-sql-discovery query-cache-info password-reuse-check query-response-time metadata-lock-info locales unix-socket wsrep file-key-management cracklib-password-check user-variables - provider-bzip2 provider-lzma provider-lzo + provider-bzip2 provider-lzma provider-lzo caching-sha2-password thread-pool-groups thread-pool-queues thread-pool-stats - thread-pool-waits hashicorp provider gssapi parsec/; + thread-pool-waits hashicorp provider gssapi parsec videx/; # And substitute the content some environment variables with their # names: diff --git a/mysql-test/main/mysqld_option_err.result b/mysql-test/main/mysqld_option_err.result index 157edb58532b9..c59d038a3965a 100644 --- a/mysql-test/main/mysqld_option_err.result +++ b/mysql-test/main/mysqld_option_err.result @@ -2,6 +2,7 @@ Test that unknown option is not silently ignored. Test bad binlog format. Test bad default storage engine. Test non-numeric value passed to number option. +Test with invalid path Test that bad value for plugin enum option is rejected correctly. Test to see if multiple unknown options will be displayed in the error output FOUND 1 /unknown option '--nonexistentoption2'/ in mysqltest.log @@ -14,6 +15,8 @@ FOUND 1 /option '--bootstrap' cannot take an argument/ in mysqltest.log FOUND 1 /Integer value out of range for uint64: '18446744073709551616' for binlog_cache_size/ in mysqltest.log FOUND 1 /Unknown suffix 'y' used for variable 'bulk_insert_buffer_size' \(value '123y'\). Legal suffix characters are: K, M, G, T, P, E/ in mysqltest.log FOUND 1 /Error while setting value '123y' to 'bulk_insert_buffer_size'/ in mysqltest.log +FOUND 1 /Error while setting value 'noexist' to 'plugin-example-enum-var'/ in mysqltest.log +FOUND 1 /Variable 'PATH' can't be set to the value of 'a b'/ in mysqltest.log Test that --help --verbose works Test that --not-known-option --help --verbose gives error Done. diff --git a/mysql-test/main/mysqld_option_err.test b/mysql-test/main/mysqld_option_err.test index c2b943bafa1d4..2b98ef0fb9304 100644 --- a/mysql-test/main/mysqld_option_err.test +++ b/mysql-test/main/mysqld_option_err.test @@ -9,6 +9,7 @@ # --source include/not_embedded.inc +--source include/have_example_plugin.inc # mysqld refuses to run as root normally. -- source include/not_as_root.inc @@ -38,13 +39,16 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --error 9 --exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --min-examined-row-limit=notanumber >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 +--echo Test with invalid path +--error 1 +--exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --plugin-dir=$MYSQLTEST_VARDIR/plugins --path="a b" >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 # Test for MBug#423035: error in parsing enum value for plugin # variable in mysqld command-line option. # See also Bug#32034. --echo Test that bad value for plugin enum option is rejected correctly. ---error 7 ---exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --plugin-dir=$MYSQLTEST_VARDIR/plugins --plugin-load=example=ha_example.so --plugin-example-enum-var=noexist >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 +--error 1 +--exec $MYSQLD_BOOTSTRAP_CMD --skip-networking --datadir=$MYSQLTEST_VARDIR/tmp/mysqld_option_err --skip-grant-tables --plugin-maturity=experimental --plugin-load=example=ha_example --plugin-example=FORCE --plugin-example-enum-var=noexist >>$MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log 2>&1 --let SEARCH_FILE = $MYSQLTEST_VARDIR/tmp/mysqld_option_err/mysqltest.log @@ -75,6 +79,10 @@ mkdir $MYSQLTEST_VARDIR/tmp/mysqld_option_err; --source include/search_pattern_in_file.inc --let SEARCH_PATTERN=Error while setting value '123y' to 'bulk_insert_buffer_size' --source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Error while setting value 'noexist' to 'plugin-example-enum-var' +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=Variable 'PATH' can't be set to the value of 'a b' +--source include/search_pattern_in_file.inc # # Test that an wrong option with --help --verbose gives an error diff --git a/mysql-test/main/mysqldump-system-incomplete.result b/mysql-test/main/mysqldump-system-incomplete.result new file mode 100644 index 0000000000000..bd96c02eb32da --- /dev/null +++ b/mysql-test/main/mysqldump-system-incomplete.result @@ -0,0 +1,6 @@ +# +# MDEV-38642 Missing Null terminator in the definition of mysqldump's +# --system typelib +# +# Should not crash +# End of 10.6 tests diff --git a/mysql-test/main/mysqldump-system-incomplete.test b/mysql-test/main/mysqldump-system-incomplete.test new file mode 100644 index 0000000000000..e3fd64dee7c7a --- /dev/null +++ b/mysql-test/main/mysqldump-system-incomplete.test @@ -0,0 +1,11 @@ +--source include/not_embedded.inc + +--echo # +--echo # MDEV-38642 Missing Null terminator in the definition of mysqldump's +--echo # --system typelib +--echo # + +--echo # Should not crash +--exec $MYSQL_DUMP --system=user > /dev/null + +--echo # End of 10.6 tests diff --git a/mysql-test/main/mysqldump-system.test b/mysql-test/main/mysqldump-system.test index dc338cbe7e85c..d23bd18c5d55d 100644 --- a/mysql-test/main/mysqldump-system.test +++ b/mysql-test/main/mysqldump-system.test @@ -125,7 +125,9 @@ set time_zone= @@global.time_zone; --echo # Restore from mysqldump --exec $MYSQL --user mariadb_test_restore --password=getitback --show-warnings < $MYSQLTEST_VARDIR/tmp/dump1.sql +--disable_warnings DROP USER mariadb_test_restore; +--enable_warnings # successful restore? diff --git a/mysql-test/main/mysqldump.result b/mysql-test/main/mysqldump.result index cb1bbfb4a5cde..ec14b283894fb 100644 --- a/mysql-test/main/mysqldump.result +++ b/mysql-test/main/mysqldump.result @@ -38,11 +38,12 @@ CREATE TABLE `t1` ( `a` decimal(64,20) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` VALUES (1234567890123456789012345678901234567890.00000000000000000000), (987654321098765432109876543210987654321.00000000000000000000); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE t1; # # Bug#2055 mysqldump should replace "-inf" numeric field values with "NULL" @@ -58,10 +59,11 @@ CREATE TABLE `t1` ( `a` double DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` VALUES (-1.7976931348623157e308); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE t1; # # Bug#3361 mysqldump quotes DECIMAL values inconsistently @@ -84,14 +86,15 @@ CREATE TABLE `t1` ( `b` float DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` VALUES (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -100,14 +103,15 @@ CREATE TABLE `t1` ( `b` float DEFAULT NULL ); /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` VALUES (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*M!999999\- enable the sandbox mode */ /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; @@ -129,9 +133,9 @@ CREATE TABLE `t1` ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1.23450,2.3456), (1.23450,2.3456), @@ -140,7 +144,8 @@ INSERT INTO `t1` VALUES (1.23450,2.3456); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -166,14 +171,15 @@ CREATE TABLE `t1` ( ); /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` VALUES (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456), (1.23450,2.3456); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -255,14 +261,15 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=koi8r COLLATE=koi8r_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES ('абцде'); INSERT INTO `t1` VALUES (NULL); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -291,15 +298,16 @@ CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1), (2); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -319,15 +327,16 @@ CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1), (2); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -347,8 +356,9 @@ CREATE TABLE ```a` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; -commit; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; drop table ```a`; # # Bug#2591 mysqldump quotes names inconsistently @@ -374,12 +384,13 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -405,12 +416,13 @@ CREATE TABLE "t1" ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES "t1" WRITE; /*!40000 ALTER TABLE "t1" DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE "t1" ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -439,12 +451,13 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -470,12 +483,13 @@ CREATE TABLE "t1" ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES "t1" WRITE; /*!40000 ALTER TABLE "t1" DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE "t1" ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -605,14 +619,15 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES ('ÄÖÜß'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -642,14 +657,15 @@ CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (''); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -669,14 +685,15 @@ CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (''); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -696,14 +713,15 @@ CREATE TABLE `t1` ( `a` char(10) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES ('ÄÖÜß'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -739,16 +757,17 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t2` VALUES (4), (5), (6); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -786,13 +805,14 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (0x602010000280100005E71A); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -830,9 +850,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT IGNORE INTO `t1` VALUES (1), (2), @@ -842,7 +862,8 @@ INSERT IGNORE INTO `t1` VALUES (6); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -873,8 +894,8 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT DELAYED IGNORE INTO `t1` VALUES (1), (2), @@ -883,7 +904,8 @@ INSERT DELAYED IGNORE INTO `t1` VALUES (5), (6); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1580,13 +1602,14 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` (`F_c4ca4238a0b923820dcc509a6f75849b`, `F_c81e728d9d4c2f636f067f89cc14862c`, `F_eccbc87e4b5ce2fe28308fd9f2a7baf3`, `F_a87ff679a2f3e71d9181a67b7542122c`, `F_e4da3b7fbbce2345d7772b0674a318d5`, `F_1679091c5a880faf6fb5e6087eb1b2dc`, `F_8f14e45fceea167a5a36dedd4bea2543`, `F_c9f0f895fb98ab9159f51fd0297e236d`, `F_45c48cce2e2d7fbdea1afc51c7c6ad26`, `F_d3d9446802a44259755d38e6d163e820`, `F_6512bd43d9caa6e02c990b0a82652dca`, `F_c20ad4d76fe97759aa27a0c99bff6710`, `F_c51ce410c124a10e0db5e4b97fc2af39`, `F_aab3238922bcc25a6f606eb525ffdc56`, `F_9bf31c7ff062936a96d3c8bd1f8f2ff3`, `F_c74d97b01eae257e44aa9d5bade97baf`, `F_70efdf2ec9b086079795c442636b55fb`, `F_6f4922f45568161a8cdf4ad2299f6d23`, `F_1f0e3dad99908345f7439f8ffabdffc4`, `F_98f13708210194c475687be6106a3b84`, `F_3c59dc048e8850243be8079a5c74d079`, `F_b6d767d2f8ed5d21a44b0e5886680cb9`, `F_37693cfc748049e45d87b8c7d8b9aacd`, `F_1ff1de774005f8da13f42943881c655f`, `F_8e296a067a37563370ded05f5a3bf3ec`, `F_4e732ced3463d06de0ca9a15b6153677`, `F_02e74f10e0327ad868d138f2b4fdd6f0`, `F_33e75ff09dd601bbe69f351039152189`, `F_6ea9ab1baa0efb9e19094440c317e21b`, `F_34173cb38f07f89ddbebc2ac9128303f`, `F_c16a5320fa475530d9583c34fd356ef5`, `F_6364d3f0f495b6ab9dcf8d3b5c6e0b01`, `F_182be0c5cdcd5072bb1864cdee4d3d6e`, `F_e369853df766fa44e1ed0ff613f563bd`, `F_1c383cd30b7c298ab50293adfecb7b18`, `F_19ca14e7ea6328a42e0eb13d585e4c22`, `F_a5bfc9e07964f8dddeb95fc584cd965d`, `F_a5771bce93e200c36f7cd9dfd0e5deaa`, `F_d67d8ab4f4c10bf22aa353e27879133c`, `F_d645920e395fedad7bbbed0eca3fe2e0`, `F_3416a75f4cea9109507cacd8e2f2aefc`, `F_a1d0c6e83f027327d8461063f4ac58a6`, `F_17e62166fc8586dfa4d1bc0e1742c08b`, `F_f7177163c833dff4b38fc8d2872f1ec6`, `F_6c8349cc7260ae62e3b1396831a8398f`, `F_d9d4f495e875a2e075a1a4a6e1b9770f`, `F_67c6a1e7ce56d3d6fa748ab6d9af3fd7`, `F_642e92efb79421734881b53e1e1b18b6`, `F_f457c545a9ded88f18ecee47145a72c0`, `F_c0c7c76d30bd3dcaefc96f40275bdc0a`, `F_2838023a778dfaecdc212708f721b788`, `F_9a1158154dfa42caddbd0694a4e9bdc8`, `F_d82c8d1619ad8176d665453cfb2e55f0`, `F_a684eceee76fc522773286a895bc8436`, `F_b53b3a3d6ab90ce0268229151c9bde11`, `F_9f61408e3afb633e50cdf1b20de6f466`, `F_72b32a1f754ba1c09b3695e0cb6cde7f`, `F_66f041e16a60928b05a7e228a89c3799`, `F_093f65e080a295f8076b1c5722a46aa2`, `F_072b030ba126b2f4b2374f342be9ed44`, `F_7f39f8317fbdb1988ef4c628eba02591`, `F_44f683a84163b3523afe57c2e008bc8c`, `F_03afdbd66e7929b125f8597834fa83a4`, `F_ea5d2f1c4608232e07d3aa3d998e5135`, `F_fc490ca45c00b1249bbe3554a4fdf6fb`, `F_3295c76acbf4caaed33c36b1b5fc2cb1`, `F_735b90b4568125ed6c3f678819b6e058`, `F_a3f390d88e4c41f2747bfa2f1b5f87db`, `F_14bfa6bb14875e45bba028a21ed38046`, `F_7cbbc409ec990f19c78c75bd1e06f215`, `F_e2c420d928d4bf8ce0ff2ec19b371514`, `F_32bb90e8976aab5298d5da10fe66f21d`, `F_d2ddea18f00665ce8623e36bd4e3c7c5`, `F_ad61ab143223efbc24c7d2583be69251`, `F_d09bf41544a3365a46c9077ebb5e35c3`, `F_fbd7939d674997cdb4692d34de8633c4`, `F_28dd2c7955ce926456240b2ff0100bde`, `F_35f4a8d465e6e1edc05f3d8ab658c551`, `F_d1fe173d08e959397adf34b1d77e88d7`, `F_f033ab37c30201f73f142449d037028d`, `F_43ec517d68b6edd3015b3edc9a11367b`, `F_9778d5d219c5080b9a6a17bef029331c`, `F_fe9fc289c3ff0af142b6d3bead98a923`, `F_68d30a9594728bc39aa24be94b319d21`, `F_3ef815416f775098fe977004015c6193`, `F_93db85ed909c13838ff95ccfa94cebd9`, `F_c7e1249ffc03eb9ded908c236bd1996d`, `F_2a38a4a9316c49e5a833517c45d31070`, `F_7647966b7343c29048673252e490f736`, `F_8613985ec49eb8f757ae6439e879bb2a`, `F_54229abfcfa5649e7003b83dd4755294`, `F_92cc227532d17e56e07902b254dfad10`, `F_98dce83da57b0395e163467c9dae521b`, `F_f4b9ec30ad9f68f89b29639786cb62ef`, `F_812b4ba287f5ee0bc9d43bbf5bbe87fb`, `F_26657d5ff9020d2abefe558796b99584`, `F_e2ef524fbf3d9fe611d5a8e90fefdc9c`, `F_ed3d2c21991e3bef5e069713af9fa6ca`, `F_ac627ab1ccbdb62ec96e702f07f6425b`, `F_f899139df5e1059396431415e770c6dd`, `F_38b3eff8baf56627478ec76a704e9b52`, `F_ec8956637a99787bd197eacd77acce5e`, `F_6974ce5ac660610b44d9b9fed0ff9548`, `F_c9e1074f5b3f9fc8ea15d152add07294`, `F_65b9eea6e1cc6bb9f0cd2a47751a186f`, `F_f0935e4cd5920aa6c7c996a5ee53a70f`, `F_a97da629b098b75c294dffdc3e463904`, `F_a3c65c2974270fd093ee8a9bf8ae7d0b`, `F_2723d092b63885e0d7c260cc007e8b9d`, `F_5f93f983524def3dca464469d2cf9f3e`, `F_698d51a19d8a121ce581499d7b701668`, `F_7f6ffaa6bb0b408017b62254211691b5`, `F_73278a4a86960eeb576a8fd4c9ec6997`, `F_5fd0b37cd7dbbb00f97ba6ce92bf5add`, `F_2b44928ae11fb9384c4cf38708677c48`, `F_c45147dee729311ef5b5c3003946c48f`, `F_eb160de1de89d9058fcb0b968dbbbd68`, `F_5ef059938ba799aaa845e1c2e8a762bd`, `F_07e1cd7dca89a1678042477183b7ac3f`, `F_da4fb5c6e93e74d3df8527599fa62642`, `F_4c56ff4ce4aaf9573aa5dff913df997a`, `F_a0a080f42e6f13b3a2df133f073095dd`, `F_202cb962ac59075b964b07152d234b70`, `F_c8ffe9a587b126f152ed3d89a146b445`, `F_3def184ad8f4755ff269862ea77393dd`, `F_069059b7ef840f0c74a814ec9237b6ec`, `F_ec5decca5ed3d6b8079e2e7e7bacc9f2`, `F_76dc611d6ebaafc66cc0879c71b5db5c`, `F_d1f491a404d6854880943e5c3cd9ca25`, `F_9b8619251a19057cff70779273e95aa6`, `F_1afa34a7f984eeabdbb0a7d494132ee5`, `F_65ded5353c5ee48d0b7d48c591b8f430`, `F_9fc3d7152ba9336a670e36d0ed79bc43`, `F_02522a2b2726fb0a03bb19f2d8d9524d`, `F_7f1de29e6da19d22b51c68001e7e0e54`, `F_42a0e188f5033bc65bf8d78622277c4e`, `F_3988c7f88ebcb58c6ce932b957b6f332`, `F_013d407166ec4fa56eb1e1f8cbe183b9`, `F_e00da03b685a0dd18fb6a08af0923de0`, `F_1385974ed5904a438616ff7bdb3f7439`, `F_0f28b5d49b3020afeecd95b4009adf4c`, `F_a8baa56554f96369ab93e4f3bb068c22`, `F_903ce9225fca3e988c2af215d4e544d3`, `F_0a09c8844ba8f0936c20bd791130d6b6`, `F_2b24d495052a8ce66358eb576b8912c8`, `F_a5e00132373a7031000fd987a3c9f87b`, `F_8d5e957f297893487bd98fa830fa6413`, `F_47d1e990583c9c67424d369f3414728e`, `F_f2217062e9a397a1dca429e7d70bc6ca`, `F_7ef605fc8dba5425d6965fbd4c8fbe1f`, `F_a8f15eda80c50adb0e71943adc8015cf`, `F_37a749d808e46495a8da1e5352d03cae`, `F_b3e3e393c77e35a4a3f3cbd1e429b5dc`, `F_1d7f7abc18fcb43975065399b0d1e48e`, `F_2a79ea27c279e471f4d180b08d62b00a`, `F_1c9ac0159c94d8d0cbedc973445af2da`, `F_6c4b761a28b734fe93831e3fb400ce87`, `F_06409663226af2f3114485aa4e0a23b4`, `F_140f6969d5213fd0ece03148e62e461e`, `F_b73ce398c39f506af761d2277d853a92`, `F_bd4c9ab730f5513206b999ec0d90d1fb`, `F_82aa4b0af34c2313a562076992e50aa3`, `F_0777d5c17d4066b82ab86dff8a46af6f`, `F_fa7cdfad1a5aaf8370ebeda47a1ff1c3`, `F_9766527f2b5d3e95d4a733fcfb77bd7e`, `F_7e7757b1e12abcb736ab9a754ffb617a`, `F_5878a7ab84fb43402106c575658472fa`, `F_006f52e9102a8d3be2fe5614f42ba989`, `F_3636638817772e42b59d74cff571fbb3`, `F_149e9677a5989fd342ae44213df68868`, `F_a4a042cf4fd6bfb47701cbc8a1653ada`, `F_1ff8a7b5dc7a7d1f0ed65aaa29c04b1e`, `F_f7e6c85504ce6e82442c770f7c8606f0`, `F_bf8229696f7a3bb4700cfddef19fa23f`, `F_82161242827b703e6acf9c726942a1e4`, `F_38af86134b65d0f10fe33d30dd76442e`, `F_96da2f590cd7246bbde0051047b0d6f7`, `F_8f85517967795eeef66c225f7883bdcb`, `F_8f53295a73878494e9bc8dd6c3c7104f`, `F_045117b0e0a11a242b9765e79cbf113f`, `F_fc221309746013ac554571fbd180e1c8`, `F_4c5bde74a8f110656874902f07378009`, `F_cedebb6e872f539bef8c3f919874e9d7`, `F_6cdd60ea0045eb7a6ec44c54d29ed402`, `F_eecca5b6365d9607ee5a9d336962c534`, `F_9872ed9fc22fc182d371c3e9ed316094`, `F_31fefc0e570cb3860f2a6d4b38c6490d`, `F_9dcb88e0137649590b755372b040afad`, `F_a2557a7b2e94197ff767970b67041697`, `F_cfecdb276f634854f3ef915e2e980c31`, `F_0aa1883c6411f7873cb83dacb17b0afc`, `F_58a2fc6ed39fd083f55d4182bf88826d`, `F_bd686fd640be98efaae0091fa301e613`, `F_a597e50502f5ff68e3e25b9114205d4a`, `F_0336dcbab05b9d5ad24f4333c7658a0e`, `F_084b6fbb10729ed4da8c3d3f5a3ae7c9`, `F_85d8ce590ad8981ca2c8286f79f59954`, `F_0e65972dce68dad4d52d063967f0a705`, `F_84d9ee44e457ddef7f2c4f25dc8fa865`, `F_3644a684f98ea8fe223c713b77189a77`, `F_757b505cfd34c64c85ca5b5690ee5293`, `F_854d6fae5ee42911677c739ee1734486`, `F_e2c0be24560d78c5e599c2a9c9d0bbd2`, `F_274ad4786c3abca69fa097b85867d9a4`, `F_eae27d77ca20db309e056e3d2dcd7d69`, `F_7eabe3a1649ffa2b3ff8c02ebfd5659f`, `F_69adc1e107f7f7d035d7baf04342e1ca`, `F_091d584fced301b442654dd8c23b3fc9`, `F_b1d10e7bafa4421218a51b1e1f1b0ba2`, `F_6f3ef77ac0e3619e98159e9b6febf557`, `F_eb163727917cbba1eea208541a643e74`, `F_1534b76d325a8f591b52d302e7181331`, `F_979d472a84804b9f647bc185a877a8b5`, `F_ca46c1b9512a7a8315fa3c5a946e8265`, `F_3b8a614226a953a8cd9526fca6fe9ba5`, `F_45fbc6d3e05ebd93369ce542e8f2322d`, `F_63dc7ed1010d3c3b8269faf0ba7491d4`, `F_e96ed478dab8595a7dbda4cbcbee168f`, `F_c0e190d8267e36708f955d7ab048990d`, `F_ec8ce6abb3e952a85b8551ba726a1227`, `F_060ad92489947d410d897474079c1477`, `F_bcbe3365e6ac95ea2c0343a2395834dd`, `F_115f89503138416a242f40fb7d7f338e`, `F_13fe9d84310e77f13a6d184dbf1232f3`, `F_d1c38a09acc34845c6be3a127a5aacaf`, `F_9cfdf10e8fc047a44b08ed031e1f0ed1`, `F_705f2172834666788607efbfca35afb3`, `F_74db120f0a8e5646ef5a30154e9f6deb`, `F_57aeee35c98205091e18d1140e9f38cf`, `F_6da9003b743b65f4c0ccd295cc484e57`, `F_9b04d152845ec0a378394003c96da594`, `F_be83ab3ecd0db773eb2dc1b0a17836a1`, `F_e165421110ba03099a1c0393373c5b43`, `F_289dff07669d7a23de0ef88d2f7129e7`, `F_577ef1154f3240ad5b9b413aa7346a1e`, `F_01161aaa0b6d1345dd8fe4e481144d84`, `F_539fd53b59e3bb12d203f45a912eeaf2`, `F_ac1dd209cbcc5e5d1c6e28598e8cbbe8`, `F_555d6702c950ecb729a966504af0a635`, `F_335f5352088d7d9bf74191e006d8e24c`, `F_f340f1b1f65b6df5b5e3f94d95b11daf`, `F_e4a6222cdb5b34375400904f03d8e6a5`, `F_cb70ab375662576bd1ac5aaf16b3fca4`, `F_9188905e74c28e489b44e954ec0b9bca`, `F_0266e33d3f546cb5436a10798e657d97`, `F_38db3aed920cf82ab059bfccbd02be6a`, `F_3cec07e9ba5f5bb252d13f5f431e4bbb`, `F_621bf66ddb7c962aa0d22ac97d69b793`, `F_077e29b11be80ab57e1a2ecabb7da330`, `F_6c9882bbac1c7093bd25041881277658`, `F_19f3cd308f1455b3fa09a282e0d496f4`, `F_03c6b06952c750899bb03d998e631860`, `F_c24cd76e1ce41366a4bbe8a49b02a028`, `F_c52f1bd66cc19d05628bd8bf27af3ad6`, `F_fe131d7f5a6b38b23cc967316c13dae2`, `F_f718499c1c8cef6730f9fd03c8125cab`, `F_d96409bf894217686ba124d7356686c9`, `F_502e4a16930e414107ee22b6198c578f`, `F_cfa0860e83a4c3a763a7e62d825349f7`, `F_a4f23670e1833f3fdb077ca70bbd5d66`, `F_b1a59b315fc9a3002ce38bbe070ec3f5`, `F_36660e59856b4de58a219bcf4e27eba3`, `F_8c19f571e251e61cb8dd3612f26d5ecf`, `F_d6baf65e0b240ce177cf70da146c8dc8`, `F_e56954b4f6347e897f954495eab16a88`, `F_f7664060cc52bc6f3d620bcedc94a4b6`, `F_eda80a3d5b344bc40f3bc04f65b7a357`, `F_8f121ce07d74717e0b1f21d122e04521`, `F_06138bc5af6023646ede0e1f7c1eac75`, `F_39059724f73a9969845dfe4146c5660e`, `F_7f100b7b36092fb9b06dfb4fac360931`, `F_7a614fd06c325499f1680b9896beedeb`, `F_4734ba6f3de83d861c3176a6273cac6d`, `F_d947bf06a885db0d477d707121934ff8`, `F_63923f49e5241343aa7acb6a06a751e7`, `F_db8e1af0cb3aca1ae2d0018624204529`, `F_20f07591c6fcb220ffe637cda29bb3f6`, `F_07cdfd23373b17c6b337251c22b7ea57`, `F_d395771085aab05244a4fb8fd91bf4ee`, `F_92c8c96e4c37100777c7190b76d28233`, `F_e3796ae838835da0b6f6ea37bcf8bcb7`, `F_6a9aeddfc689c1d0e3b9ccc3ab651bc5`, `F_0f49c89d1e7298bb9930789c8ed59d48`, `F_46ba9f2a6976570b0353203ec4474217`, `F_0e01938fc48a2cfb5f2217fbfb00722d`, `F_16a5cdae362b8d27a1d8f8c7b78b4330`, `F_918317b57931b6b7a7d29490fe5ec9f9`, `F_48aedb8880cab8c45637abc7493ecddd`, `F_839ab46820b524afda05122893c2fe8e`, `F_f90f2aca5c640289d0a29417bcb63a37`, `F_9c838d2e45b2ad1094d42f4ef36764f6`, `F_1700002963a49da13542e0726b7bb758`, `F_53c3bce66e43be4f209556518c2fcb54`, `F_6883966fd8f918a4aa29be29d2c386fb`, `F_49182f81e6a13cf5eaa496d51fea6406`, `F_d296c101daa88a51f6ca8cfc1ac79b50`, `F_9fd81843ad7f202f26c1a174c7357585`, `F_26e359e83860db1d11b6acca57d8ea88`, `F_ef0d3930a7b6c95bd2b32ed45989c61f`, `F_94f6d7e04a4d452035300f18b984988c`, `F_34ed066df378efacc9b924ec161e7639`, `F_577bcc914f9e55d5e4e4f82f9f00e7d4`, `F_11b9842e0a271ff252c1903e7132cd68`, `F_37bc2f75bf1bcfe8450a1a41c200364c`, `F_496e05e1aea0a9c4655800e8a7b9ea28`, `F_b2eb7349035754953b57a32e2841bda5`, `F_8e98d81f8217304975ccb23337bb5761`, `F_a8c88a0055f636e4a163a5e3d16adab7`, `F_eddea82ad2755b24c4e168c5fc2ebd40`, `F_06eb61b839a0cefee4967c67ccb099dc`, `F_9dfcd5e558dfa04aaf37f137a1d9d3e5`, `F_950a4152c2b4aa3ad78bdd6b366cc179`, `F_158f3069a435b314a80bdcb024f8e422`, `F_758874998f5bd0c393da094e1967a72b`, `F_ad13a2a07ca4b7642959dc0c4c740ab6`, `F_3fe94a002317b5f9259f82690aeea4cd`, `F_5b8add2a5d98b1a652ea7fd72d942dac`, `F_432aca3a1e345e339f35a30c8f65edce`, `F_8d3bba7425e7c98c50f52ca1b52d3735`, `F_320722549d1751cf3f247855f937b982`, `F_caf1a3dfb505ffed0d024130f58c5cfa`, `F_5737c6ec2e0716f3d8a7a5c4e0de0d9a`, `F_bc6dc48b743dc5d013b1abaebd2faed2`, `F_f2fc990265c712c49d51a18a32b39f0c`, `F_89f0fd5c927d466d6ec9a21b9ac34ffa`, `F_a666587afda6e89aec274a3657558a27`, `F_b83aac23b9528732c23cc7352950e880`, `F_cd00692c3bfe59267d5ecfac5310286c`, `F_6faa8040da20ef399b63a72d0e4ab575`, `F_fe73f687e5bc5280214e0486b273a5f9`) VALUES (NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,1,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1629,16 +1652,17 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1), (2), (3); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1871,20 +1895,21 @@ insert into t2 (a, b) values (NULL, NULL),(10, NULL),(NULL, "twenty"),(30, "thir /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; /*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (NULL), (10), (20); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t2` VALUES (1,NULL,NULL,NULL,NULL,NULL), (2,10,NULL,NULL,NULL,NULL), @@ -1892,7 +1917,8 @@ INSERT INTO `t2` VALUES (4,30,'thirty',NULL,NULL,NULL); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -1922,16 +1948,17 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (NULL), (10), (20); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -1946,9 +1973,9 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t2` VALUES (1,NULL,NULL,NULL,NULL,NULL), (2,10,NULL,NULL,NULL,NULL), @@ -1956,7 +1983,8 @@ INSERT INTO `t2` VALUES (4,30,'thirty',NULL,NULL,NULL); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -2142,14 +2170,15 @@ CREATE TABLE "t1" ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES "t1" WRITE; /*!40000 ALTER TABLE "t1" DISABLE KEYS */; -set autocommit=0; INSERT INTO "t1" VALUES (815,4711,2006); /*!40000 ALTER TABLE "t1" ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -2180,14 +2209,15 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (815,4711,2006); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -2236,9 +2266,9 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t2` VALUES ('alfred'), ('angie'), @@ -2247,7 +2277,8 @@ INSERT INTO `t2` VALUES ('lemon'); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; @@ -2337,12 +2368,13 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; @@ -2411,9 +2443,9 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t2` VALUES ('alfred'), ('angie'), @@ -2422,7 +2454,8 @@ INSERT INTO `t2` VALUES ('lemon'); /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; @@ -2483,14 +2516,15 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES ('\''); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -2535,16 +2569,17 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1,2,'one'), (2,4,'two'), (3,6,'three'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; @@ -2693,9 +2728,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1,NULL), (2,NULL), @@ -2703,7 +2738,8 @@ INSERT INTO `t1` VALUES (11,NULL); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -2770,12 +2806,13 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -2831,9 +2868,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1,NULL), (2,NULL), @@ -2841,7 +2878,8 @@ INSERT INTO `t1` VALUES (11,NULL); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `t2`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -2850,12 +2888,13 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -2984,9 +3023,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1), (2), @@ -2995,7 +3034,8 @@ INSERT INTO `t1` VALUES (5); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!50003 SET @saved_sql_mode = @@sql_mode */ ; /*!50003 SET sql_mode = 'STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION' */ ; /*!50003 DROP FUNCTION IF EXISTS `bug9056_func1` */; @@ -3144,15 +3184,16 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES ('2003-10-25 22:00:00'), ('2003-10-25 23:00:00'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -3186,15 +3227,16 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES ('2003-10-26 02:00:00'), ('2003-10-26 02:00:00'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; @@ -3243,16 +3285,17 @@ CREATE TABLE "t1 test" ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES "t1 test" WRITE; /*!40000 ALTER TABLE "t1 test" DISABLE KEYS */; -set autocommit=0; INSERT INTO "t1 test" VALUES (1), (2), (3); /*!40000 ALTER TABLE "t1 test" ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -3277,16 +3320,17 @@ CREATE TABLE "t2 test" ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES "t2 test" WRITE; /*!40000 ALTER TABLE "t2 test" DISABLE KEYS */; -set autocommit=0; INSERT INTO "t2 test" VALUES (1), (2), (3); /*!40000 ALTER TABLE "t2 test" ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -3339,16 +3383,17 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1,'first value','xxxx'), (2,'second value','tttt'), (3,'third value','vvv vvv'); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v0`; /*!50001 DROP VIEW IF EXISTS `v0`*/; SET @saved_cs_client = @@character_set_client; @@ -3468,12 +3513,13 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; /*!50003 SET @saved_col_connection = @@collation_connection */ ; @@ -3531,13 +3577,14 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (0x00,''); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -3569,14 +3616,15 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (0x00,''); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -3756,9 +3804,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1232131), (4711), @@ -3766,7 +3814,8 @@ INSERT INTO `t1` VALUES (815); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; @@ -3824,8 +3873,9 @@ CREATE TABLE `basetable` ( UNIQUE KEY `id` (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; -commit; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `mysqldump_views` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; @@ -3934,6 +3984,8 @@ drop table t1; drop table u1; revoke all privileges on mysqldump_myDB.* from myDB_User@localhost; drop user myDB_User@localhost; +Warnings: +Note 4227 Dropped users 'myDB_User'@'localhost' have active connections. Use KILL CONNECTION if they should not be used anymore. drop database mysqldump_myDB; flush privileges; # Bug#21424 continues from here. @@ -4057,12 +4109,13 @@ CREATE TABLE `t2` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t2` WRITE; /*!40000 ALTER TABLE `t2` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t2` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `t3`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -4071,12 +4124,13 @@ CREATE TABLE `t3` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t3` WRITE; /*!40000 ALTER TABLE `t3` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t3` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -4168,10 +4222,11 @@ CREATE TABLE `t1` ( `c2` longblob DEFAULT NULL ); /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` VALUES (11,0x7171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171717171); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE t1; # # Bug#28524 mysqldump --skip-add-drop-table is not @@ -4265,12 +4320,13 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v2`; /*!50001 DROP VIEW IF EXISTS `v2`*/; SET @saved_cs_client = @@character_set_client; @@ -4320,12 +4376,13 @@ CREATE TABLE `straße` ( `f1` int(11) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `straße` WRITE; /*!40000 ALTER TABLE `straße` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `straße` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -4345,12 +4402,13 @@ CREATE TABLE `stra `f1` int(11) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `strae` WRITE; /*!40000 ALTER TABLE `strae` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `strae` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -4372,12 +4430,13 @@ CREATE TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ( `f1` int(11) DEFAULT NULL ) TYPE=MyISAM; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `כדשגכחךלדגכחשךדגחכךלדגכ` WRITE; /*!40000 ALTER TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `כדשגכחךלדגכחשךדגחכךלדגכ` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -4424,9 +4483,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; REPLACE INTO `t1` VALUES (1,1), (2,3), @@ -4434,7 +4493,8 @@ REPLACE INTO `t1` VALUES (4,5); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -4707,9 +4767,9 @@ CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; INSERT INTO `t1` VALUES (1232131), (4711), @@ -4717,7 +4777,8 @@ INSERT INTO `t1` VALUES (815); /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `v1`; /*!50001 DROP VIEW IF EXISTS `v1`*/; SET @saved_cs_client = @@character_set_client; @@ -4824,12 +4885,13 @@ CREATE TABLE `test` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `test` WRITE; /*!40000 ALTER TABLE `test` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `test` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; drop database `test-database`; use test; @@ -5048,8 +5110,9 @@ CREATE TABLE `test` ( `c1` varchar(10) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; -commit; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; ALTER DATABASE `test-database` CHARACTER SET latin1 COLLATE latin1_swedish_ci ; /*!50003 SET @saved_cs_client = @@character_set_client */ ; /*!50003 SET @saved_cs_results = @@character_set_results */ ; @@ -5543,12 +5606,13 @@ CREATE TABLE `t1` ( ); /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `t1` WRITE; /*!40000 ALTER TABLE `t1` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `t1` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; @@ -5561,7 +5625,6 @@ DROP TABLE t1; # Bug#12809202 61854: MYSQLDUMP --SINGLE-TRANSACTION --FLUSH-LOG BREAKS # CONSISTENCY # -DROP DATABASE IF EXISTS b12809202_db; CREATE DATABASE b12809202_db; CREATE TABLE b12809202_db.t1 (c1 INT); CREATE TABLE b12809202_db.t2 (c1 INT); @@ -5826,11 +5889,12 @@ CREATE TABLE `basetable` ( `id` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `basetable` VALUES (5), (6); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( @@ -5853,22 +5917,24 @@ CREATE TABLE `nonunique_table_name` ( UNIQUE KEY `i1` (`i1`) ) ENGINE=MEMORY AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `nonunique_table_name` VALUES (1), (2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_view_name` ( `i2` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `nonunique_table_view_name` VALUES (3), (4); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; USE `db1`; /*!50001 DROP VIEW IF EXISTS `nonunique_table_view_name`*/; @@ -5898,22 +5964,24 @@ CREATE TABLE `nonunique_table_name` ( UNIQUE KEY `i1` (`i1`) ) ENGINE=MEMORY AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `nonunique_table_name` VALUES (1), (2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_view_name` ( `i2` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `nonunique_table_view_name` VALUES (3), (4); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; ################################################## # --compact --delayed-insert --no-data-med=0 --databases db2 db1 @@ -5929,22 +5997,24 @@ CREATE TABLE `nonunique_table_name` ( UNIQUE KEY `i1` (`i1`) ) ENGINE=MEMORY AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT DELAYED INTO `nonunique_table_name` VALUES (1), (2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_view_name` ( `i2` int(11) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `nonunique_table_view_name` VALUES (3), (4); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; CREATE DATABASE /*!32312 IF NOT EXISTS*/ `db1` /*!40100 DEFAULT CHARACTER SET utf8mb3 COLLATE utf8mb3_uca1400_ai_ci */; @@ -5955,22 +6025,24 @@ CREATE TABLE `basetable` ( `id` smallint(6) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT DELAYED INTO `basetable` VALUES (5), (6); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `nonunique_table_name` ( `i3` smallint(6) DEFAULT NULL ) ENGINE=MRG_MyISAM DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_uca1400_ai_ci INSERT_METHOD=LAST UNION=(`basetable`); /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `nonunique_table_name` VALUES (5), (6); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `nonunique_table_view_name` AS SELECT @@ -6263,12 +6335,13 @@ CREATE TABLE `innodb_index_stats` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `innodb_index_stats` WRITE; /*!40000 ALTER TABLE `innodb_index_stats` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `innodb_table_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -6283,12 +6356,13 @@ CREATE TABLE `innodb_table_stats` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `innodb_table_stats` WRITE; /*!40000 ALTER TABLE `innodb_table_stats` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `transaction_registry` ( @@ -6373,12 +6447,13 @@ CREATE TABLE `innodb_index_stats` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `innodb_index_stats` WRITE; /*!40000 ALTER TABLE `innodb_index_stats` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `innodb_index_stats` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; DROP TABLE IF EXISTS `innodb_table_stats`; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; @@ -6393,12 +6468,13 @@ CREATE TABLE `innodb_table_stats` ( ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_bin STATS_PERSISTENT=0; /*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; LOCK TABLES `innodb_table_stats` WRITE; /*!40000 ALTER TABLE `innodb_table_stats` DISABLE KEYS */; -set autocommit=0; /*!40000 ALTER TABLE `innodb_table_stats` ENABLE KEYS */; UNLOCK TABLES; -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE IF NOT EXISTS `transaction_registry` ( @@ -6453,10 +6529,11 @@ CREATE TABLE `t1` ( `b` int(11) DEFAULT NULL INVISIBLE ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL), (1,2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( @@ -6464,11 +6541,12 @@ CREATE TABLE `t2` ( `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t2` VALUES (1,2), (1,2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( @@ -6477,22 +6555,24 @@ CREATE TABLE `t3` ( `ds=~!@ \# $% ^ & * ( ) _ - = +` int(11) DEFAULT 5 INVISIBLE ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5), (5,4,5), (2,4,5), (1,2,3); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t4` ( `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t4` VALUES (1); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; #Check side effect on --complete insert /*M!999999\- enable the sandbox mode */ /*!40101 SET @saved_cs_client = @@character_set_client */; @@ -6502,10 +6582,11 @@ CREATE TABLE `t1` ( `b` int(11) DEFAULT NULL INVISIBLE ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t1` (`a`, `b`) VALUES (1,NULL), (1,2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t2` ( @@ -6513,10 +6594,11 @@ CREATE TABLE `t2` ( `b` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t2` (`a`, `b`) VALUES (1,2), (1,2); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t3` ( @@ -6525,21 +6607,23 @@ CREATE TABLE `t3` ( `ds=~!@ \# $% ^ & * ( ) _ - = +` int(11) DEFAULT 5 INVISIBLE ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t3` (`invisible`, `a b c & $!@#$%^&*( )`, `ds=~!@ \# $% ^ & * ( ) _ - = +`) VALUES (1,4,5), (5,4,5), (2,4,5), (1,2,3); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!40101 SET @saved_cs_client = @@character_set_client */; /*!40101 SET character_set_client = utf8mb4 */; CREATE TABLE `t4` ( `ËÏÌÏÎËÁ1` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; INSERT INTO `t4` (`ËÏÌÏÎËÁ1`) VALUES (1); -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; #Check xml @@ -6870,9 +6954,10 @@ CREATE TABLE `t1` ( `i` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; mariadb-dump: Couldn't execute 'SHOW CREATE FUNCTION `f1`': Undeclared variable: no_such_var (1327) -commit; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; /*!50106 SET @save_time_zone= @@TIME_ZONE */ ; DELIMITER ;; /*!50003 SET @saved_cs_client = @@character_set_client */ ;; @@ -6926,9 +7011,10 @@ CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; -commit; -ERROR at line 11: Not allowed in the sandbox mode +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +ERROR at line 12: Not allowed in the sandbox mode drop table t1; # # MDEV-36268 mariadb-dump used wrong quoting character @@ -6942,8 +7028,9 @@ CREATE TABLE `t1` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; /*!40101 SET character_set_client = @saved_cs_client */; -set autocommit=0; -commit; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8mb4; /*!50001 CREATE VIEW `v'1"2` AS SELECT @@ -6967,6 +7054,52 @@ drop view `v'1"2`; drop table t1; # End of 10.5 tests # +# MDEV-37483 mariadb-dump -T doesn't convert table names +# +create database foo; +use foo; +create table `con_schöne_grüße` (a int) select 1 as a; +create table `con` (b int) select 2 as b; +create table `con/bar` (c int) select 3 as c; +create table `con@fame` (d int) select 4 as d; +drop database foo; +use test; +con@002fbar.sql +con@002fbar.txt +con@@@.sql +con@@@.txt +con@fame.sql +con@fame.txt +con_sch@1ine_gr@1o@1je.sql +con_sch@1ine_gr@1o@1je.txt +show tables; +Tables_in_test +con +con/bar +con@fame +con_schöne_grüße +test.con: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 +test.con/bar: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 +test.con_schöne_grüße: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 +test.con@fame: Records: 1 Deleted: 0 Skipped: 0 Warnings: 0 +select * from `con_schöne_grüße`; +a +1 +select * from `con`; +b +2 +select * from `con/bar`; +c +3 +select * from `con@fame`; +d +4 +drop table `con_schöne_grüße`; +drop table `con`; +drop table `con/bar`; +drop table `con@fame`; +# End of 10.6 tests +# # MDEV-16733 mysqldump --tab and --xml options are conflicting # mariadb-dump: --xml can't be used with --tab or --dir. @@ -7017,3 +7150,907 @@ mariadb-dump: Error: path 'MYSQLTEST_VARDIR/tmp/mysql' exists, but it is not a d mariadb-dump: Path 'MYSQLTEST_VARDIR/tmp/dump' specified by option '--dir' is not a directory mariadb-dump: Path 'MYSQLTEST_VARDIR/does_not_exist' specified by option '--dir' does not exist ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; +# MDEV-21376 mysqldump should support wildcards. +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE TABLE t2(a int); +INSERT INTO t2 VALUES (21),(52),(131); +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS `t2`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES +(21), +(52), +(131); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +DROP DATABASE test1; +# +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE TABLE t2(a int); +INSERT INTO t2 VALUES (21),(52),(131); +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS `t2`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES +(21), +(52), +(131); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +DROP TABLE IF EXISTS `t2`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +INSERT INTO `t2` VALUES +(21), +(52), +(131); +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +DROP DATABASE test1; +# +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE DATABASE test2; +USE test2; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test1`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test2` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test2`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test2` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test2`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +DROP DATABASE test1; +DROP DATABASE test2; +# +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE TABLE tt(a int); +INSERT INTO tt VALUES (2),(5),(11); +CREATE DATABASE test2; +USE test2; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci */; + +USE `test`; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test1`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS `tt`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `tt` WRITE; +/*!40000 ALTER TABLE `tt` DISABLE KEYS */; +INSERT INTO `tt` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `tt` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test2` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test2`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +# +# Table names match multiple patterns. +# +/*M!999999\- enable the sandbox mode */ +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS `tt`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `tt` WRITE; +/*!40000 ALTER TABLE `tt` DISABLE KEYS */; +INSERT INTO `tt` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `tt` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +# +# Database names match multiple patterns. +# +/*M!999999\- enable the sandbox mode */ + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci */; + +USE `test`; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test1` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test1`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS `tt`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `tt` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `tt` WRITE; +/*!40000 ALTER TABLE `tt` DISABLE KEYS */; +INSERT INTO `tt` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `tt` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test2` /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE `test2`; +DROP TABLE IF EXISTS `t1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `t1` WRITE; +/*!40000 ALTER TABLE `t1` DISABLE KEYS */; +INSERT INTO `t1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `t1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP DATABASE test1; +DROP DATABASE test2; +# +CREATE DATABASE test1; +USE test1; +CREATE TABLE table1(a int); +INSERT INTO table1 VALUES (2),(5),(11); +CREATE TABLE tt(a int); +INSERT INTO tt VALUES (2),(5),(11); +/*M!999999\- enable the sandbox mode */ +DROP TABLE IF EXISTS `table1`; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE `table1` ( + `a` int(11) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci; +/*!40101 SET character_set_client = @saved_cs_client */; +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES `table1` WRITE; +/*!40000 ALTER TABLE `table1` DISABLE KEYS */; +INSERT INTO `table1` VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE `table1` ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*M!999999\- enable the sandbox mode */ +DROP DATABASE test1; +# +# +# strange names +# +CREATE DATABASE `t?1`; +USE `t?1`; +CREATE TABLE `t?1`(a int); +INSERT INTO `t?1` VALUES (2),(5),(11); +CREATE TABLE `t%t`(a int); +INSERT INTO `t%t` VALUES (2),(5),(11); +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +DROP TABLE IF EXISTS "t?1"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t?1" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t?1" WRITE; +/*!40000 ALTER TABLE "t?1" DISABLE KEYS */; +INSERT INTO "t?1" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t?1" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +CREATE DATABASE `t%*!`; +USE `t%*!`; +CREATE TABLE `t???1`(a int); +INSERT INTO `t???1` VALUES (2),(5),(11); +CREATE TABLE `t___t`(a int); +INSERT INTO `t___t` VALUES (2),(5),(11); +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ "t%*!" /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE "t%*!"; +DROP TABLE IF EXISTS "t???1"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t???1" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t???1" WRITE; +/*!40000 ALTER TABLE "t???1" DISABLE KEYS */; +INSERT INTO "t???1" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t???1" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS "t___t"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t___t" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t___t" WRITE; +/*!40000 ALTER TABLE "t___t" DISABLE KEYS */; +INSERT INTO "t___t" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t___t" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ "t?1" /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE "t?1"; +DROP TABLE IF EXISTS "t%t"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t%t" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t%t" WRITE; +/*!40000 ALTER TABLE "t%t" DISABLE KEYS */; +INSERT INTO "t%t" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t%t" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS "t?1"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t?1" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t?1" WRITE; +/*!40000 ALTER TABLE "t?1" DISABLE KEYS */; +INSERT INTO "t?1" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t?1" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ "test" /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci */; + +USE "test"; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +DROP TABLE IF EXISTS "t___t"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t___t" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t___t" WRITE; +/*!40000 ALTER TABLE "t___t" DISABLE KEYS */; +INSERT INTO "t___t" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t___t" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; + +CREATE DATABASE /*!32312 IF NOT EXISTS*/ "t?1" /*!40100 DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci */; + +USE "t?1"; +DROP TABLE IF EXISTS "t%t"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t%t" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t%t" WRITE; +/*!40000 ALTER TABLE "t%t" DISABLE KEYS */; +INSERT INTO "t%t" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t%t" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +DROP TABLE IF EXISTS "t?1"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t?1" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t?1" WRITE; +/*!40000 ALTER TABLE "t?1" DISABLE KEYS */; +INSERT INTO "t?1" VALUES +(2), +(5), +(11); +/*!40000 ALTER TABLE "t?1" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +DROP DATABASE `t?1`; +DROP DATABASE `t%*!`; +CREATE DATABASE test1; +USE test1; +create table t_1 (a int); +create table tt1 (b int); +/*M!999999\- enable the sandbox mode */ +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO,ANSI' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +DROP TABLE IF EXISTS "t_1"; +/*!40101 SET @saved_cs_client = @@character_set_client */; +/*!40101 SET character_set_client = utf8mb4 */; +CREATE TABLE "t_1" ( + "a" int(11) DEFAULT NULL +); +/*!40101 SET character_set_client = @saved_cs_client */; + +SET @OLD_AUTOCOMMIT=@@AUTOCOMMIT, @@AUTOCOMMIT=0; +LOCK TABLES "t_1" WRITE; +/*!40000 ALTER TABLE "t_1" DISABLE KEYS */; +/*!40000 ALTER TABLE "t_1" ENABLE KEYS */; +UNLOCK TABLES; +COMMIT; +SET AUTOCOMMIT=@OLD_AUTOCOMMIT; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +DROP DATABASE test1; +# +# no database matches the pattern. +# +mariadb-dump: Error: no databases matching the pattern 'a%' found. +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + +mariadb-dump: Error: no databases matching the pattern 'perf%' found. +/*M!999999\- enable the sandbox mode */ + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8mb4 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*M!100616 SET @OLD_NOTE_VERBOSITY=@@NOTE_VERBOSITY, NOTE_VERBOSITY=0 */; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*M!100616 SET NOTE_VERBOSITY=@OLD_NOTE_VERBOSITY */; + diff --git a/mysql-test/main/mysqldump.test b/mysql-test/main/mysqldump.test index 78d1605741304..340f20a4a51a6 100644 --- a/mysql-test/main/mysqldump.test +++ b/mysql-test/main/mysqldump.test @@ -14,9 +14,6 @@ call mtr.add_suppression("@003f.frm' \\(errno: 22\\)"); let collation=utf8mb3_unicode_ci; --source include/have_collation.inc -# Save the initial number of concurrent sessions ---source include/count_sessions.inc - # There are tables in 'mysql' database of type innodb --source include/have_innodb.inc @@ -1620,8 +1617,10 @@ drop procedure sp1; connection default; disconnect user27293; +--disable_warnings drop user user1; drop user user2; +--enable_warnings drop database mysqldump_test_db; @@ -2351,7 +2350,9 @@ connection conn_1; connection default; disconnect conn_1; +--disable_warnings DROP USER user1; +--enable_warnings DROP DATABASE BUG52792; --echo # UTF-8 CREATE DATABASE BUG52792; @@ -2386,10 +2387,6 @@ DROP TABLE t1; --echo # CONSISTENCY --echo # ---disable_warnings -DROP DATABASE IF EXISTS b12809202_db; ---enable_warnings - CREATE DATABASE b12809202_db; CREATE TABLE b12809202_db.t1 (c1 INT); CREATE TABLE b12809202_db.t2 (c1 INT); @@ -2423,9 +2420,6 @@ DROP DATABASE b12809202_db; --echo # RESET MASTER; -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc - --echo # --echo # Bug#45740 MYSQLDUMP DOESN'T DUMP GENERAL_LOG AND SLOW_QUERY CAUSES RESTORE PROBLEM --echo # @@ -2555,7 +2549,7 @@ DROP DATABASE bug25717383; # # MDEV-6091 mysqldump goes in a loop and segfaults if --dump-slave is specified and it cannot connect to the server # ---replace_regex /mariadb-dump\.exe/mariadb-dump/ /'unknownhost' \(.*\)/'unknownhost'/ +--replace_regex /mariadb-dump\.exe/mariadb-dump/ /'unknownhost' \(.*\)/'unknownhost'/ /Got error: 2002: "Can't connect to server on/Got error: 2005: "Unknown server host/ --error 2 --exec $MYSQL_DUMP --default-character-set=utf8mb4 -hunknownhost --dump-slave nulldb 2>&1 @@ -3043,6 +3037,42 @@ drop table t1; --echo # End of 10.5 tests +--echo # +--echo # MDEV-37483 mariadb-dump -T doesn't convert table names +--echo # +create database foo; +use foo; + +create table `con_schöne_grüße` (a int) select 1 as a; +create table `con` (b int) select 2 as b; +create table `con/bar` (c int) select 3 as c; +create table `con@fame` (d int) select 4 as d; +exec $MYSQL_DUMP foo --tab $MYSQLTEST_VARDIR/tmp; +drop database foo; +use test; +move_file $MYSQLTEST_VARDIR/tmp/con@0040fame.sql $MYSQLTEST_VARDIR/tmp/con@fame.sql; +move_file $MYSQLTEST_VARDIR/tmp/con@0040fame.txt $MYSQLTEST_VARDIR/tmp/con@fame.txt; +list_files $MYSQLTEST_VARDIR/tmp con*; +exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con@@@.sql; +exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con@002fbar.sql; +exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con_sch@1ine_gr@1o@1je.sql; +exec $MYSQL test < $MYSQLTEST_VARDIR/tmp/con@fame.sql; +show tables; +exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con@@@.txt; +exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con@002fbar.txt; +exec $MYSQL_IMPORT --default-character-set=utf8mb4 test $MYSQLTEST_VARDIR/tmp/con_sch@1ine_gr@1o@1je.txt; +exec $MYSQL_IMPORT test $MYSQLTEST_VARDIR/tmp/con@fame.txt; +select * from `con_schöne_grüße`; +select * from `con`; +select * from `con/bar`; +select * from `con@fame`; +drop table `con_schöne_grüße`; +drop table `con`; +drop table `con/bar`; +drop table `con@fame`; + +--echo # End of 10.6 tests + --echo # --echo # MDEV-16733 mysqldump --tab and --xml options are conflicting --echo # @@ -3146,3 +3176,127 @@ EOF --exec $MYSQL_DUMP --dir=$MYSQLTEST_VARDIR/does_not_exist mysql 2>&1 --source include/test_db_charset_restore.inc + +--echo # MDEV-21376 mysqldump should support wildcards. + +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE TABLE t2(a int); +INSERT INTO t2 VALUES (21),(52),(131); +--exec $MYSQL_DUMP --skip-comments --wildcards=ON test1 t_ +--exec $MYSQL_DUMP --skip-comments --wildcards=ON test1 t? tx +DROP DATABASE test1; + +--echo # + +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE TABLE t2(a int); +INSERT INTO t2 VALUES (21),(52),(131); +--exec $MYSQL_DUMP --skip-comments --wildcards=ON test1 t% +--exec $MYSQL_DUMP --skip-comments --wildcards=ON --ignore-table=test1.t1 test1 % +DROP DATABASE test1; + +--echo # + +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE DATABASE test2; +USE test2; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +--exec $MYSQL_DUMP --skip-comments --databases --wildcards=ON test_ +--exec $MYSQL_DUMP --skip-comments --databases --wildcards=ON test_ --ignore-database test1 +DROP DATABASE test1; +DROP DATABASE test2; + +--echo # + +CREATE DATABASE test1; +USE test1; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +CREATE TABLE tt(a int); +INSERT INTO tt VALUES (2),(5),(11); +CREATE DATABASE test2; +USE test2; +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (2),(5),(11); +--exec $MYSQL_DUMP --skip-comments --databases --wildcards=ON t% + +--echo # +--echo # Table names match multiple patterns. +--echo # +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --opt -L test1 "t%" "t%" +--echo # +--echo # Database names match multiple patterns. +--echo # +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --opt -L -B "t%" "t%" + +DROP DATABASE test1; +DROP DATABASE test2; + +--echo # + +CREATE DATABASE test1; +USE test1; +CREATE TABLE table1(a int); +INSERT INTO table1 VALUES (2),(5),(11); +CREATE TABLE tt(a int); +INSERT INTO tt VALUES (2),(5),(11); +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --opt -L test1 table1 +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compact --opt -L test1 tab?e1 + +DROP DATABASE test1; + +--echo # + + +--echo # +--echo # strange names +--echo # + +CREATE DATABASE `t?1`; +USE `t?1`; +CREATE TABLE `t?1`(a int); +INSERT INTO `t?1` VALUES (2),(5),(11); +CREATE TABLE `t%t`(a int); +INSERT INTO `t%t` VALUES (2),(5),(11); +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments -L "t?1" "t%1" +CREATE DATABASE `t%*!`; +USE `t%*!`; +CREATE TABLE `t???1`(a int); +INSERT INTO `t???1` VALUES (2),(5),(11); +CREATE TABLE `t___t`(a int); +INSERT INTO `t___t` VALUES (2),(5),(11); +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments -L -B "t%" +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments -L "t%*!" "t?%1 " +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments -L "t%*!" "t?t" "t%t" +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments --databases -L "t%1" +DROP DATABASE `t?1`; +DROP DATABASE `t%*!`; + +CREATE DATABASE test1; +USE test1; +create table t_1 (a int); +create table tt1 (b int); +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments -L test1 "t\_1" + +DROP DATABASE test1; + +--exec $MYSQL_DUMP --default-character-set=utf8mb4 --compatible=ansi --skip-comments --databases -L "%" >/dev/null + +--echo # +--echo # no database matches the pattern. +--echo # + +--replace_result mariadb-dump.exe mariadb-dump +--exec $MYSQL_DUMP --skip-comments -L -B a% 2>&1 +--replace_result mariadb-dump.exe mariadb-dump +--exec $MYSQL_DUMP --skip-comments --databases --wildcards=ON perf% 2>&1 diff --git a/mysql-test/main/mysqltest.result b/mysql-test/main/mysqltest.result index 7121c4135c192..7bbe7d9a6d0a3 100644 --- a/mysql-test/main/mysqltest.result +++ b/mysql-test/main/mysqltest.result @@ -949,6 +949,10 @@ drop table t1; mysqltest: At line 1: query 'change_user root,,inexistent' failed: ER_BAD_DB_ERROR (1049): Unknown database 'inexistent' mysqltest: At line 1: query 'change_user inexistent,,test' failed: ER_ACCESS_DENIED_ERROR (1045): Access denied for user 'inexistent'@'localhost' (using password: NO) mysqltest: At line 1: query 'change_user root,inexistent,test' failed: ER_ACCESS_DENIED_ERROR (1045): Access denied for user 'root'@'localhost' (using password: YES) +change_user root,,test; +change_user root,,; +change_user root,,; +change_user root,,test; REPLACED_FILE1.txt file1.txt file2.txt @@ -998,4 +1002,4 @@ SELECT 1 /* doesn't throw error */; SELECT 1 /* doesn't throw error */; 1 1 -End of tests +# End of tests diff --git a/mysql-test/main/mysqltest.test b/mysql-test/main/mysqltest.test index eb6c1bffc91b4..3db8e36317074 100644 --- a/mysql-test/main/mysqltest.test +++ b/mysql-test/main/mysqltest.test @@ -9,16 +9,13 @@ echo $mysql_errno before test; echo $mysql_errname before test; --- source include/have_log_bin.inc +--source include/have_log_bin.inc # This test should work in embedded server after mysqltest is fixed --- source include/not_embedded.inc +--source include/not_embedded.inc # This test uses chmod, can't be run with root permissions --- source include/not_as_root.inc - -# Save the initial number of concurrent sessions ---source include/count_sessions.inc +--source include/not_as_root.inc # Some tests below connect/disconnect rapidly in a loop. This causes a race # where mysqld may not have time to register the previous disconnects before @@ -2960,10 +2957,7 @@ set sql_mode=default; SELECT 1 /* doesn't throw error */; SELECT 1 /* doesn't throw error */; ---echo End of tests - -# Wait till we reached the initial number of concurrent sessions ---source include/wait_until_count_sessions.inc +--echo # End of tests --disable_query_log --eval SET GLOBAL max_connections = $saved_max_connections diff --git a/mysql-test/main/mysqltest_expression_evaluation.result b/mysql-test/main/mysqltest_expression_evaluation.result new file mode 100644 index 0000000000000..d9fa0ccb3b835 --- /dev/null +++ b/mysql-test/main/mysqltest_expression_evaluation.result @@ -0,0 +1,508 @@ +# ---------------------------------------------------------------------------- +# Test for MDEV-36107: Add expression evaluation support to mysqltest +# ---------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- +# Test backward compatibility (expressions are not evaluated without $()) +# ---------------------------------------------------------------------------- +# Backward compatibility - no evaluation +5 + 2 (no evaluation) -> 5 + 2 +# ---------------------------------------------------------------------------- +# Basic arithmetic operations +# ---------------------------------------------------------------------------- +# Basic arithmetic operations +10 + 5 -> 15 +10 - 4 -> 6 +3 * 7 -> 21 +20 / 4 -> 5 +21 % 5 -> 1 +# ---------------------------------------------------------------------------- +# Negative numbers and unary minus +# ---------------------------------------------------------------------------- +# Negative numbers and unary minus +-5 -> -5 +-1 + 3 -> 2 +-(2 + 3) -> -5 +-1 * -2 -> 2 +-10 / 2 -> -5 +-7 % 3 -> -1 +# Negative numbers in complex expressions +5 + -3 -> 2 +10 - -5 -> 15 +-2 * 3 + 1 -> -5 +# ---------------------------------------------------------------------------- +# Operator precedence +# ---------------------------------------------------------------------------- +# Operator precedence +2 + 3 * 4 - 1 -> 13 +20 / 2 - 3 -> 7 +10 - 4 + 2 -> 8 +# ---------------------------------------------------------------------------- +# Parentheses override precedence +# ---------------------------------------------------------------------------- +# Parentheses override precedence +(2 + 3) * 4 -> 20 +20 / (5 - 3) -> 10 +((2 + 3) * (4 + 1)) -> 25 +(10 / (3 + 2)) + 1 -> 3 +# ---------------------------------------------------------------------------- +# Test variables in expressions +# ---------------------------------------------------------------------------- +# Variables in expressions +100 / 25 + 1 = 5 +Variable substitution: 10 + 20 == 30 is 1 +# Test multiple variable references +Multiple variables: 10 * 20 / 10 = 20 +# ---------------------------------------------------------------------------- +# Overflow edge cases +# ---------------------------------------------------------------------------- +-9223372036854775808 / -1 -> -9223372036854775808 +-9223372036854775808 % -1 -> 0 +-(-9223372036854775808) -> -9223372036854775808 +-4611686018427387904 * 2 -> -9223372036854775808 +-4611686018427387904 * 2 / -1 -> -9223372036854775808 +-4611686018427387904 * -2 / -1 -> -9223372036854775808 +18446744073709551615 / 2 / -1 -> 0 +# ---------------------------------------------------------------------------- +# Comparison operators +# ---------------------------------------------------------------------------- +# Comparison operators +10 > 5 -> 1 +10 < 5 -> 0 +5 == 5 -> 1 +5 != 5 -> 0 +10 >= 10 -> 1 +10 <= 9 -> 0 +5 <= 5 -> 1 +5 >= 5 -> 1 +5 != 6 -> 1 +18446744073709551615 == -1 -> 0 +18446744073709551615 != -1 -> 1 +18446744073709551615 > -1 -> 1 +18446744073709551615 < -1 -> 0 +18446744073709551615 >= -1 -> 1 +18446744073709551615 <= -1 -> 0 +# NULL comparisons +NULL > 5 -> +NULL < 5 -> +NULL == 5 -> +NULL != 5 -> +NULL >= 5 -> +NULL <= 5 -> +NULL > 5 -> +NULL < 5 -> +NULL == NULL -> +NULL != NULL -> +# ---------------------------------------------------------------------------- +# Logical operators +# ---------------------------------------------------------------------------- +# Logical operators and combinations +1 && 1 -> 1 +1 && 0 -> 0 +0 && 1 -> 0 +0 && 0 -> 0 +2 && 3 -> 1 +2 && 0 -> 0 +-1 && -2 -> 1 +-2 && 2 -> 1 +1 || 1 -> 1 +1 || 0 -> 1 +0 || 1 -> 1 +0 || 0 -> 0 +2 || 3 -> 1 +2 || 0 -> 1 +-1 || -2 -> 1 +-2 || 2 -> 1 +!0 -> 1 +!1 -> 0 +!-3 -> 0 +!10 -> 0 +!-0 -> 1 +1 && 1 && 1 -> 1 +1 && 1 && 0 -> 0 +0 || 0 || 1 -> 1 +0 || 0 || 0 -> 0 +!(5 > 10) -> 1; +!(2 + 3 == 6) -> 1 +# ---------------------------------------------------------------------------- +# Expressions with spaces and formatting +# ---------------------------------------------------------------------------- +# Expressions with varying spaces +10 + 5 (with spaces) -> 15 +10+5 (no spaces) -> 15 +10+ 5 (mixed spaces) -> 15 +# Test spacing in comparisons +Spaced comparison works +No space comparison works +Mixed spacing works +# ---------------------------------------------------------------------------- +# Hex and Binary Literal Tests +# ---------------------------------------------------------------------------- +# Basic hex and binary parsing +0x10 -> 16 +0xFF -> 255 +0x0 -> 0 +0b1010 -> 10 +0b1111 -> 15 +0b0 -> 0 +# ---------------------------------------------------------------------------- +# Hex and Binary Arithmetic +# ---------------------------------------------------------------------------- +# Hex arithmetic operations +0x10 + 0x20 -> 48 +0xFF - 0x0F -> 240 +0x10 * 0x2 -> 32 +0x20 / 0x4 -> 8 +0x17 % 0x5 -> 3 +# Binary arithmetic operations +0b1010 + 0b0101 -> 15 +0b1111 - 0b0011 -> 12 +0b110 * 0b10 -> 12 +0b1000 / 0b10 -> 4 +0b1011 % 0b11 -> 2 +# ---------------------------------------------------------------------------- +# Mixed Base Arithmetic +# ---------------------------------------------------------------------------- +# Mixed base arithmetic (hex + binary + decimal) +0x10 + 0b1000 + 8 -> 32 +0xFF - 0b11111111 -> 0 +0x20 * 0b10 + 5 -> 74 +(0x64 + 0b1100) / 4 -> 28 +# ---------------------------------------------------------------------------- +# Hex and Binary Comparisons +# ---------------------------------------------------------------------------- +# Hex vs decimal comparisons +0x10 == 16 -> 1 +0xFF > 200 -> 1 +0x20 <= 32 -> 1 +0xA != 11 -> 1 +# Binary vs decimal comparisons +0b1010 == 10 -> 1 +0b1111 > 14 -> 1 +0b1000 <= 8 -> 1 +0b101 != 6 -> 1 +# Hex vs binary comparisons +0xFF == 0b11111111 -> 1 +0x10 > 0b1111 -> 1 +0xA <= 0b1010 -> 1 +0x5 != 0b101 -> 0 +# ---------------------------------------------------------------------------- +# Boolean Literal Tests +# ---------------------------------------------------------------------------- +# Boolean literals +true -> 1 +false -> 0 +TRUE -> 1 +FALSE -> 0 +# Boolean operations +true && false -> 0 +true || false -> 1 +true && true -> 1 +true || true -> 1 +!true -> 0 +!false -> 1 +# Boolean comparisons +true == 1 -> 1 +false == 0 -> 1 +true == 10 -> 0 +false == 10 -> 0 +true == 1 -> 1 +false == 1 -> 0 +true == 0 -> 0 +false == 0 -> 1 +true == true -> 1 +true == false -> 0 +true != true -> 0 +true != false -> 1 +true > true -> 0 +true > false -> 1 +true < true -> 0 +true < false -> 0 +true >= true -> 1 +true >= false -> 1 +true <= true -> 1 +true <= false -> 0 +# ---------------------------------------------------------------------------- +# Complex Mixed-Base Expressions +# ---------------------------------------------------------------------------- +# Complex expressions with multiple bases +0x10 + 0b1000 == 0x18 -> 1 +0x20 / 0b100 + 0b11 == 11 -> 1 +# ---------------------------------------------------------------------------- +# Test string comparisons with spaces +# ---------------------------------------------------------------------------- +# String comparisons with spaces +"hello' world" == hello world = 0 +hello world != goodbye world = 1 +# Basic equality: quoted vs quoted +"hello" == "hello" -> 1 +'hello' == 'hello' -> 1 +"hello" == 'hello' -> 1 +"" == "" -> 1 +'' == '' -> 1 +"" == '' -> 1 +# Basic in-equality: quoted vs quoted +"hello" == "world" -> 0 +"hello" == "Hello" -> 0 +"hello" == "hello " -> 0 +"" == "a" -> 0 +# Unquoted vs quoted strings +hello == "hello" -> 1 +hello == 'hello' -> 1 +hello == "hello" -> 1 +hello == " hello " -> 0 +hello world == "hello world" -> 1 +hello world == "hello world" -> 1 +hello world == "hello world" -> 1 +hello world == "hello world" -> 0 +hello world == "hello world" -> 0 +# Unquoted vs unquoted strings +hello == hello -> 1 +hello == hello -> 1 +hello world == hello world -> 1 +hello world == hello world -> 0 +# Strings with special characters (inside quotes) +"'hello'" == "'hello'" -> 1 +'"hello"' == '"hello"' -> 1 +"a+b=c" == "a+b=c" -> 1 +"a*b" == "a*b" -> 1 +"a()b" == "a()b" -> 1 +"a\b" == "a\b" -> 1 +# Complex expressions with string equality +"a" == "a" && 1 == 1 -> 1 +"a" == "b" || "c" == "c" -> 1 +!("a" == "b") -> 1 +(1+2) == 3 && "x" == "x" -> 1 +"x" == "y" || (5 > 3) -> 1 +# Using variables +"test string" == 'test string' -> 1 +"test string" == "another string" -> 0 +"test string" != "another string" -> 1 +"test string" == test string -> 1 +# Using results from SQL +CREATE TABLE t1 (s VARCHAR(20)); +INSERT INTO t1 VALUES ('data'); +data == "data" -> 1 +data == data -> 1 +data == 'data' -> 1 +DROP TABLE t1; +# Edge cases +" " == " " -> 0 +" " == "" -> 0 +"" == "" -> 1 +'\))(' == "\))(" -> 1 +# Numeric strings +"123" == 123 -> 0 +123 == "123" -> 0 +"0" == 0 -> 0 +1 == "1.0" -> 0 +# Mixed quotes in variables +'This is a "quoted" string' == 'This is a "quoted" string' -> 1 +"This is a 'quoted' string" == "This is a 'quoted' string" -> 1 +# Mixed type comparisons +0 != "string" -> 1 +123 == "123" -> 0 +"abc" == 123 -> 0 +NULL == "string" -> +# ---------------------------------------------------------------------------- +# SQL Integration +# ---------------------------------------------------------------------------- +# Expression in SQL query +SQL with expression (7 * 8) -> 56 +# Basic SQL result usage in expressions +Expression with SQL: SQL(15) + 5 -> 20 +# Complex SQL queries in expressions +SQL count matches expression -> 3 +# ---------------------------------------------------------------------------- +# Control Flow Statements (if/while) +# ---------------------------------------------------------------------------- +# Basic if statement conditions +if (1) evaluates to true +Non-zero number is true +Non-empty string is true +Non-empty string with spaces is true +# Variable comparisons in if statements +Arithmetic in comparison: (5 * 2) == 10 is true +# String comparisons in if statements +if (hello != world) evaluates to true +if (hello world == hello world) evaluates to true +# While loop with expression condition +While loop iteration: 3 +While loop iteration: 2 +While loop iteration: 1 +0x10 is greater than 0b1111 +Boolean and hex comparison works +Counter: 0 +Counter: 1 +Counter: 2 +# ---------------------------------------------------------------------------- +# Bitwise operators +# ---------------------------------------------------------------------------- +# Basic bitwise AND (&) +12 & 10 -> 8 +15 & 7 -> 7 +255 & 128 -> 128 +0 & 15 -> 0 +# Basic bitwise OR (|) +12 | 10 -> 14 +8 | 4 -> 12 +1 | 2 -> 3 +0 | 15 -> 15 +# Basic bitwise XOR (^) +12 ^ 10 -> 6 +15 ^ 15 -> 0 +5 ^ 3 -> 6 +255 ^ 128 -> 127 +# Basic bitwise NOT (~) +~0 -> 18446744073709551615 +~1 -> 18446744073709551614 +~255 -> 18446744073709551360 +~(-1) -> 0 +# Basic left shift (<<) +1 << 3 -> 8 +5 << 2 -> 20 +8 << 1 -> 16 +0 << 5 -> 0 +# Basic right shift (>>) +8 >> 3 -> 1 +20 >> 2 -> 5 +16 >> 1 -> 8 +7 >> 3 -> 0 +# ---------------------------------------------------------------------------- +# Bitwise operations with hex and binary literals +# ---------------------------------------------------------------------------- +# Bitwise operations with hex literals +0xFF & 0x0F -> 15 +0xF0 | 0x0F -> 255 +0xFF ^ 0xAA -> 85 +~0xFF -> 18446744073709551360 +0x10 << 2 -> 64 +0x80 >> 4 -> 8 +# Bitwise operations with binary literals +0b1100 & 0b1010 -> 8 +0b1000 | 0b0100 -> 12 +0b1111 ^ 0b1010 -> 5 +~0b1111 -> 18446744073709551600 +0b101 << 2 -> 20 +0b10000 >> 2 -> 4 +# ---------------------------------------------------------------------------- +# Mixed base bitwise operations +# ---------------------------------------------------------------------------- +# Mixed base bitwise operations +0xFF & 0b11110000 -> 240 +0x0F | 0b11110000 -> 255 +255 ^ 0xAA -> 85 +0b1000 << 0x2 -> 32 +0x40 >> 0b10 -> 16 +# ---------------------------------------------------------------------------- +# Bitwise operator precedence +# ---------------------------------------------------------------------------- +# Bitwise operator precedence +12 | 8 ^ 4 -> 12 +12 ^ 8 | 4 -> 4 +12 & 8 ^ 4 -> 12 +12 ^ 8 & 4 -> 4 +12 | 8 & 4 -> 12 +# Parentheses override bitwise precedence +(12 | 8) ^ 4 -> 8 +12 | (8 ^ 4) -> 12 +(12 & 8) | 4 -> 12 +12 & (8 | 4) -> 12 +# ---------------------------------------------------------------------------- +# Shift precedence with arithmetic operators +# ---------------------------------------------------------------------------- +# Shift operators vs arithmetic +2 + 3 << 1 -> 10 +8 >> 1 + 1 -> 2 +4 * 2 << 2 -> 32 +16 >> 2 * 1 -> 4 +# ---------------------------------------------------------------------------- +# Bitwise operations with negative numbers +# ---------------------------------------------------------------------------- +# Bitwise operations with negative numbers (unsigned interpretation) +-1 & 15 -> 15 +-16 | 7 -> 18446744073709551607 +-1 ^ 255 -> 18446744073709551360 +-10 << 3 -> 18446744073709551536 +-10 >> 3 -> 2305843009213693950 +# ---------------------------------------------------------------------------- +# Complex bitwise expressions +# ---------------------------------------------------------------------------- +# Complex bitwise expressions +(0xFF & 0xF0) | (0x0F & 0x05) -> 245 +~(~0xFF | 0x0F) -> 240 +(1 << 4) | (1 << 2) | (1 << 0) -> 21 +(255 >> 2) & (63 << 1) -> 62 +# ---------------------------------------------------------------------------- +# Bitwise operations in conditional expressions +# ---------------------------------------------------------------------------- +# Bitwise operations in conditions +15 & 8 is true (result is 8, non-zero) +!(12 ^ 12) is true +1 << 5 equals 32 +# ---------------------------------------------------------------------------- +# Bitwise operations with variables +# ---------------------------------------------------------------------------- +# Bitwise operations with variables +0xAB & 0xFF -> 171 +0xAB << 4 -> 2736 +0xAB >> 4 -> 10 +~0xAB -> 18446744073709551444 +# ---------------------------------------------------------------------------- +# Bitwise error cases +# ---------------------------------------------------------------------------- +# Testing bitwise error cases +# Shift by negative amount +mysqltest: At line 1: Evaluation error: Invalid shift amount +# Shift by too large amount (>= 64) +mysqltest: At line 1: Evaluation error: Invalid shift amount +mysqltest: At line 1: Evaluation error: Invalid shift amount +# ---------------------------------------------------------------------------- +# Edge cases for shift operations +# ---------------------------------------------------------------------------- +# Edge cases for shift operations +1 << 0 -> 1 +1 << 63 -> 9223372036854775808 +8 >> 0 -> 8 +1 >> 63 -> 0 +# ---------------------------------------------------------------------------- +# Bitwise operations with large numbers +# ---------------------------------------------------------------------------- +# Bitwise operations with large numbers +0x7FFFFFFFFFFFFFFF & 0x7FFFFFFFFFFFFFFE -> 9223372036854775806 +0x7FFFFFFFFFFFFFFF | 0x7FFFFFFFFFFFFFFE -> 9223372036854775807 +0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE -> 1 +# ---------------------------------------------------------------------------- +# Complex expressions with multiple operators +# ---------------------------------------------------------------------------- +# Complex expressions +2 + 3 * 4 > 10 -> 1 +(5 + 5) == (2 * 5) -> 1 +1 + 2 + 3 + 4 == 10 -> 1 +3 + 2 > 4 && 5 > 2 -> 1 +2 * 3 + 1 << 1 & 15 ^ 8 | 4 > 2 -> 1 +1 + 2 * 3 / 2 % 5 << 1 ^ 7 & 15 | 8 > 4 -> 1 +4 + 3 * 2 >> 1 ^ 6 & 3 < 5 | ~1 - 1 % 2 -> 1 +5 * 3 + 7 << 1 ^ 12 >> 2 -> 45056 +8 * 2 / 4 + 3 % 2 << 1 > 2 ^ 1 & 1 | !0 - 2 -> 0 +(!((6 + 3 * 2) > (14 / 2 - 1)) | ((8 << 1) & ~(5 ^ 3)) + (4 >= 2) * (3 <= 3) - (9 % 4 >> 1)) -> 17 +# ---------------------------------------------------------------------------- +# Error Handling (Syntax and Runtime) +# ---------------------------------------------------------------------------- +# Test case: Empty unquoted string (illegal) +mysqltest: At line 1: Syntax error: invalid expression +# Test case: Empty unquoted string with only spaces (illegal) +mysqltest: At line 1: Syntax error: invalid expression +# Test case: Unmatched parenthesis +mysqltest: At line 1: Unmatched parenthesis in expression starting at '$((1 + 2)' +mysqltest: At line 1: Unmatched parenthesis in expression starting at '$(((((((((' +# Test case: Expression evaluator not the entire condition +mysqltest: At line 1: Expression evaluator $(...) must be the entire condition +mysqltest: At line 1: Empty variable +# Test case: Division by zero +mysqltest: At line 1: Evaluation error: Division by zero +# Test case: Modulo by zero +mysqltest: At line 1: Evaluation error: Modulo by zero +# Test case: Overflow +mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type +mysqltest: At line 1: Range error: 18446744073709551616 value out of range for Integer type +# Expression evaluation tests completed successfully diff --git a/mysql-test/main/mysqltest_expression_evaluation.test b/mysql-test/main/mysqltest_expression_evaluation.test new file mode 100644 index 0000000000000..7a108f2fe172f --- /dev/null +++ b/mysql-test/main/mysqltest_expression_evaluation.test @@ -0,0 +1,897 @@ +--echo # ---------------------------------------------------------------------------- +--echo # Test for MDEV-36107: Add expression evaluation support to mysqltest +--echo # ---------------------------------------------------------------------------- + +--source include/not_embedded.inc + +--echo # ---------------------------------------------------------------------------- +--echo # Test backward compatibility (expressions are not evaluated without \$()) +--echo # ---------------------------------------------------------------------------- + +let $old_math = 5 + 2; + +--echo # Backward compatibility - no evaluation +--echo 5 + 2 (no evaluation) -> $old_math + +--echo # ---------------------------------------------------------------------------- +--echo # Basic arithmetic operations +--echo # ---------------------------------------------------------------------------- + +let $a = $(10 + 5); +let $b = $(10 - 4); +let $c = $(3 * 7); +let $d = $(20 / 4); +let $e = $(21 % 5); + +--echo # Basic arithmetic operations +--echo 10 + 5 -> $a +--echo 10 - 4 -> $b +--echo 3 * 7 -> $c +--echo 20 / 4 -> $d +--echo 21 % 5 -> $e + +--echo # ---------------------------------------------------------------------------- +--echo # Negative numbers and unary minus +--echo # ---------------------------------------------------------------------------- + +let $neg1 = $(-5); +let $neg2 = $(-1 + 3); +let $neg3 = $(-(2 + 3)); +let $neg4 = $(-1 * -2); +let $neg5 = $(-10 / 2); +let $neg6 = $(-7 % 3); + +--echo # Negative numbers and unary minus +--echo -5 -> $neg1 +--echo -1 + 3 -> $neg2 +--echo -(2 + 3) -> $neg3 +--echo -1 * -2 -> $neg4 +--echo -10 / 2 -> $neg5 +--echo -7 % 3 -> $neg6 + +let $neg_complex1 = $(5 + -3); +let $neg_complex2 = $(10 - -5); +let $neg_complex3 = $(-2 * 3 + 1); + +--echo # Negative numbers in complex expressions +--echo 5 + -3 -> $neg_complex1 +--echo 10 - -5 -> $neg_complex2 +--echo -2 * 3 + 1 -> $neg_complex3 + +--echo # ---------------------------------------------------------------------------- +--echo # Operator precedence +--echo # ---------------------------------------------------------------------------- + +let $p1 = $(2 + 3 * 4 - 1); +let $p2 = $(20 / 2 - 3); +let $p3 = $(10 - 4 + 2); + +--echo # Operator precedence +--echo 2 + 3 * 4 - 1 -> $p1 +--echo 20 / 2 - 3 -> $p2 +--echo 10 - 4 + 2 -> $p3 + +--echo # ---------------------------------------------------------------------------- +--echo # Parentheses override precedence +--echo # ---------------------------------------------------------------------------- + +let $p4 = $((2 + 3) * 4); +let $p5 = $(20 / (5 - 3)); +let $p6 = $(((2 + 3) * (4 + 1))); +let $p7 = $((10 / (3 + 2)) + 1); + +--echo # Parentheses override precedence +--echo (2 + 3) * 4 -> $p4 +--echo 20 / (5 - 3) -> $p5 +--echo ((2 + 3) * (4 + 1)) -> $p6 +--echo (10 / (3 + 2)) + 1 -> $p7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test variables in expressions +--echo # ---------------------------------------------------------------------------- + +let $v1 = 100; +let $v2 = 25; +let $v_res = $($v1 / $v2 + 1); + +--echo # Variables in expressions +--echo 100 / 25 + 1 = $v_res + + +let $var_a = 10; +let $var_b = 20; +let $var_expr = $($var_a + $var_b == 30); + +--echo Variable substitution: 10 + 20 == 30 is $var_expr + +--echo # Test multiple variable references +let $multi_var = $($var_a * $var_b / $var_a); +--echo Multiple variables: 10 * 20 / 10 = $multi_var + +--echo # ---------------------------------------------------------------------------- +--echo # Overflow edge cases +--echo # ---------------------------------------------------------------------------- + +--echo -9223372036854775808 / -1 -> $(-9223372036854775808 / -1) +--echo -9223372036854775808 % -1 -> $(-9223372036854775808 % -1) +--echo -(-9223372036854775808) -> $(-(-9223372036854775808)) +--echo -4611686018427387904 * 2 -> $(-4611686018427387904 * 2) +--echo -4611686018427387904 * 2 / -1 -> $(-4611686018427387904 * 2 / -1) +--echo -4611686018427387904 * -2 / -1 -> $(-4611686018427387904 * -2 / -1) +--echo 18446744073709551615 / 2 / -1 -> $(18446744073709551615 / 2 / -1) + +--echo # ---------------------------------------------------------------------------- +--echo # Comparison operators +--echo # ---------------------------------------------------------------------------- + +--echo # Comparison operators +--echo 10 > 5 -> $(10 > 5) +--echo 10 < 5 -> $(10 < 5) +--echo 5 == 5 -> $(5 == 5) +--echo 5 != 5 -> $(5 != 5) +--echo 10 >= 10 -> $(10 >= 10) +--echo 10 <= 9 -> $(10 <= 9) +--echo 5 <= 5 -> $(5 <= 5) +--echo 5 >= 5 -> $(5 >= 5) +--echo 5 != 6 -> $(5 != 6) + +--echo 18446744073709551615 == -1 -> $(18446744073709551615 == -1) +--echo 18446744073709551615 != -1 -> $(18446744073709551615 != -1) +--echo 18446744073709551615 > -1 -> $(18446744073709551615 > -1) +--echo 18446744073709551615 < -1 -> $(18446744073709551615 < -1) +--echo 18446744073709551615 >= -1 -> $(18446744073709551615 >= -1) +--echo 18446744073709551615 <= -1 -> $(18446744073709551615 <= -1) + +--echo # NULL comparisons +--echo NULL > 5 -> $(NULL > 5) +--echo NULL < 5 -> $(NULL < 5) +--echo NULL == 5 -> $(NULL == 5) +--echo NULL != 5 -> $(NULL != 5) +--echo NULL >= 5 -> $(NULL >= 5) +--echo NULL <= 5 -> $(NULL <= 5) +--echo NULL > 5 -> $(NULL > 5) +--echo NULL < 5 -> $(NULL < 5) +--echo NULL == NULL -> $(NULL == NULL) +--echo NULL != NULL -> $(NULL != NULL) + +--echo # ---------------------------------------------------------------------------- +--echo # Logical operators +--echo # ---------------------------------------------------------------------------- + +--echo # Logical operators and combinations +--echo 1 && 1 -> $(1 && 1) +--echo 1 && 0 -> $(1 && 0) +--echo 0 && 1 -> $(0 && 1) +--echo 0 && 0 -> $(0 && 0) +--echo 2 && 3 -> $(2 && 3) +--echo 2 && 0 -> $(2 && 0) +--echo -1 && -2 -> $(-1 && -2) +--echo -2 && 2 -> $(-2 && 2) + +--echo 1 || 1 -> $(1 || 1) +--echo 1 || 0 -> $(1 || 0) +--echo 0 || 1 -> $(0 || 1) +--echo 0 || 0 -> $(0 || 0) +--echo 2 || 3 -> $(2 || 3) +--echo 2 || 0 -> $(2 || 0) +--echo -1 || -2 -> $(-1 || -2) +--echo -2 || 2 -> $(-2 || 2) + +--echo !0 -> $(!0) +--echo !1 -> $(!1) +--echo !-3 -> $(!-3) +--echo !10 -> $(!10) +--echo !-0 -> $(!-0) +--echo 1 && 1 && 1 -> $(1 && 1 && 1) +--echo 1 && 1 && 0 -> $(1 && 1 && 0) +--echo 0 || 0 || 1 -> $(0 || 0 || 1) +--echo 0 || 0 || 0 -> $(0 || 0 || 0) +--echo !(5 > 10) -> $(!(5 > 10)); +--echo !(2 + 3 == 6) -> $(!(2 + 3 == 6)) + +--echo # ---------------------------------------------------------------------------- +--echo # Expressions with spaces and formatting +--echo # ---------------------------------------------------------------------------- + +let $spaced = $( 10 + 5 ); +let $no_space = $(10+5); +let $mixed_space = $( 10+ 5 ); + +--echo # Expressions with varying spaces +--echo 10 + 5 (with spaces) -> $spaced +--echo 10+5 (no spaces) -> $no_space +--echo 10+ 5 (mixed spaces) -> $mixed_space + +--echo # Test spacing in comparisons +if ($( 5 == 5 )) +{ + --echo Spaced comparison works +} + +if ($(5< 7)) +{ + --echo No space comparison works +} + +if ($( 5 >= 5 )) +{ + --echo Mixed spacing works +} + +--echo # ---------------------------------------------------------------------------- +--echo # Hex and Binary Literal Tests +--echo # ---------------------------------------------------------------------------- + +--echo # Basic hex and binary parsing +let $hex1 = $(0x10); +let $hex2 = $(0xFF); +let $hex3 = $(0x0); +let $bin1 = $(0b1010); +let $bin2 = $(0b1111); +let $bin3 = $(0b0); + +--echo 0x10 -> $hex1 +--echo 0xFF -> $hex2 +--echo 0x0 -> $hex3 +--echo 0b1010 -> $bin1 +--echo 0b1111 -> $bin2 +--echo 0b0 -> $bin3 + +--echo # ---------------------------------------------------------------------------- +--echo # Hex and Binary Arithmetic +--echo # ---------------------------------------------------------------------------- + +--echo # Hex arithmetic operations +let $hex_add = $(0x10 + 0x20); +let $hex_sub = $(0xFF - 0x0F); +let $hex_mul = $(0x10 * 0x2); +let $hex_div = $(0x20 / 0x4); +let $hex_mod = $(0x17 % 0x5); + +--echo 0x10 + 0x20 -> $hex_add +--echo 0xFF - 0x0F -> $hex_sub +--echo 0x10 * 0x2 -> $hex_mul +--echo 0x20 / 0x4 -> $hex_div +--echo 0x17 % 0x5 -> $hex_mod + +--echo # Binary arithmetic operations +let $bin_add = $(0b1010 + 0b0101); +let $bin_sub = $(0b1111 - 0b0011); +let $bin_mul = $(0b110 * 0b10); +let $bin_div = $(0b1000 / 0b10); +let $bin_mod = $(0b1011 % 0b11); + +--echo 0b1010 + 0b0101 -> $bin_add +--echo 0b1111 - 0b0011 -> $bin_sub +--echo 0b110 * 0b10 -> $bin_mul +--echo 0b1000 / 0b10 -> $bin_div +--echo 0b1011 % 0b11 -> $bin_mod + +--echo # ---------------------------------------------------------------------------- +--echo # Mixed Base Arithmetic +--echo # ---------------------------------------------------------------------------- + +--echo # Mixed base arithmetic (hex + binary + decimal) +let $mixed1 = $(0x10 + 0b1000 + 8); # 16 + 8 + 8 = 32 +let $mixed2 = $(0xFF - 0b11111111); # 255 - 255 = 0 +let $mixed3 = $(0x20 * 0b10 + 10); # 32 * 2 + 10 = 74 +let $mixed4 = $((0x64 + 0b1100) / 4); # (100 + 12) / 4 = 28 + +--echo 0x10 + 0b1000 + 8 -> $mixed1 +--echo 0xFF - 0b11111111 -> $mixed2 +--echo 0x20 * 0b10 + 5 -> $mixed3 +--echo (0x64 + 0b1100) / 4 -> $mixed4 + +--echo # ---------------------------------------------------------------------------- +--echo # Hex and Binary Comparisons +--echo # ---------------------------------------------------------------------------- + +--echo # Hex vs decimal comparisons +--echo 0x10 == 16 -> $(0x10 == 16) +--echo 0xFF > 200 -> $(0xFF > 200) +--echo 0x20 <= 32 -> $(0x20 <= 32) +--echo 0xA != 11 -> $(0xA != 11) + +--echo # Binary vs decimal comparisons +--echo 0b1010 == 10 -> $(0b1010 == 10) +--echo 0b1111 > 14 -> $(0b1111 > 14) +--echo 0b1000 <= 8 -> $(0b1000 <= 8) +--echo 0b101 != 6 -> $(0b101 != 6) + +--echo # Hex vs binary comparisons +--echo 0xFF == 0b11111111 -> $(0xFF == 0b11111111) +--echo 0x10 > 0b1111 -> $(0x10 > 0b1111) +--echo 0xA <= 0b1010 -> $(0xA <= 0b1010) +--echo 0x5 != 0b101 -> $(0x5 != 0b101) + +--echo # ---------------------------------------------------------------------------- +--echo # Boolean Literal Tests +--echo # ---------------------------------------------------------------------------- + +--echo # Boolean literals +let $bool1 = $(true); +let $bool2 = $(false); +let $bool3 = $(TRUE); +let $bool4 = $(FALSE); + +--echo true -> $bool1 +--echo false -> $bool2 +--echo TRUE -> $bool3 +--echo FALSE -> $bool4 + +--echo # Boolean operations +--echo true && false -> $(true && false) +--echo true || false -> $(true || false) +--echo true && true -> $(true && true) +--echo true || true -> $(true || true) +--echo !true -> $(!true) +--echo !false -> $(!false) + +--echo # Boolean comparisons +--echo true == 1 -> $(true == 1) +--echo false == 0 -> $(false == 0) +--echo true == 10 -> $(true == 10) +--echo false == 10 -> $(false == 10) +--echo true == 1 -> $(true == 1) +--echo false == 1 -> $(false == 1) +--echo true == 0 -> $(true == 0) +--echo false == 0 -> $(false == 0) +--echo true == true -> $(true == true) +--echo true == false -> $(true == false) +--echo true != true -> $(true != true) +--echo true != false -> $(true != false) +--echo true > true -> $(true > true) +--echo true > false -> $(true > false) +--echo true < true -> $(true < true) +--echo true < false -> $(true < false) +--echo true >= true -> $(true >= true) +--echo true >= false -> $(true >= false) +--echo true <= true -> $(true <= true) +--echo true <= false -> $(true <= false) + +--echo # ---------------------------------------------------------------------------- +--echo # Complex Mixed-Base Expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Complex expressions with multiple bases +let $complex1 = $(0x10 + 0b1000 == 0x18); # 16 + 8 == 24 +let $complex3 = $(0x20 / 0b100 + 0b11 == 11); # 32/4 + 3 == 11 + +--echo 0x10 + 0b1000 == 0x18 -> $complex1 +--echo 0x20 / 0b100 + 0b11 == 11 -> $complex3 + +--echo # ---------------------------------------------------------------------------- +--echo # Test string comparisons with spaces +--echo # ---------------------------------------------------------------------------- + +--echo # String comparisons with spaces +--echo "hello' world" == hello world = $("hello' world" == hello world) +--echo hello world != goodbye world = $(hello world != goodbye world) + +--echo # Basic equality: quoted vs quoted +--echo "hello" == "hello" -> $("hello" == "hello") +--echo 'hello' == 'hello' -> $('hello' == 'hello') +--echo "hello" == 'hello' -> $("hello" == 'hello') +--echo "" == "" -> $("" == "") +--echo '' == '' -> $('' == '') +--echo "" == '' -> $("" == '') + +--echo # Basic in-equality: quoted vs quoted +--echo "hello" == "world" -> $("hello" == "world") +--echo "hello" == "Hello" -> $("hello" == "Hello") +--echo "hello" == "hello " -> $("hello" == "hello ") +--echo "" == "a" -> $("" == "a") + +--echo # Unquoted vs quoted strings +--echo hello == "hello" -> $(hello == "hello") +--echo hello == 'hello' -> $(hello == 'hello') +--echo hello == "hello" -> $( hello == "hello") +--echo hello == " hello " -> $(hello == " hello ") +--echo hello world == "hello world" -> $(hello world == "hello world") +--echo hello world == "hello world" -> $( hello world == "hello world") +--echo hello world == "hello world" -> $(hello world == "hello world") +--echo hello world == "hello world" -> $(hello world == "hello world") +--echo hello world == "hello world" -> $(hello world == "hello world") + +--echo # Unquoted vs unquoted strings +--echo hello == hello -> $(hello == hello) +--echo hello == hello -> $( hello == hello ) +--echo hello world == hello world -> $(hello world == hello world) +--echo hello world == hello world -> $( hello world == hello world ) + +--echo # Strings with special characters (inside quotes) +--echo "'hello'" == "'hello'" -> $("'hello'" == "'hello'") +--echo '"hello"' == '"hello"' -> $('"hello"' == '"hello"') +--echo "a+b=c" == "a+b=c" -> $("a+b=c" == "a+b=c") +--echo "a*b" == "a*b" -> $("a*b" == "a*b") +--echo "a()b" == "a()b" -> $("a()b" == "a()b") +--echo "a\\b" == "a\\b" -> $("a\\b" == "a\\b") + + +--echo # Complex expressions with string equality +--echo "a" == "a" && 1 == 1 -> $("a" == "a" && 1 == 1) +--echo "a" == "b" || "c" == "c" -> $("a" == "b" || "c" == "c") +--echo !("a" == "b") -> $(!("a" == "b")) +--echo (1+2) == 3 && "x" == "x" -> $((1+2) == 3 && "x" == "x") +--echo "x" == "y" || (5 > 3) -> $("x" == "y" || (5 > 3)) + +--echo # Using variables +let $s1 = "test string"; +let $s2 = 'test string'; +let $s3 = "another string"; +--echo $s1 == $s2 -> $($s1 == $s2) +--echo $s1 == $s3 -> $($s1 == $s3) +--echo $s1 != $s3 -> $($s1 != $s3) +let $s_unquoted = test string; +--echo $s1 == $s_unquoted -> $($s1 == $s_unquoted) + +--echo # Using results from SQL +CREATE TABLE t1 (s VARCHAR(20)); +INSERT INTO t1 VALUES ('data'); +let $sql_res = `SELECT s FROM t1`; +--echo $sql_res == "data" -> $($sql_res == "data") +--echo $sql_res == data -> $($sql_res == data) +--echo $sql_res == 'data' -> $($sql_res == 'data') +DROP TABLE t1; + +--echo # Edge cases +--echo " " == " " -> $(" " == " ") +--echo " " == "" -> $(" " == "") +--echo "" == "" -> $("" == "") +--echo '\))(' == "\))(" -> $('\))(' == "\))(") + +--echo # Numeric strings +--echo "123" == 123 -> $("123" == 123) +--echo 123 == "123" -> $(123 == "123") +--echo "0" == 0 -> $("0" == 0) +--echo 1 == "1.0" -> $(1 == "1.0") + +--echo # Mixed quotes in variables +let $a = 'This is a "quoted" string'; +let $b = "This is a 'quoted' string"; +--echo $a == 'This is a "quoted" string' -> $($a == 'This is a "quoted" string') +--echo $b == "This is a 'quoted' string" -> $($b == "This is a 'quoted' string") + +--echo # Mixed type comparisons +--echo 0 != "string" -> $(0 != string) +--echo 123 == "123" -> $(123 == "123") +--echo "abc" == 123 -> $(abc == 123) +--echo NULL == "string" -> $(NULL == "string") + +--echo # ---------------------------------------------------------------------------- +--echo # SQL Integration +--echo # ---------------------------------------------------------------------------- + +let $val1 = 7; +let $val2 = 8; +let $query_result = `SELECT $($val1 * $val2) as product`; + +--echo # Expression in SQL query +--echo SQL with expression (7 * 8) -> $query_result + +--echo # Basic SQL result usage in expressions +let $sql_val = `SELECT 15`; +let $expr_with_sql = $($sql_val + 5); +--echo Expression with SQL: SQL(15) + 5 -> $expr_with_sql + +--echo # Complex SQL queries in expressions +let $count_result = `SELECT COUNT(*) FROM (SELECT 1 UNION SELECT 2 UNION SELECT 3) t`; +if ($($count_result == 1 + 2)) +{ + --echo SQL count matches expression -> $count_result +} + +--echo # ---------------------------------------------------------------------------- +--echo # Control Flow Statements (if/while) +--echo # ---------------------------------------------------------------------------- + +--echo # Basic if statement conditions +if ($(1)) { + --echo if (1) evaluates to true +} + +if ($(0)) { + --echo This should not print - if (0) is false +} + +if ($(-42)) +{ + --echo Non-zero number is true +} + +if ($(some_string)) +{ + --echo Non-empty string is true +} + +if ($(some string with spaces)) +{ + --echo Non-empty string with spaces is true +} + +--echo # Variable comparisons in if statements +let $x = 5; +if ($(($x * 2) == 10)) { + --echo Arithmetic in comparison: (5 * 2) == 10 is true +} + +--echo # String comparisons in if statements +if ($(hello == world)) { + --echo This should not print - strings don't match +} + +if ($(hello != world)) { + --echo if (hello != world) evaluates to true +} + +if ($(hello world == hello world)) { + --echo if (hello world == hello world) evaluates to true +} + +--echo # While loop with expression condition +let $i = 3; +while ($($i > 0)) { + --echo While loop iteration: $i + --dec $i +} + +if ($(0x10 > 0b1111)) +{ + --echo 0x10 is greater than 0b1111 +} + +if ($(true && (0xFF == 255))) +{ + --echo Boolean and hex comparison works +} + +let $counter = $(0x0); +while ($($counter < 0b11)) +{ + --echo Counter: $counter + --inc $counter +} + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operators +--echo # ---------------------------------------------------------------------------- + +--echo # Basic bitwise AND (&) +let $and1 = $(12 & 10); +let $and2 = $(15 & 7); +let $and3 = $(255 & 128); +let $and4 = $(0 & 15); + +--echo 12 & 10 -> $and1 +--echo 15 & 7 -> $and2 +--echo 255 & 128 -> $and3 +--echo 0 & 15 -> $and4 + +--echo # Basic bitwise OR (|) +let $or1 = $(12 | 10); +let $or2 = $(8 | 4); +let $or3 = $(1 | 2); +let $or4 = $(0 | 15); + +--echo 12 | 10 -> $or1 +--echo 8 | 4 -> $or2 +--echo 1 | 2 -> $or3 +--echo 0 | 15 -> $or4 + +--echo # Basic bitwise XOR (^) +let $xor1 = $(12 ^ 10); +let $xor2 = $(15 ^ 15); +let $xor3 = $(5 ^ 3); +let $xor4 = $(255 ^ 128); + +--echo 12 ^ 10 -> $xor1 +--echo 15 ^ 15 -> $xor2 +--echo 5 ^ 3 -> $xor3 +--echo 255 ^ 128 -> $xor4 + +--echo # Basic bitwise NOT (~) +let $not1 = $(~0); +let $not2 = $(~1); +let $not3 = $(~255); +let $not4 = $(~(-1)); + +--echo ~0 -> $not1 +--echo ~1 -> $not2 +--echo ~255 -> $not3 +--echo ~(-1) -> $not4 + +--echo # Basic left shift (<<) +let $lshift1 = $(1 << 3); +let $lshift2 = $(5 << 2); +let $lshift3 = $(8 << 1); +let $lshift4 = $(0 << 5); + +--echo 1 << 3 -> $lshift1 +--echo 5 << 2 -> $lshift2 +--echo 8 << 1 -> $lshift3 +--echo 0 << 5 -> $lshift4 + +--echo # Basic right shift (>>) +let $rshift1 = $(8 >> 3); +let $rshift2 = $(20 >> 2); +let $rshift3 = $(16 >> 1); +let $rshift4 = $(7 >> 3); + +--echo 8 >> 3 -> $rshift1 +--echo 20 >> 2 -> $rshift2 +--echo 16 >> 1 -> $rshift3 +--echo 7 >> 3 -> $rshift4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with hex and binary literals +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with hex literals +let $hex_and = $(0xFF & 0x0F); +let $hex_or = $(0xF0 | 0x0F); +let $hex_xor = $(0xFF ^ 0xAA); +let $hex_not = $(~0xFF); +let $hex_lshift = $(0x10 << 2); +let $hex_rshift = $(0x80 >> 4); + +--echo 0xFF & 0x0F -> $hex_and +--echo 0xF0 | 0x0F -> $hex_or +--echo 0xFF ^ 0xAA -> $hex_xor +--echo ~0xFF -> $hex_not +--echo 0x10 << 2 -> $hex_lshift +--echo 0x80 >> 4 -> $hex_rshift + +--echo # Bitwise operations with binary literals +let $bin_and = $(0b1100 & 0b1010); +let $bin_or = $(0b1000 | 0b0100); +let $bin_xor = $(0b1111 ^ 0b1010); +let $bin_not = $(~0b1111); +let $bin_lshift = $(0b101 << 2); +let $bin_rshift = $(0b10000 >> 2); + +--echo 0b1100 & 0b1010 -> $bin_and +--echo 0b1000 | 0b0100 -> $bin_or +--echo 0b1111 ^ 0b1010 -> $bin_xor +--echo ~0b1111 -> $bin_not +--echo 0b101 << 2 -> $bin_lshift +--echo 0b10000 >> 2 -> $bin_rshift + +--echo # ---------------------------------------------------------------------------- +--echo # Mixed base bitwise operations +--echo # ---------------------------------------------------------------------------- + +--echo # Mixed base bitwise operations +let $mixed_and = $(0xFF & 0b11110000); +let $mixed_or = $(0x0F | 0b11110000); +let $mixed_xor = $(255 ^ 0xAA); +let $mixed_shift1 = $(0b1000 << 0x2); +let $mixed_shift2 = $(0x40 >> 0b10); + +--echo 0xFF & 0b11110000 -> $mixed_and +--echo 0x0F | 0b11110000 -> $mixed_or +--echo 255 ^ 0xAA -> $mixed_xor +--echo 0b1000 << 0x2 -> $mixed_shift1 +--echo 0x40 >> 0b10 -> $mixed_shift2 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operator precedence +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operator precedence +let $prec1 = $(12 | 8 ^ 4); +let $prec2 = $(12 ^ 8 | 4); +let $prec3 = $(12 & 8 ^ 4); +let $prec4 = $(12 ^ 8 & 4); +let $prec5 = $(12 | 8 & 4); + +--echo 12 | 8 ^ 4 -> $prec1 +--echo 12 ^ 8 | 4 -> $prec2 +--echo 12 & 8 ^ 4 -> $prec3 +--echo 12 ^ 8 & 4 -> $prec4 +--echo 12 | 8 & 4 -> $prec5 + +--echo # Parentheses override bitwise precedence +let $paren1 = $((12 | 8) ^ 4); +let $paren2 = $(12 | (8 ^ 4)); +let $paren3 = $((12 & 8) | 4); +let $paren4 = $(12 & (8 | 4)); + +--echo (12 | 8) ^ 4 -> $paren1 +--echo 12 | (8 ^ 4) -> $paren2 +--echo (12 & 8) | 4 -> $paren3 +--echo 12 & (8 | 4) -> $paren4 + +--echo # ---------------------------------------------------------------------------- +--echo # Shift precedence with arithmetic operators +--echo # ---------------------------------------------------------------------------- + +--echo # Shift operators vs arithmetic +let $shift_arith1 = $(2 + 3 << 1); +let $shift_arith2 = $(8 >> 1 + 1); +let $shift_arith3 = $(4 * 2 << 2); +let $shift_arith4 = $(16 >> 2 * 1); + +--echo 2 + 3 << 1 -> $shift_arith1 +--echo 8 >> 1 + 1 -> $shift_arith2 +--echo 4 * 2 << 2 -> $shift_arith3 +--echo 16 >> 2 * 1 -> $shift_arith4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with negative numbers +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with negative numbers (unsigned interpretation) +let $neg_and = $(-1 & 15); +let $neg_or = $(-16 | 7); +let $neg_xor = $(-1 ^ 255); +let $neg_lshift = $(-10 << 3); +let $neg_rshift = $(-10 >> 3); + +--echo -1 & 15 -> $neg_and +--echo -16 | 7 -> $neg_or +--echo -1 ^ 255 -> $neg_xor +--echo -10 << 3 -> $neg_lshift +--echo -10 >> 3 -> $neg_rshift + +--echo # ---------------------------------------------------------------------------- +--echo # Complex bitwise expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Complex bitwise expressions +let $complex1 = $((0xFF & 0xF0) | (0x0F & 0x05)); +let $complex2 = $(~(~0xFF | 0x0F)); +let $complex3 = $((1 << 4) | (1 << 2) | (1 << 0)); +let $complex4 = $((255 >> 2) & (63 << 1)); + +--echo (0xFF & 0xF0) | (0x0F & 0x05) -> $complex1 +--echo ~(~0xFF | 0x0F) -> $complex2 +--echo (1 << 4) | (1 << 2) | (1 << 0) -> $complex3 +--echo (255 >> 2) & (63 << 1) -> $complex4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations in conditional expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations in conditions +if ($(15 & 8)) +{ + --echo 15 & 8 is true (result is 8, non-zero) +} + +if ($(12 ^ 12)) +{ + --echo This should not print - 12 ^ 12 is 0 +} + +if ($(!(12 ^ 12))) +{ + --echo !(12 ^ 12) is true +} + +if ($((1 << 5) == 32)) +{ + --echo 1 << 5 equals 32 +} + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with variables +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with variables +let $mask = 0xFF; +let $value = 0xAB; +let $shift_amount = 4; + +let $masked = $($value & $mask); +let $shifted_left = $($value << $shift_amount); +let $shifted_right = $($value >> $shift_amount); +let $inverted = $(~$value); + +--echo $value & $mask -> $masked +--echo $value << $shift_amount -> $shifted_left +--echo $value >> $shift_amount -> $shifted_right +--echo ~$value -> $inverted + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise error cases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing bitwise error cases + +--echo # Shift by negative amount +--error 1 +--exec echo "let \$invalid_shift1= \$(5 << -1);" | $MYSQL_TEST 2>&1 + +--echo # Shift by too large amount (>= 64) +--error 1 +--exec echo "let \$invalid_shift2= \$(5 << 64);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$invalid_shift3= \$(100 >> 65);" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Edge cases for shift operations +--echo # ---------------------------------------------------------------------------- + +--echo # Edge cases for shift operations +let $edge_shift1 = $(1 << 0); +let $edge_shift2 = $(1 << 63); +let $edge_shift3 = $(8 >> 0); +let $edge_shift4 = $(1 >> 63); + +--echo 1 << 0 -> $edge_shift1 +--echo 1 << 63 -> $edge_shift2 +--echo 8 >> 0 -> $edge_shift3 +--echo 1 >> 63 -> $edge_shift4 + +--echo # ---------------------------------------------------------------------------- +--echo # Bitwise operations with large numbers +--echo # ---------------------------------------------------------------------------- + +--echo # Bitwise operations with large numbers +let $large_and = $(0x7FFFFFFFFFFFFFFF & 0x7FFFFFFFFFFFFFFE); +let $large_or = $(0x7FFFFFFFFFFFFFFF | 0x7FFFFFFFFFFFFFFE); +let $large_xor = $(0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE); + +--echo 0x7FFFFFFFFFFFFFFF & 0x7FFFFFFFFFFFFFFE -> $large_and +--echo 0x7FFFFFFFFFFFFFFF | 0x7FFFFFFFFFFFFFFE -> $large_or +--echo 0x7FFFFFFFFFFFFFFF ^ 0x7FFFFFFFFFFFFFFE -> $large_xor + +--echo # ---------------------------------------------------------------------------- +--echo # Complex expressions with multiple operators +--echo # ---------------------------------------------------------------------------- + +--echo # Complex expressions +--echo 2 + 3 * 4 > 10 -> $(2 + 3 * 4 > 10) +--echo (5 + 5) == (2 * 5) -> $((5 + 5) == (2 * 5)) +--echo 1 + 2 + 3 + 4 == 10 -> $(1 + 2 + 3 + 4 == 10) +--echo 3 + 2 > 4 && 5 > 2 -> $(3 + 2 > 4 && 5 > 2) +--echo 2 * 3 + 1 << 1 & 15 ^ 8 | 4 > 2 -> $(2 * 3 + 1 << 1 & 15 ^ 8 | 4 > 2) +--echo 1 + 2 * 3 / 2 % 5 << 1 ^ 7 & 15 | 8 > 4 -> $(1 + 2 * 3 / 2 % 5 << 1 ^ 7 & 15 | 8 > 4) +--echo 4 + 3 * 2 >> 1 ^ 6 & 3 < 5 | ~1 - 1 % 2 -> $(4 + 3 * 2 >> 1 ^ 6 & 3 < 5 | ~1 - 1 % 2) +--echo 5 * 3 + 7 << 1 ^ 12 >> 2 -> $(5 * 3 + 7 << 1 ^ 12 >> 2) +--echo 8 * 2 / 4 + 3 % 2 << 1 > 2 ^ 1 & 1 | !0 - 2 -> $(8 * 2 / 4 + 3 % 2 << 1 > 2 ^ 1 & 1 | !0 - 2) +--echo (!((6 + 3 * 2) > (14 / 2 - 1)) | ((8 << 1) & ~(5 ^ 3)) + (4 >= 2) * (3 <= 3) - (9 % 4 >> 1)) -> $(!((6 + 3 * 2) > (14 / 2 - 1)) | ((8 << 1) & ~(5 ^ 3)) + (4 >= 2) * (3 <= 3) - (9 % 4 >> 1)) + +--echo # ---------------------------------------------------------------------------- +--echo # Error Handling (Syntax and Runtime) +--echo # ---------------------------------------------------------------------------- + +--echo # Test case: Empty unquoted string (illegal) +--error 1 +--exec echo "let \$a = \$();" | $MYSQL_TEST 2>&1 + +--echo # Test case: Empty unquoted string with only spaces (illegal) +--error 1 +--exec echo "let \$a = \$( );" | $MYSQL_TEST 2>&1 + +--echo # Test case: Unmatched parenthesis +--error 1 +--exec echo "let \$a = \$((1 + 2);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(((((((((1+3;" | $MYSQL_TEST 2>&1 + +--echo # Test case: Expression evaluator not the entire condition +--error 1 +--exec echo "if(\$(1 + 2) + 3) { echo 'error'; }" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a=3; if (\$a > \$(1 + 2)) { echo 'error'; }" | $MYSQL_TEST 2>&1 + +--echo # Test case: Division by zero +--error 1 +--exec echo "let \$a = \$(5 / 0);" | $MYSQL_TEST 2>&1 + +--echo # Test case: Modulo by zero +--error 1 +--exec echo "let \$a = \$(5 % 0);" | $MYSQL_TEST 2>&1 + +--echo # Test case: Overflow +--error 1 +--exec echo "let \$a = \$(18446744073709551616);" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$a = \$(-18446744073709551616);" | $MYSQL_TEST 2>&1 + +--echo # Expression evaluation tests completed successfully diff --git a/mysql-test/main/mysqltest_string_functions.result b/mysql-test/main/mysqltest_string_functions.result new file mode 100644 index 0000000000000..e6f848cef6f9a --- /dev/null +++ b/mysql-test/main/mysqltest_string_functions.result @@ -0,0 +1,1093 @@ +# ---------------------------------------------------------------------------- +# Test for MDEV-36108: Variable substitutions in mysqltest +# ---------------------------------------------------------------------------- +# ---------------------------------------------------------------------------- +# Test conversion functions (conv, bin, oct, hex) +# ---------------------------------------------------------------------------- +# Basic conv() function tests +conv(10, 10, 2) -> 1010 +conv(255, 10, 16) -> FF +conv(FF, 16, 10) -> 255 +conv(1010, 2, 10) -> 10 +conv(64, 10, 8) -> 100 +conv(77, 8, 10) -> 63 +# ---------------------------------------------------------------------------- +# Test shortcut functions bin(), oct(), hex() +# ---------------------------------------------------------------------------- +# Testing bin() function +bin(10) -> 1010 +bin(255) -> 11111111 +bin(0) -> 0 +# Testing oct() function +oct(64) -> 100 +oct(512) -> 1000 +# Testing hex() function +hex(255) -> FF +hex(4095) -> FFF +# ---------------------------------------------------------------------------- +# Test extended base support (bases 2-62) +# ---------------------------------------------------------------------------- +# Testing extended bases +conv(ZZ, 36, 10) -> 1295 +# ---------------------------------------------------------------------------- +# Test signed vs unsigned interpretation +# ---------------------------------------------------------------------------- +# Testing signed vs unsigned interpretation +conv(-1, 10, 16) -> FFFFFFFFFFFFFFFF +conv(-1, 10, -16) -> -1 +conv(-10, 10, 2) -> 1111111111111111111111111111111111111111111111111111111111110110 +conv(-10, 10, -2) -> -1010 +conv(-255, 10, 16) -> FFFFFFFFFFFFFF01 +conv(-255, 10, -16) -> -FF +conv(-1234, -10, 2) -> 1111111111111111111111111111111111111111111111111111101100101110 +conv(-1234, -10, -2) -> -10011010010 +# ---------------------------------------------------------------------------- +# Edge cases and boundary conditions +# ---------------------------------------------------------------------------- +# Testing edge cases and boundaries +conv(0, 10, 2) -> 0 +conv(0, 16, 10) -> 0 +conv(9223372036854775807, 10, 16) -> 7FFFFFFFFFFFFFFF +conv(~0, 10, 2) -> 1111111111111111111111111111111111111111111111111111111111111111 +conv(7FFFFFFFFFFFFFFF, 16, 10) -> 9223372036854775807 +conv(777777777777777777777, 8, 10) -> 9223372036854775807 +conv(1111111111111111111111111111111111111111111111111111111111111111, 2, 10) -> 18446744073709551615 +conv(9223372036854775807, 10, 2) -> 111111111111111111111111111111111111111111111111111111111111111 +conv(18446744073709551615, 10, 16) -> FFFFFFFFFFFFFFFF +conv(18446744073709551615, 10, 2) -> 1111111111111111111111111111111111111111111111111111111111111111 +conv(-~0, 10, 2) -> 1 +conv(0000123, 10, 16) -> 7B +# ---------------------------------------------------------------------------- +# Test case sensitivity in conversion +# ---------------------------------------------------------------------------- +# Testing case sensitivity +conv(AbCd, 16, 10) -> 43981 +conv(abcd, 16, 10) -> 43981 +conv(ABCD, 16, 10) -> 43981 +# ---------------------------------------------------------------------------- +# Test with variables and expressions +# ---------------------------------------------------------------------------- +# Testing with variables and expressions +conv(FF, 16, 10) -> 255 +# ---------------------------------------------------------------------------- +# Error cases - Invalid bases +# ---------------------------------------------------------------------------- +# Testing error cases - Invalid bases +# Base too small (< 2) +mysqltest: At line 1: conv() from_base must be between 2 and 62, got 1 +# Base too large (> 62 for our parser, > 36 for MariaDB) +mysqltest: At line 1: conv() from_base must be between 2 and 62, got 63 +# Zero base +mysqltest: At line 1: conv() from_base must be between 2 and 62, got 0 +# ---------------------------------------------------------------------------- +# Error cases - Invalid characters for base +# ---------------------------------------------------------------------------- +# Testing error cases - Invalid characters +# Character not valid for base 8 +mysqltest: At line 1: invalid number '189' for base 8 +# Character not valid for base 16 +mysqltest: At line 1: invalid number 'XYZ' for base 16 +# Special characters +mysqltest: At line 1: invalid number '@#$' for base 36 +# ---------------------------------------------------------------------------- +# Error cases - Function argument count +# ---------------------------------------------------------------------------- +# Testing error cases - Wrong argument count +# Too few arguments for conv +mysqltest: At line 1: conv() expects 3 arguments (N, from_base, to_base), got 2 +# Too many arguments for conv +mysqltest: At line 1: conv() expects 3 arguments (N, from_base, to_base), got 4 +# Too many arguments for bin +mysqltest: At line 1: bin() expects 1 argument, got 2 +# No arguments for hex +mysqltest: At line 1: hex() expects 1 argument, got 0 +# ---------------------------------------------------------------------------- +# Overflow cases +# ---------------------------------------------------------------------------- +# Testing overflow cases +# Number too large for 64-bit +mysqltest: At line 1: Range error: 99999999999999999999999999999999 value out of range for Integer type +# Very long hex string that would cause overflow +mysqltest: At line 1: Range error: value out of range for Integer type +# ---------------------------------------------------------------------------- +# Test REPLACE function +# ---------------------------------------------------------------------------- +# Basic REPLACE function tests +replace("hello world", "world", "mariadb") -> "hello mariadb" +replace("hello hello hello", "hello", "hi") -> "hi hi hi" +replace("test string", "test", "") -> " string" +replace("no change", "missing", "replacement") -> "no change" +# ---------------------------------------------------------------------------- +# REPLACE with empty strings +# ---------------------------------------------------------------------------- +# REPLACE with empty strings +replace("hello world", "", "test") -> "hello world" +replace("hello world", "hello", "") -> " world" +replace("", "test", "replacement") -> "" +# ---------------------------------------------------------------------------- +# REPLACE with special characters +# ---------------------------------------------------------------------------- +# REPLACE with special characters +replace("a+b=c", "+", "-") -> "a-b=c" +replace("test\nstring", "\n", " ") -> "test string" +replace("quoted 'string'", "'", "") -> "quoted string" +replace('quoted "string"', '"', "") -> "quoted string" +# ---------------------------------------------------------------------------- +# REPLACE with variables +# ---------------------------------------------------------------------------- +# REPLACE with variables +replace("hello world", "world", "mariadb") -> "hello mariadb" +replace("test test test", "test", "mariadb") -> "mariadb mariadb mariadb" +# ---------------------------------------------------------------------------- +# REPLACE edge cases +# ---------------------------------------------------------------------------- +# REPLACE edge cases +replace("aaa", "aa", "b") -> "ba" +replace("aaaa", "aa", "b") -> "bb" +replace("test", "test", "test") -> "test" +replace("", "", "something") -> "" +# ---------------------------------------------------------------------------- +# Test SUBSTR function +# ---------------------------------------------------------------------------- +# SUBSTR function +substr("hello", -7, -7) -> "" +substr("hello", -7, -6) -> "" +substr("hello", -7, -5) -> "" +substr("hello", -7, -4) -> "" +substr("hello", -7, -3) -> "" +substr("hello", -7, -2) -> "" +substr("hello", -7, -1) -> "" +substr("hello", -7, 0) -> "" +substr("hello", -7, 1) -> "" +substr("hello", -7, 2) -> "" +substr("hello", -7, 3) -> "" +substr("hello", -7, 4) -> "" +substr("hello", -7, 5) -> "" +substr("hello", -7, 6) -> "" +substr("hello", -7, 7) -> "" +substr("hello", -6, -7) -> "" +substr("hello", -6, -6) -> "" +substr("hello", -6, -5) -> "" +substr("hello", -6, -4) -> "" +substr("hello", -6, -3) -> "" +substr("hello", -6, -2) -> "" +substr("hello", -6, -1) -> "" +substr("hello", -6, 0) -> "" +substr("hello", -6, 1) -> "" +substr("hello", -6, 2) -> "" +substr("hello", -6, 3) -> "" +substr("hello", -6, 4) -> "" +substr("hello", -6, 5) -> "" +substr("hello", -6, 6) -> "" +substr("hello", -6, 7) -> "" +substr("hello", -5, -7) -> "" +substr("hello", -5, -6) -> "" +substr("hello", -5, -5) -> "" +substr("hello", -5, -4) -> "" +substr("hello", -5, -3) -> "" +substr("hello", -5, -2) -> "" +substr("hello", -5, -1) -> "" +substr("hello", -5, 0) -> "" +substr("hello", -5, 1) -> "h" +substr("hello", -5, 2) -> "he" +substr("hello", -5, 3) -> "hel" +substr("hello", -5, 4) -> "hell" +substr("hello", -5, 5) -> "hello" +substr("hello", -5, 6) -> "hello" +substr("hello", -5, 7) -> "hello" +substr("hello", -4, -7) -> "" +substr("hello", -4, -6) -> "" +substr("hello", -4, -5) -> "" +substr("hello", -4, -4) -> "" +substr("hello", -4, -3) -> "" +substr("hello", -4, -2) -> "" +substr("hello", -4, -1) -> "" +substr("hello", -4, 0) -> "" +substr("hello", -4, 1) -> "e" +substr("hello", -4, 2) -> "el" +substr("hello", -4, 3) -> "ell" +substr("hello", -4, 4) -> "ello" +substr("hello", -4, 5) -> "ello" +substr("hello", -4, 6) -> "ello" +substr("hello", -4, 7) -> "ello" +substr("hello", -3, -7) -> "" +substr("hello", -3, -6) -> "" +substr("hello", -3, -5) -> "" +substr("hello", -3, -4) -> "" +substr("hello", -3, -3) -> "" +substr("hello", -3, -2) -> "" +substr("hello", -3, -1) -> "" +substr("hello", -3, 0) -> "" +substr("hello", -3, 1) -> "l" +substr("hello", -3, 2) -> "ll" +substr("hello", -3, 3) -> "llo" +substr("hello", -3, 4) -> "llo" +substr("hello", -3, 5) -> "llo" +substr("hello", -3, 6) -> "llo" +substr("hello", -3, 7) -> "llo" +substr("hello", -2, -7) -> "" +substr("hello", -2, -6) -> "" +substr("hello", -2, -5) -> "" +substr("hello", -2, -4) -> "" +substr("hello", -2, -3) -> "" +substr("hello", -2, -2) -> "" +substr("hello", -2, -1) -> "" +substr("hello", -2, 0) -> "" +substr("hello", -2, 1) -> "l" +substr("hello", -2, 2) -> "lo" +substr("hello", -2, 3) -> "lo" +substr("hello", -2, 4) -> "lo" +substr("hello", -2, 5) -> "lo" +substr("hello", -2, 6) -> "lo" +substr("hello", -2, 7) -> "lo" +substr("hello", -1, -7) -> "" +substr("hello", -1, -6) -> "" +substr("hello", -1, -5) -> "" +substr("hello", -1, -4) -> "" +substr("hello", -1, -3) -> "" +substr("hello", -1, -2) -> "" +substr("hello", -1, -1) -> "" +substr("hello", -1, 0) -> "" +substr("hello", -1, 1) -> "o" +substr("hello", -1, 2) -> "o" +substr("hello", -1, 3) -> "o" +substr("hello", -1, 4) -> "o" +substr("hello", -1, 5) -> "o" +substr("hello", -1, 6) -> "o" +substr("hello", -1, 7) -> "o" +substr("hello", 0, -7) -> "" +substr("hello", 0, -6) -> "" +substr("hello", 0, -5) -> "" +substr("hello", 0, -4) -> "" +substr("hello", 0, -3) -> "" +substr("hello", 0, -2) -> "" +substr("hello", 0, -1) -> "" +substr("hello", 0, 0) -> "" +substr("hello", 0, 1) -> "" +substr("hello", 0, 2) -> "" +substr("hello", 0, 3) -> "" +substr("hello", 0, 4) -> "" +substr("hello", 0, 5) -> "" +substr("hello", 0, 6) -> "" +substr("hello", 0, 7) -> "" +substr("hello", 1, -7) -> "" +substr("hello", 1, -6) -> "" +substr("hello", 1, -5) -> "" +substr("hello", 1, -4) -> "" +substr("hello", 1, -3) -> "" +substr("hello", 1, -2) -> "" +substr("hello", 1, -1) -> "" +substr("hello", 1, 0) -> "" +substr("hello", 1, 1) -> "h" +substr("hello", 1, 2) -> "he" +substr("hello", 1, 3) -> "hel" +substr("hello", 1, 4) -> "hell" +substr("hello", 1, 5) -> "hello" +substr("hello", 1, 6) -> "hello" +substr("hello", 1, 7) -> "hello" +substr("hello", 2, -7) -> "" +substr("hello", 2, -6) -> "" +substr("hello", 2, -5) -> "" +substr("hello", 2, -4) -> "" +substr("hello", 2, -3) -> "" +substr("hello", 2, -2) -> "" +substr("hello", 2, -1) -> "" +substr("hello", 2, 0) -> "" +substr("hello", 2, 1) -> "e" +substr("hello", 2, 2) -> "el" +substr("hello", 2, 3) -> "ell" +substr("hello", 2, 4) -> "ello" +substr("hello", 2, 5) -> "ello" +substr("hello", 2, 6) -> "ello" +substr("hello", 2, 7) -> "ello" +substr("hello", 3, -7) -> "" +substr("hello", 3, -6) -> "" +substr("hello", 3, -5) -> "" +substr("hello", 3, -4) -> "" +substr("hello", 3, -3) -> "" +substr("hello", 3, -2) -> "" +substr("hello", 3, -1) -> "" +substr("hello", 3, 0) -> "" +substr("hello", 3, 1) -> "l" +substr("hello", 3, 2) -> "ll" +substr("hello", 3, 3) -> "llo" +substr("hello", 3, 4) -> "llo" +substr("hello", 3, 5) -> "llo" +substr("hello", 3, 6) -> "llo" +substr("hello", 3, 7) -> "llo" +substr("hello", 4, -7) -> "" +substr("hello", 4, -6) -> "" +substr("hello", 4, -5) -> "" +substr("hello", 4, -4) -> "" +substr("hello", 4, -3) -> "" +substr("hello", 4, -2) -> "" +substr("hello", 4, -1) -> "" +substr("hello", 4, 0) -> "" +substr("hello", 4, 1) -> "l" +substr("hello", 4, 2) -> "lo" +substr("hello", 4, 3) -> "lo" +substr("hello", 4, 4) -> "lo" +substr("hello", 4, 5) -> "lo" +substr("hello", 4, 6) -> "lo" +substr("hello", 4, 7) -> "lo" +substr("hello", 5, -7) -> "" +substr("hello", 5, -6) -> "" +substr("hello", 5, -5) -> "" +substr("hello", 5, -4) -> "" +substr("hello", 5, -3) -> "" +substr("hello", 5, -2) -> "" +substr("hello", 5, -1) -> "" +substr("hello", 5, 0) -> "" +substr("hello", 5, 1) -> "o" +substr("hello", 5, 2) -> "o" +substr("hello", 5, 3) -> "o" +substr("hello", 5, 4) -> "o" +substr("hello", 5, 5) -> "o" +substr("hello", 5, 6) -> "o" +substr("hello", 5, 7) -> "o" +substr("hello", 6, -7) -> "" +substr("hello", 6, -6) -> "" +substr("hello", 6, -5) -> "" +substr("hello", 6, -4) -> "" +substr("hello", 6, -3) -> "" +substr("hello", 6, -2) -> "" +substr("hello", 6, -1) -> "" +substr("hello", 6, 0) -> "" +substr("hello", 6, 1) -> "" +substr("hello", 6, 2) -> "" +substr("hello", 6, 3) -> "" +substr("hello", 6, 4) -> "" +substr("hello", 6, 5) -> "" +substr("hello", 6, 6) -> "" +substr("hello", 6, 7) -> "" +substr("hello", 7, -7) -> "" +substr("hello", 7, -6) -> "" +substr("hello", 7, -5) -> "" +substr("hello", 7, -4) -> "" +substr("hello", 7, -3) -> "" +substr("hello", 7, -2) -> "" +substr("hello", 7, -1) -> "" +substr("hello", 7, 0) -> "" +substr("hello", 7, 1) -> "" +substr("hello", 7, 2) -> "" +substr("hello", 7, 3) -> "" +substr("hello", 7, 4) -> "" +substr("hello", 7, 5) -> "" +substr("hello", 7, 6) -> "" +substr("hello", 7, 7) -> "" +substr("hello world", 1, 5) -> "hello" +substr("hello world", 7) -> "world" +substr("hello world", 1, 3) -> "hel" +substr("hello world", 7, 5) -> "world" +# ---------------------------------------------------------------------------- +# SUBSTR with negative indices +# ---------------------------------------------------------------------------- +# SUBSTR with negative indices +substr("hello world", -5) -> "world" +substr("hello world", -5, 3) -> "wor" +substr("hello world", -10, 5) -> "ello " +substr("hello world", -20) -> "" +# ---------------------------------------------------------------------------- +# SUBSTR boundary conditions +# ---------------------------------------------------------------------------- +# SUBSTR boundary conditions +substr("hello world", 1, 0) -> "" +substr("hello world", 1, 20) -> "hello world" +substr("hello world", 12) -> "" +substr("hello world", 0) -> "" +substr("hello world", 0, 5) -> "" +# ---------------------------------------------------------------------------- +# SUBSTR with variables +# ---------------------------------------------------------------------------- +# SUBSTR with variables +substr("hello world", 7, 5) -> "world" +substr("hello world", -5) -> "world" +# ---------------------------------------------------------------------------- +# SUBSTR edge cases +# ---------------------------------------------------------------------------- +# SUBSTR edge cases +substr("", 1) -> "" +substr("a", 1, 5) -> "a" +substr("hello", 1, -1) -> "" +substr("hello", 5, 1) -> "o" +# ---------------------------------------------------------------------------- +# Combined function tests +# ---------------------------------------------------------------------------- +# Combined function tests +replace(substr("hello world", 1, 5), "hello", "hi") -> "hi" +substr(replace("hello world", "world", "mariadb"), 7) -> "mariadb" +replace(substr("test test test", 1, 9), "test", "check") -> "check check" +upper(replace("hello world", "world", "mariadb")) -> "HELLO MARIADB" +length(trim(replace(" hello world ", "world", "mariadb"))) -> "13" +instr(lower("HELLO WORLD"), "world") -> 7 +locate(upper("o"), upper("hello world")) -> 5 +reverse(substr(upper("hello world"), 1, 5)) -> "OLLEH" +# ---------------------------------------------------------------------------- +# String functions in while loops +# ---------------------------------------------------------------------------- +# String functions in while loops +Character at position 1: h (upper: H, lower: h) +Character at position 2: e (upper: E, lower: e) +Character at position 3: l (upper: L, lower: l) +Character at position 4: l (upper: L, lower: l) +Character at position 5: o (upper: O, lower: o) +# String processing with multiple functions +Original: "HelloWorld" -> Processed: HeLLoWoRLD +# ---------------------------------------------------------------------------- +# Error cases for REPLACE function +# ---------------------------------------------------------------------------- +# Testing error cases for REPLACE function +# Wrong number of arguments +mysqltest: At line 1: replace() expects 3 arguments (str, from, to), got 1 +mysqltest: At line 1: replace() expects 3 arguments (str, from, to), got 2 +mysqltest: At line 1: replace() expects 3 arguments (str, from, to), got 4 +# Wrong argument types +mysqltest: At line 1: replace() arguments must be strings +mysqltest: At line 1: replace() arguments must be strings +mysqltest: At line 1: replace() arguments must be strings +# ---------------------------------------------------------------------------- +# Error cases for SUBSTR function +# ---------------------------------------------------------------------------- +# Testing error cases for SUBSTR function +# Wrong number of arguments +mysqltest: At line 1: substr() expects 2 or 3 arguments (str, start [, length]), got 1 +mysqltest: At line 1: substr() expects 2 or 3 arguments (str, start [, length]), got 4 +# Wrong argument types +mysqltest: At line 1: substr() first argument must be a string +mysqltest: At line 1: substr() start position must be numeric +mysqltest: At line 1: substr() length must be numeric +# Expression evaluation tests completed successfully +# ---------------------------------------------------------------------------- +# Basic INSTR function tests +# ---------------------------------------------------------------------------- +# Basic INSTR function tests +instr("hello world", "world") -> 7 +instr("hello world", "hello") -> 1 +instr("hello world", "o") -> 5 +instr("hello world", "xyz") -> 0 +instr("hello world", "") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with single characters +# ---------------------------------------------------------------------------- +# INSTR with single characters +instr("hello", "h") -> 1 +instr("hello", "e") -> 2 +instr("hello", "l") -> 3 +instr("hello", "o") -> 5 +instr("hello", "x") -> 0 +# ---------------------------------------------------------------------------- +# INSTR with repeated characters +# ---------------------------------------------------------------------------- +# INSTR with repeated characters +instr("hello", "l") -> 3 +instr("hello hello", "hello") -> 1 +instr("aaa", "aa") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with empty strings +# ---------------------------------------------------------------------------- +# INSTR with empty strings +instr("", "hello") -> 0 +instr("hello", "") -> 1 +instr("", "") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with special characters +# ---------------------------------------------------------------------------- +# INSTR with special characters +instr("a+b=c", "+") -> 2 +instr("test\nstring", "\n") -> 5 +instr("quoted 'string'", "'") -> 8 +instr('quoted "string"', '"') -> 8 +instr("test@example.com", "@") -> 5 +# ---------------------------------------------------------------------------- +# INSTR with variables +# ---------------------------------------------------------------------------- +# INSTR with variables +instr("hello world", "world") -> 7 +instr("hello world", "o") -> 5 +# ---------------------------------------------------------------------------- +# INSTR edge cases +# ---------------------------------------------------------------------------- +# INSTR edge cases +instr("hello", "hello") -> 1 +instr("hello", "hellox") -> 0 +instr("hello", "h") -> 1 +instr("hello", "o") -> 5 +instr("a", "a") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with case sensitivity +# ---------------------------------------------------------------------------- +# INSTR with case sensitivity +instr("Hello World", "hello") -> 1 +instr("Hello World", "HELLO") -> 1 +# ---------------------------------------------------------------------------- +# INSTR with whitespace +# ---------------------------------------------------------------------------- +# INSTR with whitespace +instr("hello world", " ") -> 6 +instr(" hello ", "hello") -> 3 +instr("hello world", " ") -> 6 +instr("hello\tworld", "\t") -> 6 +# ---------------------------------------------------------------------------- +# INSTR with complex expressions +# ---------------------------------------------------------------------------- +# INSTR with complex expressions +instr("hello world", substr("world test", 1, 5)) -> 7 +instr(replace("hello world", "world", "mariadb"), "mariadb") -> 7 +# ---------------------------------------------------------------------------- +# INSTR with arithmetic expressions +# ---------------------------------------------------------------------------- +# INSTR with arithmetic expressions +instr("hello world", "world") + 5 -> 12 +instr("hello world", "hello") * 2 -> 2 +# ---------------------------------------------------------------------------- +# INSTR with logical operators +# ---------------------------------------------------------------------------- +# INSTR with logical operators +instr("hello world", "hello") > 0 && instr("hello world", "world") > 0 -> 1 +instr("hello world", "hello") > 0 || instr("hello world", "xyz") > 0 -> 1 +# ---------------------------------------------------------------------------- +# INSTR integration with other functions +# ---------------------------------------------------------------------------- +# INSTR integration with other functions +instr("hello world", substr("world test", 1, 5)) -> 7 +instr(replace("hello world", "world", "mariadb"), "mariadb") -> 7 +# ---------------------------------------------------------------------------- +# INSTR error cases +# ---------------------------------------------------------------------------- +# Testing error cases for INSTR function +# Wrong number of arguments +mysqltest: At line 1: instr() expects 2 arguments (str, substr), got 1 +mysqltest: The test didn't produce any output +# Wrong argument types +mysqltest: The test didn't produce any output +mysqltest: The test didn't produce any output +# ---------------------------------------------------------------------------- +# Test LOCATE function +# ---------------------------------------------------------------------------- +# LOCATE function tests +locate('world', 'hello world') -> 7 +locate('o', 'hello world') -> 5 +locate('o', 'hello world', 6) -> 8 +locate('xyz', 'hello world') -> 0 +locate('', 'hello world') -> 1 +locate('hello', '') -> 0 +locate('', '') -> 1 +locate('l', 'hello world', 1) -> 3 +locate('l', 'hello world', 4) -> 4 +locate('l', 'hello world', 10) -> 10 +# ---------------------------------------------------------------------------- +# LOCATE with empty strings +# ---------------------------------------------------------------------------- +# LOCATE with empty strings +locate('', 'hello world') -> 1 +locate('hello', '') -> 0 +locate('', '') -> 1 +# ---------------------------------------------------------------------------- +# LOCATE with special characters +# ---------------------------------------------------------------------------- +# LOCATE with special characters +locate('+', 'a+b=c') -> 2 +locate('@', 'test@example.com') -> 5 +locate('.', 'file.txt') -> 5 +# ---------------------------------------------------------------------------- +# LOCATE with variables +# ---------------------------------------------------------------------------- +# LOCATE with variables +locate("world", "hello world") -> 7 +locate('o', "hello world", 6) -> 8 +# ---------------------------------------------------------------------------- +# LOCATE edge cases +# ---------------------------------------------------------------------------- +# LOCATE edge cases +locate('hello', 'hello world') -> 1 +locate('world', 'hello world') -> 7 +locate('xyz', 'hello world') -> 0 +locate('o', 'hello world', 1) -> 5 +locate('o', 'hello world', 20) -> 0 +# ---------------------------------------------------------------------------- +# Error cases for LOCATE function +# ---------------------------------------------------------------------------- +# Testing error cases for LOCATE function +# Wrong number of arguments +mysqltest: At line 1: locate() expects 2 or 3 arguments (substr, str [, start]), got 1 +mysqltest: At line 1: locate() expects 2 or 3 arguments (substr, str [, start]), got 4 +# Wrong argument types +mysqltest: The test didn't produce any output +mysqltest: The test didn't produce any output +mysqltest: At line 1: locate() start position must be numeric +# ---------------------------------------------------------------------------- +# Test LOWER function +# ---------------------------------------------------------------------------- +# LOWER function tests +lower('HELLO WORLD') -> hello world +lower('Hello World') -> hello world +lower('hello world') -> hello world +lower('ABC123') -> abc123 +lower('') -> +lower('MIXED Case 123') -> mixed case 123 +lower('SPECIAL@#$%') -> special@#$% +# ---------------------------------------------------------------------------- +# LOWER with empty strings +# ---------------------------------------------------------------------------- +# LOWER with empty strings +lower('') -> +# ---------------------------------------------------------------------------- +# LOWER with special characters +# ---------------------------------------------------------------------------- +# LOWER with special characters +lower('TEST@EXAMPLE.COM') -> test@example.com +lower('FILE.TXT') -> file.txt +lower('HELLO-WORLD_123') -> hello-world_123 +# ---------------------------------------------------------------------------- +# LOWER with variables +# ---------------------------------------------------------------------------- +# LOWER with variables +lower("HELLO WORLD") -> hello world +# ---------------------------------------------------------------------------- +# LOWER edge cases +# ---------------------------------------------------------------------------- +# LOWER edge cases +lower('A') -> a +lower('a') -> a +lower('123') -> 123 +lower('MiXeD cAsE') -> mixed case +# ---------------------------------------------------------------------------- +# Test UPPER function +# ---------------------------------------------------------------------------- +# UPPER function tests +upper('hello world') -> HELLO WORLD +upper('Hello World') -> HELLO WORLD +upper('HELLO WORLD') -> HELLO WORLD +upper('abc123') -> ABC123 +upper('') -> +upper('mixed case 123') -> MIXED CASE 123 +upper('special@#$%') -> SPECIAL@#$% +# ---------------------------------------------------------------------------- +# UPPER with empty strings +# ---------------------------------------------------------------------------- +# UPPER with empty strings +upper('') -> +# ---------------------------------------------------------------------------- +# UPPER with special characters +# ---------------------------------------------------------------------------- +# UPPER with special characters +upper('test@example.com') -> TEST@EXAMPLE.COM +upper('file.txt') -> FILE.TXT +upper('hello-world_123') -> HELLO-WORLD_123 +# ---------------------------------------------------------------------------- +# UPPER with variables +# ---------------------------------------------------------------------------- +# UPPER with variables +upper("hello world") -> HELLO WORLD +# ---------------------------------------------------------------------------- +# UPPER edge cases +# ---------------------------------------------------------------------------- +# UPPER edge cases +upper('a') -> A +upper('A') -> A +upper('123') -> 123 +upper('MiXeD cAsE') -> MIXED CASE +# ---------------------------------------------------------------------------- +# Test REVERSE function +# ---------------------------------------------------------------------------- +# REVERSE function tests +reverse('hello') -> olleh +reverse('hello world') -> dlrow olleh +reverse('12345') -> 54321 +reverse('') -> +reverse('a') -> a +reverse('ab') -> ba +reverse('ABC123') -> 321CBA +# ---------------------------------------------------------------------------- +# Test TRIM function +# ---------------------------------------------------------------------------- +# TRIM function tests +trim(' hello world ') -> hello world +trim('hello world') -> hello world +trim(' ') -> +trim('') -> +trim(' hello') -> hello +trim('hello ') -> hello +trim(' hello world ') -> hello world +# ---------------------------------------------------------------------------- +# Test LTRIM function +# ---------------------------------------------------------------------------- +# LTRIM function tests +ltrim(' hello world') -> hello world +ltrim('hello world') -> hello world +ltrim(' ') -> +ltrim('') -> +ltrim(' hello world') -> hello world +ltrim('hello world') -> hello world +ltrim(' hello') -> hello +# ---------------------------------------------------------------------------- +# Test RTRIM function +# ---------------------------------------------------------------------------- +# RTRIM function tests +rtrim('hello world ') -> hello world +rtrim('hello world') -> hello world +rtrim(' ') -> +rtrim('') -> +rtrim(' hello world ') -> hello world +rtrim('hello world') -> hello world +rtrim('hello ') -> hello +# ---------------------------------------------------------------------------- +# Test LPAD function +# ---------------------------------------------------------------------------- +# LPAD function tests +lpad('hello', 10, '*') -> *****hello +lpad('hello', 5, '*') -> hello +lpad('hello', 3, '*') -> hel +lpad('hello', 10, ' ') -> hello +lpad('', 5, '*') -> ***** +lpad('hello', 10, 'ab') -> ababahello +lpad('hello', 0, '*') -> +# ---------------------------------------------------------------------------- +# Test RPAD function +# ---------------------------------------------------------------------------- +# RPAD function tests +rpad('hello', 10, '*') -> hello***** +rpad('hello', 5, '*') -> hello +rpad('hello', 3, '*') -> hel +rpad('hello', 10, ' ') -> hello +rpad('', 5, '*') -> ***** +rpad('hello', 10, 'ab') -> helloababa +rpad('hello', 0, '*') -> +# ---------------------------------------------------------------------------- +# Test LENGTH function +# ---------------------------------------------------------------------------- +# LENGTH function tests +length('hello') -> 5 +length('hello world') -> 11 +length('') -> 0 +length('12345') -> 5 +length(' hello ') -> 9 +length('a') -> 1 +length('special@#$%') -> 11 +# ---------------------------------------------------------------------------- +# Test special characters and Latin characters +# ---------------------------------------------------------------------------- +# Special characters and Latin characters tests +length('Björn') -> 6 +upper('björn') -> BJöRN +lower('BJÖRN') -> bjrn +reverse('Björn') -> nrjB +locate('ö', 'Björn') -> 3 +substr('Björn', 1, 3) -> Bj +trim(' Björn ') -> Björn +concat('Björn', ' ', 'Müller') -> Björn Müller +replace('Björn Müller', 'Müller', 'Schmidt') -> Björn Schmidt +instr('Björn Müller', 'Müller') -> 8 +lpad('Björn', 10, '*') -> ****Björn +rpad('Björn', 10, '*') -> Björn**** +length('Khåled Rïyad') -> 14 +upper('josé maría') -> JOSé MARíA +substr('José María', 1, 4) -> Jos +# ---------------------------------------------------------------------------- +# Test special characters and symbols +# ---------------------------------------------------------------------------- +# Special characters and symbols tests +concat('path', '/', 'to', '/', 'file.txt') -> path/to/file.txt +instr('user@domain.com', 'domain.com') -> 6 +length('path/to/file.txt') -> 16 +locate('.', 'file.txt') -> 5 +locate('/', 'path/to/file.txt') -> 5 +upper('test@example.com') -> TEST@EXAMPLE.COM +lower('TEST@EXAMPLE.COM') -> test@example.com +lpad('file', 8, '.') -> ....file +rpad('path', 10, '/') -> path////// +replace('file.txt', 'txt', 'doc') -> file.doc +replace('path/to/file.txt', 'file.txt', 'document.doc') -> path/to/document.doc +reverse('path/to/file.txt') -> txt.elif/ot/htap +substr('path/to/file.txt', 1, 4) -> path +trim(' path/to/file.txt ') -> path/to/file.txt +# ---------------------------------------------------------------------------- +# Test complex combinations of string functions +# ---------------------------------------------------------------------------- +# Complex string function combinations +length(trim(' hello world ')) -> 11 +upper(lower('MiXeD CaSe')) -> MIXED CASE +reverse(lpad('hi', 5, '*')) -> ih*** +locate('o', upper('hello world')) -> 5 +substr(trim(' hello world '), 1, 5) -> hello +length(concat('hello', ' ', 'world')) -> 11 +reverse(upper('hello')) -> OLLEH +lpad(rtrim('hello '), 10, '*') -> *****hello +least(length('hello'), length('world'), length('test')) -> 4 +greatest(instr('hello world', 'h'), instr('hello world', 'w'), instr('hello world', 'o')) -> 7 +repeat(upper(substr('hello', 1, 2)), 3) -> HEHEHE +insert(lower('HELLO WORLD'), 7, 5, upper('mariadb')) -> hello MARIADB +concat_ws('-', upper('hello'), lower('WORLD'), reverse('test')) -> HELLO-world-tset +ifnull(nullif(trim(' hello '), 'hello'), 'default') -> default +coalesce(nullif('test', 'test'), upper('backup')) -> BACKUP +substring_index(concat('www', '.', 'mariadb', '.', 'org'), '.', 2) -> www.mariadb +# ---------------------------------------------------------------------------- +# Test CONCAT function +# ---------------------------------------------------------------------------- +# Basic CONCAT function tests +concat('a','b','c') -> abc +concat(42, 'a') -> 42a +concat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '1', 'a') -> 123456789101a +concat('') -> +concat('å', 'ñ', 'ç', 'ü', 'é', 'ö', 'ß', 'æ', 'ø', 'î', 'ë', 'ä', 'ï', 'ô', 'à', 'ù', 'ê', 'â', 'ý', 'þ', 'ð', 'ł', 'ś', 'ż', 'ź', 'ć') -> åñçüéößæøîëäïôàùêâýþðłśżźć +concat('', 1) -> 1 +# ---------------------------------------------------------------------------- +# Test SUBSTRING_INDEX function +# ---------------------------------------------------------------------------- +# SUBSTRING_INDEX function tests +substring_index('www.mariadb.org', '.', 2) -> www.mariadb +substring_index('www.mariadb.org', '.', -2) -> mariadb.org +substring_index('www.mariadb.org', '.', 0) -> +substring_index('www.mariadb.org', '', 1) -> +substring_index('www.mariadb.org', '', -1) -> +substring_index('mariadb', '.', 0) -> +substring_index('mariadb', '.', -1) -> mariadb +substring_index('mariadb', '.', 1) -> mariadb +substring_index('mariadb', 'A', 1) -> mariadb +substring_index('mariadb', 'A', -1) -> mariadb +substring_index('mariadb', 'A', 0) -> +substring_index('mariadb', 'z', 2) -> mariadb +substring_index('', 'z', -2) -> +substring_index('mariadb', 'ar', 0) -> +# ---------------------------------------------------------------------------- +# Test REGEXP_INSTR function +# ---------------------------------------------------------------------------- +# REGEXP_INSTR function tests +regexp_instr('abc','b') -> 2 +regexp_instr('abc','x') -> 0 +regexp_instr('abc','') -> 1 +regexp_instr('','a') -> 0 +regexp_instr('','') -> 1 +regexp_instr('BJÖRN','N') -> 6 +regexp_instr('ABC','(?-i)b') -> 0 +regexp_instr('ABC','(?i)b') -> 2 +# ---------------------------------------------------------------------------- +# Test REGEXP_SUBSTR function +# ---------------------------------------------------------------------------- +# REGEXP_SUBSTR function tests +regexp_substr('ab12cd','[0-9]+') -> 12 +regexp_substr('ab12cd','') -> +regexp_substr('abcd','[0-9]+') -> +regexp_substr('','[0-9]+') -> +regexp_substr('','') -> +regexp_substr('See https://mariadb.org/en/foundation/ for details','https?://[^/]*') -> https://mariadb.org +regexp_substr('ABC','b') -> B +regexp_substr('ABC','(?i)b') -> B +# ---------------------------------------------------------------------------- +# Test REGEXP_REPLACE function +# ---------------------------------------------------------------------------- +# REGEXP_REPLACE function tests +regexp_replace('ABC','b','x') -> AxC +regexp_replace('ab12cd','[0-9]','') -> abcd +regexp_replace('titlebody', '<.+?>',' ') -> title body +regexp_replace('James Bond','^(.*) (.*)$','\2, \1') -> Bond, James +regexp_replace('ABC','b','-') -> A-C +regexp_replace('ABC','(?-i)b','-') -> ABC +regexp_replace('ABC','(?i)b','-') -> A-C +regexp_replace('ABC','b','') -> AC +regexp_replace('ABC','(?-i)b','') -> ABC +regexp_replace('ABC','','') -> ABC +regexp_replace('ABC','','A') -> ABC +regexp_replace('','.','x') -> +regexp_replace('ABC','b','$') -> A$C +regexp_replace('ABC','b','$A') -> A$AC +regexp_replace('ABCC','C$','D') -> ABCD +regexp_replace('ABC$','\$','D') -> ABCD +# ---------------------------------------------------------------------------- +# Test LEAST function +# ---------------------------------------------------------------------------- +# LEAST function tests +least(1, 2, 3) -> 1 +least('a', 'b', 'c') -> a +least(NULL, 1, 2) -> +least(NULL, NULL, NULL) -> +least('a', 1, 'b') -> 0 +least(1, 'a', 'b') -> 0 +least('z', '-2', 'a') -> -2 +least('z', -2, 'a') -> -2 +least(' -4a', -1, 'b') -> -4 +least(' ', 10, 'b') -> 0 +least(' -0 ', 10, 'b') -> 0 +least('', 10, '-b') -> 0 +least(18446744073709551615, 18446744073709551614, 18446744073709551613) -> 18446744073709551613 +least(18446744073709551615, -1, 18446744073709551613) -> -1 +# ---------------------------------------------------------------------------- +# Test GREATEST function +# ---------------------------------------------------------------------------- +# GREATEST function tests +greatest(1, 2, 3) -> 3 +greatest('a', 'b', 'c') -> c +greatest(NULL, 1, 2) -> +greatest(NULL, NULL, NULL) -> +greatest('a', 1, 'b') -> 1 +greatest(1, 'a', 'b') -> 1 +greatest('z', '-2', 'a') -> z +greatest('z', -2, 'a') -> 0 +greatest(' -4a', -1, 'b') -> 0 +greatest(' ', 10, 'b') -> 10 +greatest(' -0 ', 10, 'b') -> 10 +greatest('', 10, '-b') -> 10 +greatest(18446744073709551615, 18446744073709551614, 18446744073709551613) -> 18446744073709551615 +greatest(18446744073709551615, -1, 18446744073709551613) -> 18446744073709551615 +greatest(3.14, 2.71, 3.15) -> 3.15 +greatest(-10, -5, -20) -> -5 +greatest('apple', 'banana', 'cherry') -> cherry +greatest('100', '20', '3') -> 3 +# ---------------------------------------------------------------------------- +# Test REPEAT function +# ---------------------------------------------------------------------------- +# REPEAT function tests +repeat('MariaDB ',4) -> MariaDB MariaDB MariaDB MariaDB +repeat('a', 0) -> +repeat('a', 1) -> a +repeat('', 0) -> +repeat('a', -1) -> +repeat('a', 18446744073709551615) -> +repeat('', 4) -> +repeat('', -1) -> +repeat('a32423413', 10) -> a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413a32423413 +# ---------------------------------------------------------------------------- +# Test NULLIF function +# ---------------------------------------------------------------------------- +# NULLIF function tests +nullif('a', 'a') -> +nullif('a', 'b') -> a +nullif('a', NULL) -> a +nullif(NULL, 'a') -> +nullif(NULL, NULL) -> +# ---------------------------------------------------------------------------- +# Test COALESCE function +# ---------------------------------------------------------------------------- +# COALESCE function tests +coalesce(NULL, 'a') -> a +coalesce(NULL, NULL) -> +coalesce(NULL, 'a', 'b') -> a +coalesce('a', 'b', 'c') -> a +coalesce('a', NULL, 'b') -> a +coalesce(NULL, NULL, 'a') -> a +coalesce(NULL, NULL, NULL) -> +coalesce(NULL, 'a', NULL, 'b') -> a +# ---------------------------------------------------------------------------- +# Test IFNULL function +# ---------------------------------------------------------------------------- +# IFNULL function tests +ifnull(NULL, 'a') -> a +ifnull('a', NULL) -> a +ifnull(NULL, NULL) -> +ifnull('a', 'b') -> a +ifnull('a', 'a') -> a +# ---------------------------------------------------------------------------- +# Test INSERT function +# ---------------------------------------------------------------------------- +# INSERT function tests +insert('Hello World', 2, 3, 'Xyz') -> HXyzo World +insert('Hello World', 2, 3, '') -> Ho World +insert('Hello World', 2, 3, NULL) -> +insert('Hello World', 0, 0, 'Xyz') -> Hello World +insert('Hello World', 0, 0, '') -> Hello World +insert('Quadratic', 3, 4, 'What') -> QuWhattic +insert('Quadratic', -1, 4, 'What') -> Quadratic +insert('Quadratic', 3, 100, 'What') -> QuWhat +insert('Quadratic', -32, -100, 'wow') -> Quadratic +insert('Quadratic', 32, 100, 'wow') -> Quadratic +insert('Quadratic', 1, 8, 'wow') -> wowc +insert('Quadratic', 1, 1000, 'wow') -> wow +insert('Quadratic', 4, 2, 'wow') -> Quawowatic +insert('Quadratic', 4, 2, '') -> Quaatic +insert('', 4, 2, 'wow') -> +insert('Quadratic', 4, -2, 'wow') -> Quawow +insert('Quadratic', 4, 0, 'wow') -> Quawowdratic +# ---------------------------------------------------------------------------- +# Test CONCAT_WS function +# ---------------------------------------------------------------------------- +# CONCAT_WS function tests +concat_ws('-', 'a', 'b', 'c') -> a-b-c +concat_ws('#', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z') -> a#b#c#d#e#f#g#h#i#j#k#l#m#n#o#p#q#r#s#t#u#v#w#x#y#z +concat_ws(' ,', 'a') -> a +concat_ws('', 'abc', 'def', 'ghi') -> abcdefghi +concat_ws('', 'abc') -> abc +concat_ws('&', 'abc') -> abc +concat_ws(' ,', '') -> +concat_ws('&', 'abc', NULL) -> abc +concat_ws('...', 'abc', NULL, 'def') -> abc...def +concat_ws(NULL, 'abc', NULL, 'def') -> +# ---------------------------------------------------------------------------- +# Test functions with variables +# ---------------------------------------------------------------------------- +# Functions with variables +least('test string', 'string') -> string +greatest('test string', 'string') -> test string +repeat('string', 3) -> stringstringstring +insert('test string', 5, 6, 'value') -> testvalueg +concat_ws(' ', 'test string', 'string', 'value') -> test string string value +ifnull(NULL, 'value') -> value +coalesce(NULL, NULL, 'value') -> value +nullif('test string', 'string') -> test string +# ---------------------------------------------------------------------------- +# Test functions with special characters +# ---------------------------------------------------------------------------- +# Functions with special characters +least('Björn', 'Müller', 'Schmidt') -> Björn +greatest('Björn', 'Müller', 'Schmidt') -> Schmidt +repeat('ö', 5) -> ööööö +insert('Björn Müller', 7, 6, 'Schmidt') -> BjörnSchmidter +concat_ws(' ', 'José', 'María', 'González') -> José María González +ifnull(NULL, 'François') -> François +coalesce(NULL, 'Håkon', 'Olsen') -> Håkon +nullif('test@example.com', 'user@domain.com') -> test@example.com +# ---------------------------------------------------------------------------- +# Test functions with mixed data types +# ---------------------------------------------------------------------------- +# Functions with mixed data types +least(123, 'abc', 456) -> 0 +greatest(123, 'abc', 456) -> 456 +repeat('test', 3) -> testtesttest +insert('test123', 5, 3, 'ABC') -> testABC +concat_ws('-', 'prefix', 123, 'suffix') -> prefix-123-suffix +ifnull(123, 'fallback') -> 123 +coalesce(NULL, 456, 'backup') -> 456 +nullif(123, 456) -> 123 +# ---------------------------------------------------------------------------- +# Test functions in complex expressions +# ---------------------------------------------------------------------------- +# Functions in complex expressions +least(1, 2, 3) + 10 -> 11 +greatest(1, 2, 3) * 5 -> 15 +length(repeat('ab', 4)) -> 8 +upper(insert('hello world', 7, 5, 'mariadb')) -> HELLO MARIADB +length(concat_ws(' ', 'hello', 'world', 'test')) -> 16 +ifnull(NULL, 'default') == 'default' -> 1 +coalesce(NULL, NULL, 'found') != 'missing' -> 1 +nullif('same', 'same') -> +# ---------------------------------------------------------------------------- +# Test functions in conditional expressions +# ---------------------------------------------------------------------------- +# Functions in conditional expressions +least returns minimum value correctly +greatest returns maximum value correctly +repeat with count 0 returns empty string +CONCAT_WS joins with separator correctly +ifnull returns first value when not NULL +coalesce returns first non-NULL value +nullif returns first value when values differ +# ---------------------------------------------------------------------------- +# Test functions with arithmetic in arguments +# ---------------------------------------------------------------------------- +# Functions with arithmetic in arguments +least(1+2, 2*2, 3+1) -> 3 +greatest(1+2, 2*2, 3+1) -> 4 +repeat('x', 2+3) -> xxxxx +insert('hello', 1+1, 2*1, 'hi') -> hhilo +insert('testing', 2, 3, 'xyz') -> txyzing +# ---------------------------------------------------------------------------- +# Test nested function calls +# ---------------------------------------------------------------------------- +# Nested function calls +least(length('hello'), length('world'), length('test')) -> 4 +greatest(length('hello'), length('world'), length('test')) -> 5 +repeat(upper('ab'), 3) -> ABABAB +insert(upper('hello world'), 7, 5, lower('MARIADB')) -> HELLO mariadb +concat_ws(' ', upper('hello'), lower('WORLD')) -> HELLO world +ifnull(nullif('same', 'same'), 'default') -> default +coalesce(nullif('test', 'test'), 'backup') -> backup +# Expression evaluation string functions tests completed successfully diff --git a/mysql-test/main/mysqltest_string_functions.test b/mysql-test/main/mysqltest_string_functions.test new file mode 100644 index 0000000000000..9115e46923d56 --- /dev/null +++ b/mysql-test/main/mysqltest_string_functions.test @@ -0,0 +1,2058 @@ +--echo # ---------------------------------------------------------------------------- +--echo # Test for MDEV-36108: Variable substitutions in mysqltest +--echo # ---------------------------------------------------------------------------- + +--source include/not_embedded.inc + +--echo # ---------------------------------------------------------------------------- +--echo # Test conversion functions (conv, bin, oct, hex) +--echo # ---------------------------------------------------------------------------- + +--echo # Basic conv() function tests + +let $result1 = $(conv(10, 10, 2)); +--echo conv(10, 10, 2) -> $result1 + +let $result2 = $(conv(255, 10, 16)); +--echo conv(255, 10, 16) -> $result2 + +let $result3 = $(conv(FF, 16, 10)); +--echo conv(FF, 16, 10) -> $result3 + +let $result4 = $(conv(1010, 2, 10)); +--echo conv(1010, 2, 10) -> $result4 + +let $result5 = $(conv(64, 10, 8)); +--echo conv(64, 10, 8) -> $result5 + +let $result6 = $(conv(77, 8, 10)); +--echo conv(77, 8, 10) -> $result6 + +--echo # ---------------------------------------------------------------------------- +--echo # Test shortcut functions bin(), oct(), hex() +--echo # ---------------------------------------------------------------------------- + +--echo # Testing bin() function + +let $bin1 = $(bin(10)); +--echo bin(10) -> $bin1 + +let $bin2 = $(bin(255)); +--echo bin(255) -> $bin2 + +let $bin3 = $(bin(0)); +--echo bin(0) -> $bin3 + +--echo # Testing oct() function + +let $oct1 = $(oct(64)); +--echo oct(64) -> $oct1 + +let $oct2 = $(oct(512)); +--echo oct(512) -> $oct2 + +--echo # Testing hex() function + +let $hex1 = $(hex(255)); +--echo hex(255) -> $hex1 + +let $hex2 = $(hex(4095)); +--echo hex(4095) -> $hex2 + +--echo # ---------------------------------------------------------------------------- +--echo # Test extended base support (bases 2-62) +--echo # ---------------------------------------------------------------------------- + +--echo # Testing extended bases + +let $base36 = $(conv(ZZ, 36, 10)); +--echo conv(ZZ, 36, 10) -> $base36 + +# uncomment in 11.4 +#let $base62_1 = $(conv(z, 62, 10)); +#--echo conv(z, 62, 10) -> $base62_1 +#conv(z, 62, 10) -> 61 +#let $base62_2 = $(conv(Hello, 62, 10)); +#--echo conv(Hello, 62, 10) -> $base62_2 +#conv(Hello, 62, 10) -> 260914464 + +--echo # ---------------------------------------------------------------------------- +--echo # Test signed vs unsigned interpretation +--echo # ---------------------------------------------------------------------------- + +--echo # Testing signed vs unsigned interpretation + +let $unsigned1 = $(conv(-1, 10, 16)); +--echo conv(-1, 10, 16) -> $unsigned1 + +let $signed1 = $(conv(-1, 10, -16)); +--echo conv(-1, 10, -16) -> $signed1 + +let $unsigned2 = $(conv(-10, 10, 2)); +--echo conv(-10, 10, 2) -> $unsigned2 + +let $signed2 = $(conv(-10, 10, -2)); +--echo conv(-10, 10, -2) -> $signed2 + +let $unsigned3 = $(conv(-255, 10, 16)); +--echo conv(-255, 10, 16) -> $unsigned3 + +let $signed3 = $(conv(-255, 10, -16)); +--echo conv(-255, 10, -16) -> $signed3 + +let $signed4 = $(conv(-1234, -10, 2)); +--echo conv(-1234, -10, 2) -> $signed4 + +let $signed5 = $(conv(-1234, -10, -2)); +--echo conv(-1234, -10, -2) -> $signed5 + +--echo # ---------------------------------------------------------------------------- +--echo # Edge cases and boundary conditions +--echo # ---------------------------------------------------------------------------- + +--echo # Testing edge cases and boundaries + +let $zero1 = $(conv(0, 10, 2)); +--echo conv(0, 10, 2) -> $zero1 + +let $zero2 = $(conv(0, 16, 10)); +--echo conv(0, 16, 10) -> $zero2 + +let $max1 = $(conv(9223372036854775807, 10, 16)); +--echo conv(9223372036854775807, 10, 16) -> $max1 + +let $max2 = $(conv(~0, 10, 2)); +--echo conv(~0, 10, 2) -> $max2 + +let $large1 = $(conv(7FFFFFFFFFFFFFFF, 16, 10)); +--echo conv(7FFFFFFFFFFFFFFF, 16, 10) -> $large1 + +let $large2 = $(conv('777777777777777777777', 8, 10)); +--echo conv(777777777777777777777, 8, 10) -> $large2 + +let $large3 = $(conv('1111111111111111111111111111111111111111111111111111111111111111', 2, 10)); +--echo conv(1111111111111111111111111111111111111111111111111111111111111111, 2, 10) -> $large3 + +let $large4 = $(conv('9223372036854775807', 10, 2)); +--echo conv(9223372036854775807, 10, 2) -> $large4 + +let $large5 = $(conv('18446744073709551615', 10, 16)); +--echo conv(18446744073709551615, 10, 16) -> $large5 + +let $large6 = $(conv('18446744073709551615', 10, 2)); +--echo conv(18446744073709551615, 10, 2) -> $large6 + +let $min1 = $(conv(-~0, 10, 2)); +--echo conv(-~0, 10, 2) -> $min1 + +let $leading1 = $(conv(0000123, 10, 16)); +--echo conv(0000123, 10, 16) -> $leading1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test case sensitivity in conversion +--echo # ---------------------------------------------------------------------------- + +--echo # Testing case sensitivity + +let $case1 = $(conv(AbCd, 16, 10)); +--echo conv(AbCd, 16, 10) -> $case1 + +let $case2 = $(conv(abcd, 16, 10)); +--echo conv(abcd, 16, 10) -> $case2 + +let $case3 = $(conv(ABCD, 16, 10)); +--echo conv(ABCD, 16, 10) -> $case3 + +--echo # ---------------------------------------------------------------------------- +--echo # Test with variables and expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Testing with variables and expressions + +let $base_var = 16; +let $value_var = FF; +let $target_base = 10; + +let $var_result = $(conv($value_var, $base_var, $target_base)); +--echo conv($value_var, $base_var, $target_base) -> $var_result + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases - Invalid bases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases - Invalid bases + +--echo # Base too small (< 2) +--error 1 +--exec echo "let \$invalid1= \$(conv(123, 1, 10));" | $MYSQL_TEST 2>&1 + +--echo # Base too large (> 62 for our parser, > 36 for MariaDB) +--error 1 +--exec echo "let \$invalid2= \$(conv(123, 63, 10));" | $MYSQL_TEST 2>&1 + +--echo # Zero base +--error 1 +--exec echo "let \$invalid3= \$(conv(123, 0, 10));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases - Invalid characters for base +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases - Invalid characters + +--echo # Character not valid for base 8 +--error 1 +--exec echo "let \$invalid5= \$(conv(189, 8, 10));" | $MYSQL_TEST 2>&1 + +--echo # Character not valid for base 16 +--error 1 +--exec echo "let \$invalid6= \$(conv(XYZ, 16, 10));" | $MYSQL_TEST 2>&1 + +--echo # Special characters +--error 1 +--exec echo "let \$invalid7= \$(conv(@#\\\$, 36, 10));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases - Function argument count +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases - Wrong argument count + +--echo # Too few arguments for conv +--error 1 +--exec echo "let \$invalid8= \$(conv(123, 10));" | $MYSQL_TEST 2>&1 + +--echo # Too many arguments for conv +--error 1 +--exec echo "let \$invalid9= \$(conv(123, 10, 16, 2));" | $MYSQL_TEST 2>&1 + +--echo # Too many arguments for bin +--error 1 +--exec echo "let \$invalid10= \$(bin(123, 456));" | $MYSQL_TEST 2>&1 + +--echo # No arguments for hex +--error 1 +--exec echo "let \$invalid11= \$(hex());" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Overflow cases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing overflow cases + +--echo # Number too large for 64-bit +--error 1 +--exec echo "let \$overflow1= \$(conv(99999999999999999999999999999999, 10, 16));" | $MYSQL_TEST 2>&1 + +--echo # Very long hex string that would cause overflow +--error 1 +--exec echo "let \$overflow2= \$(conv(FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, 16, 10));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REPLACE function +--echo # ---------------------------------------------------------------------------- + +--echo # Basic REPLACE function tests + +let $replace1 = $(replace("hello world", "world", "mariadb")); +--echo replace("hello world", "world", "mariadb") -> "$replace1" + +let $replace2 = $(replace("hello hello hello", "hello", "hi")); +--echo replace("hello hello hello", "hello", "hi") -> "$replace2" + +let $replace3 = $(replace("test string", "test", "")); +--echo replace("test string", "test", "") -> "$replace3" + +let $replace4 = $(replace("no change", "missing", "replacement")); +--echo replace("no change", "missing", "replacement") -> "$replace4" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE with empty strings + +let $empty1 = $(replace("hello world", "", "test")); +--echo replace("hello world", "", "test") -> "$empty1" + +let $empty2 = $(replace("hello world", "hello", "")); +--echo replace("hello world", "hello", "") -> "$empty2" + +let $empty3 = $(replace("", "test", "replacement")); +--echo replace("", "test", "replacement") -> "$empty3" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE with special characters + +let $special1 = $(replace("a+b=c", "+", "-")); +--echo replace("a+b=c", "+", "-") -> "$special1" + +let $special2 = $(replace("test\\nstring", "\\n", " ")); +--echo replace("test\\nstring", "\\n", " ") -> "$special2" + +let $special3 = $(replace("quoted 'string'", "'", "")); +--echo replace("quoted 'string'", "'", "") -> "$special3" + +let $special4 = $(replace('quoted "string"', '"', "")); +--echo replace('quoted "string"', '"', "") -> "$special4" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE with variables +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE with variables + +let $text = "hello world"; +let $search = "world"; +let $replacement = "mariadb"; +let $var_result = $(replace($text, $search, $replacement)); +--echo replace($text, $search, $replacement) -> "$var_result" + +let $multi_var = $(replace("test test test", "test", $replacement)); +--echo replace("test test test", "test", $replacement) -> "$multi_var" + +--echo # ---------------------------------------------------------------------------- +--echo # REPLACE edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # REPLACE edge cases + +let $edge1 = $(replace("aaa", "aa", "b")); +--echo replace("aaa", "aa", "b") -> "$edge1" + +let $edge2 = $(replace("aaaa", "aa", "b")); +--echo replace("aaaa", "aa", "b") -> "$edge2" + +let $edge3 = $(replace("test", "test", "test")); +--echo replace("test", "test", "test") -> "$edge3" + +let $edge4 = $(replace("", "", "something")); +--echo replace("", "", "something") -> "$edge4" + +--echo # ---------------------------------------------------------------------------- +--echo # Test SUBSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR function + +let $str = "hello"; + +let $from = -7; +while ($from <= 7) +{ + let $to = -7; + while ($to <= 7) + { + let $result = $(substr($str, $from, $to)); + --echo substr("hello", $from, $to) -> "$result" + --inc $to + } + --inc $from +} + +let $substr1 = $(substr("hello world", 1, 5)); +--echo substr("hello world", 1, 5) -> "$substr1" + +let $substr2 = $(substr("hello world", 7)); +--echo substr("hello world", 7) -> "$substr2" + +let $substr3 = $(substr("hello world", 1, 3)); +--echo substr("hello world", 1, 3) -> "$substr3" + +let $substr4 = $(substr("hello world", 7, 5)); +--echo substr("hello world", 7, 5) -> "$substr4" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR with negative indices +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR with negative indices + +let $neg1 = $(substr("hello world", -5)); +--echo substr("hello world", -5) -> "$neg1" + +let $neg2 = $(substr("hello world", -5, 3)); +--echo substr("hello world", -5, 3) -> "$neg2" + +let $neg3 = $(substr("hello world", -10, 5)); +--echo substr("hello world", -10, 5) -> "$neg3" + +let $neg4 = $(substr("hello world", -20)); +--echo substr("hello world", -20) -> "$neg4" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR boundary conditions +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR boundary conditions + +let $bound1 = $(substr("hello world", 1, 0)); +--echo substr("hello world", 1, 0) -> "$bound1" + +let $bound2 = $(substr("hello world", 1, 20)); +--echo substr("hello world", 1, 20) -> "$bound2" + +let $bound3 = $(substr("hello world", 12)); +--echo substr("hello world", 12) -> "$bound3" + +let $bound4 = $(substr("hello world", 0)); +--echo substr("hello world", 0) -> "$bound4" + +let $bound5 = $(substr("hello world", 0, 5)); +--echo substr("hello world", 0, 5) -> "$bound5" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR with variables +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR with variables + +let $text_var = "hello world"; +let $start_var = 7; +let $len_var = 5; +let $var_substr = $(substr($text_var, $start_var, $len_var)); +--echo substr($text_var, $start_var, $len_var) -> "$var_substr" + +let $neg_var = $(substr($text_var, -5)); +--echo substr($text_var, -5) -> "$neg_var" + +--echo # ---------------------------------------------------------------------------- +--echo # SUBSTR edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTR edge cases + +let $edge_substr1 = $(substr("", 1)); +--echo substr("", 1) -> "$edge_substr1" + +let $edge_substr2 = $(substr("a", 1, 5)); +--echo substr("a", 1, 5) -> "$edge_substr2" + +let $edge_substr3 = $(substr("hello", 1, -1)); +--echo substr("hello", 1, -1) -> "$edge_substr3" + +let $edge_substr4 = $(substr("hello", 5, 1)); +--echo substr("hello", 5, 1) -> "$edge_substr4" + +--echo # ---------------------------------------------------------------------------- +--echo # Combined function tests +--echo # ---------------------------------------------------------------------------- + +--echo # Combined function tests + +let $combined1 = $(replace(substr("hello world", 1, 5), "hello", "hi")); +--echo replace(substr("hello world", 1, 5), "hello", "hi") -> "$combined1" + +let $combined2 = $(substr(replace("hello world", "world", "mariadb"), 7)); +--echo substr(replace("hello world", "world", "mariadb"), 7) -> "$combined2" + +let $combined3 = $(replace(substr("test test test", 1, 9), "test", "check")); +--echo replace(substr("test test test", 1, 9), "test", "check") -> "$combined3" + +let $combined4 = $(upper(replace("hello world", "world", "mariadb"))); +--echo upper(replace("hello world", "world", "mariadb")) -> "$combined4" + +let $combined5 = $(length(trim(replace(" hello world ", "world", "mariadb")))); +--echo length(trim(replace(" hello world ", "world", "mariadb"))) -> "$combined5" + +let $combined6 = $(instr(lower("HELLO WORLD"), "world")); +--echo instr(lower("HELLO WORLD"), "world") -> $combined6 + +let $combined7 = $(locate(upper("o"), upper("hello world"))); +--echo locate(upper("o"), upper("hello world")) -> $combined7 + +let $combined8 = $(reverse(substr(upper("hello world"), 1, 5))); +--echo reverse(substr(upper("hello world"), 1, 5)) -> "$combined8" + + +--echo # ---------------------------------------------------------------------------- +--echo # String functions in while loops +--echo # ---------------------------------------------------------------------------- + +--echo # String functions in while loops +let $counter = 1; +let $text_loop = "hello world"; +while ($(substr($text_loop, $counter, 1))) +{ + let $char = $(substr($text_loop, $counter, 1)); + --echo Character at position $counter: $char (upper: $(upper($char)), lower: $(lower($char))) + --inc $counter +} + +--echo # String processing with multiple functions +let $input_text = "HelloWorld"; +let $pos = 1; +let $total_length = $(length($input_text)); +let $processed = ""; +while ($pos <= $total_length) +{ + let $current_char = $(substr($input_text, $pos, 1)); + if ($(instr("AEIOU", upper($current_char)))) + { + let $processed = $(concat($processed, lower($current_char))); + } + if (!$(instr("AEIOU", upper($current_char)))) + { + let $processed = $(concat($processed, upper($current_char))); + } + --inc $pos +} +--echo Original: $input_text -> Processed: $processed + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases for REPLACE function +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for REPLACE function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error1= \$(replace('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error2= \$(replace('hello', 'world'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error3= \$(replace('hello', 'world', 'test', 'extra'));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error4= \$(replace(123, 'world', 'test'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error5= \$(replace('hello', 456, 'test'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error6= \$(replace('hello', 'world', 789));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases for SUBSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for SUBSTR function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error7= \$(substr('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error8= \$(substr('hello', 1, 2, 3));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error9= \$(substr(123, 1, 2));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error10= \$(substr('hello', 'world', 2));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error11= \$(substr('hello', 1, 'world'));" | $MYSQL_TEST 2>&1 + +--echo # Expression evaluation tests completed successfully + +--echo # ---------------------------------------------------------------------------- +--echo # Basic INSTR function tests +--echo # ---------------------------------------------------------------------------- + +--echo # Basic INSTR function tests + +let $instr1 = $(instr("hello world", "world")); +--echo instr("hello world", "world") -> $instr1 + +let $instr2 = $(instr("hello world", "hello")); +--echo instr("hello world", "hello") -> $instr2 + +let $instr3 = $(instr("hello world", "o")); +--echo instr("hello world", "o") -> $instr3 + +let $instr4 = $(instr("hello world", "xyz")); +--echo instr("hello world", "xyz") -> $instr4 + +let $instr5 = $(instr("hello world", "")); +--echo instr("hello world", "") -> $instr5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with single characters +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with single characters +let $instr_char1 = $(instr("hello", "h")); +--echo instr("hello", "h") -> $instr_char1 + +let $instr_char2 = $(instr("hello", "e")); +--echo instr("hello", "e") -> $instr_char2 + +let $instr_char3 = $(instr("hello", "l")); +--echo instr("hello", "l") -> $instr_char3 + +let $instr_char4 = $(instr("hello", "o")); +--echo instr("hello", "o") -> $instr_char4 + +let $instr_char5 = $(instr("hello", "x")); +--echo instr("hello", "x") -> $instr_char5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with repeated characters +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with repeated characters +let $instr_repeat1 = $(instr("hello", "l")); +--echo instr("hello", "l") -> $instr_repeat1 + +let $instr_repeat2 = $(instr("hello hello", "hello")); +--echo instr("hello hello", "hello") -> $instr_repeat2 + +let $instr_repeat3 = $(instr("aaa", "aa")); +--echo instr("aaa", "aa") -> $instr_repeat3 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with empty strings +let $instr_empty1 = $(instr("", "hello")); +--echo instr("", "hello") -> $instr_empty1 + +let $instr_empty2 = $(instr("hello", "")); +--echo instr("hello", "") -> $instr_empty2 + +let $instr_empty3 = $(instr("", "")); +--echo instr("", "") -> $instr_empty3 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with special characters +let $instr_special1 = $(instr("a+b=c", "+")); +--echo instr("a+b=c", "+") -> $instr_special1 + +let $instr_special2 = $(instr("test\\nstring", "\\n")); +--echo instr("test\\nstring", "\\n") -> $instr_special2 + +let $instr_special3 = $(instr("quoted 'string'", "'")); +--echo instr("quoted 'string'", "'") -> $instr_special3 + +let $instr_special4 = $(instr('quoted "string"', '"')); +--echo instr('quoted "string"', '"') -> $instr_special4 + +let $instr_special5 = $(instr("test@example.com", "@")); +--echo instr("test@example.com", "@") -> $instr_special5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with variables +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with variables +let $text = "hello world"; +let $search = "world"; +let $instr_var_result = $(instr($text, $search)); +--echo instr($text, $search) -> $instr_var_result + +let $char_var = "o"; +let $instr_char_result = $(instr($text, $char_var)); +--echo instr($text, $char_var) -> $instr_char_result + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR edge cases +let $instr_edge1 = $(instr("hello", "hello")); +--echo instr("hello", "hello") -> $instr_edge1 + +let $instr_edge2 = $(instr("hello", "hellox")); +--echo instr("hello", "hellox") -> $instr_edge2 + +let $instr_edge3 = $(instr("hello", "h")); +--echo instr("hello", "h") -> $instr_edge3 + +let $instr_edge4 = $(instr("hello", "o")); +--echo instr("hello", "o") -> $instr_edge4 + +let $instr_edge5 = $(instr("a", "a")); +--echo instr("a", "a") -> $instr_edge5 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with case sensitivity +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with case sensitivity +let $case1 = $(instr("Hello World", "hello")); +--echo instr("Hello World", "hello") -> $case1 + +let $case2 = $(instr("Hello World", "HELLO")); +--echo instr("Hello World", "HELLO") -> $case2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with whitespace +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with whitespace +let $space1 = $(instr("hello world", " ")); +--echo instr("hello world", " ") -> $space1 + +let $space2 = $(instr(" hello ", "hello")); +--echo instr(" hello ", "hello") -> $space2 + +let $space3 = $(instr("hello world", " ")); +--echo instr("hello world", " ") -> $space3 + +let $space4 = $(instr("hello\tworld", "\t")); +--echo instr("hello\tworld", "\t") -> $space4 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with complex expressions +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with complex expressions +let $complex1 = $(instr("hello world", substr("world test", 1, 5))); +--echo instr("hello world", substr("world test", 1, 5)) -> $complex1 + +let $complex2 = $(instr(replace("hello world", "world", "mariadb"), "mariadb")); +--echo instr(replace("hello world", "world", "mariadb"), "mariadb") -> $complex2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with arithmetic expressions +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with arithmetic expressions +let $arith1 = $(instr("hello world", "world") + 5); +--echo instr("hello world", "world") + 5 -> $arith1 + +let $arith2 = $(instr("hello world", "hello") * 2); +--echo instr("hello world", "hello") * 2 -> $arith2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR with logical operators +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR with logical operators +let $logical1 = $(instr("hello world", "hello") > 0 && instr("hello world", "world") > 0); +--echo instr("hello world", "hello") > 0 && instr("hello world", "world") > 0 -> $logical1 + +let $logical2 = $(instr("hello world", "hello") > 0 || instr("hello world", "xyz") > 0); +--echo instr("hello world", "hello") > 0 || instr("hello world", "xyz") > 0 -> $logical2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR integration with other functions +--echo # ---------------------------------------------------------------------------- + +--echo # INSTR integration with other functions + +let $instr_complex1 = $(instr("hello world", substr("world test", 1, 5))); +--echo instr("hello world", substr("world test", 1, 5)) -> $instr_complex1 + +let $instr_complex2 = $(instr(replace("hello world", "world", "mariadb"), "mariadb")); +--echo instr(replace("hello world", "world", "mariadb"), "mariadb") -> $instr_complex2 + +--echo # ---------------------------------------------------------------------------- +--echo # INSTR error cases +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for INSTR function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error1= \$(instr('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error2= \$(instr('hello', 'world', 'extra'));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error3= \$(instr(123, 'world'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error4= \$(instr('hello', 456));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LOCATE function +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE function tests +let $loc1 = $(locate('world', 'hello world')); +--echo locate('world', 'hello world') -> $loc1 + +let $loc2 = $(locate('o', 'hello world')); +--echo locate('o', 'hello world') -> $loc2 + +let $loc3 = $(locate('o', 'hello world', 6)); +--echo locate('o', 'hello world', 6) -> $loc3 + +let $loc4 = $(locate('xyz', 'hello world')); +--echo locate('xyz', 'hello world') -> $loc4 + +let $loc5 = $(locate('', 'hello world')); +--echo locate('', 'hello world') -> $loc5 + +let $loc6 = $(locate('hello', '')); +--echo locate('hello', '') -> $loc6 + +let $loc7 = $(locate('', '')); +--echo locate('', '') -> $loc7 + +let $loc8 = $(locate('l', 'hello world', 1)); +--echo locate('l', 'hello world', 1) -> $loc8 + +let $loc9 = $(locate('l', 'hello world', 4)); +--echo locate('l', 'hello world', 4) -> $loc9 + +let $loc10 = $(locate('l', 'hello world', 10)); +--echo locate('l', 'hello world', 10) -> $loc10 + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE with empty strings +let $locate_empty1 = $(locate('', 'hello world')); +--echo locate('', 'hello world') -> $locate_empty1 + +let $locate_empty2 = $(locate('hello', '')); +--echo locate('hello', '') -> $locate_empty2 + +let $locate_empty3 = $(locate('', '')); +--echo locate('', '') -> $locate_empty3 + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE with special characters +let $locate_special1 = $(locate('+', 'a+b=c')); +--echo locate('+', 'a+b=c') -> $locate_special1 + +let $locate_special2 = $(locate('@', 'test@example.com')); +--echo locate('@', 'test@example.com') -> $locate_special2 + +let $locate_special3 = $(locate('.', 'file.txt')); +--echo locate('.', 'file.txt') -> $locate_special3 + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE with variables +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE with variables +let $locate_text = "hello world"; +let $locate_search = "world"; +let $locate_var_result = $(locate($locate_search, $locate_text)); +--echo locate($locate_search, $locate_text) -> $locate_var_result + +let $locate_pos = 6; +let $locate_var_pos = $(locate('o', $locate_text, $locate_pos)); +--echo locate('o', $locate_text, $locate_pos) -> $locate_var_pos + +--echo # ---------------------------------------------------------------------------- +--echo # LOCATE edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # LOCATE edge cases +let $locate_edge1 = $(locate('hello', 'hello world')); +--echo locate('hello', 'hello world') -> $locate_edge1 + +let $locate_edge2 = $(locate('world', 'hello world')); +--echo locate('world', 'hello world') -> $locate_edge2 + +let $locate_edge3 = $(locate('xyz', 'hello world')); +--echo locate('xyz', 'hello world') -> $locate_edge3 + +let $locate_edge4 = $(locate('o', 'hello world', 1)); +--echo locate('o', 'hello world', 1) -> $locate_edge4 + +let $locate_edge5 = $(locate('o', 'hello world', 20)); +--echo locate('o', 'hello world', 20) -> $locate_edge5 + +--echo # ---------------------------------------------------------------------------- +--echo # Error cases for LOCATE function +--echo # ---------------------------------------------------------------------------- + +--echo # Testing error cases for LOCATE function + +--echo # Wrong number of arguments +--error 1 +--exec echo "let \$error1= \$(locate('hello'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error2= \$(locate('hello', 'world', 1, 'extra'));" | $MYSQL_TEST 2>&1 + +--echo # Wrong argument types +--error 1 +--exec echo "let \$error3= \$(locate(123, 'world'));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error4= \$(locate('hello', 456));" | $MYSQL_TEST 2>&1 + +--error 1 +--exec echo "let \$error5= \$(locate('hello', 'world', 'invalid'));" | $MYSQL_TEST 2>&1 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LOWER function +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER function tests +let $low1 = $(lower('HELLO WORLD')); +--echo lower('HELLO WORLD') -> $low1 + +let $low2 = $(lower('Hello World')); +--echo lower('Hello World') -> $low2 + +let $low3 = $(lower('hello world')); +--echo lower('hello world') -> $low3 + +let $low4 = $(lower('ABC123')); +--echo lower('ABC123') -> $low4 + +let $low5 = $(lower('')); +--echo lower('') -> $low5 + +let $low6 = $(lower('MIXED Case 123')); +--echo lower('MIXED Case 123') -> $low6 + +let $low7 = $(lower('SPECIAL@#\$%')); +--echo lower('SPECIAL@#\$%') -> $low7 + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER with empty strings +let $lower_empty1 = $(lower('')); +--echo lower('') -> $lower_empty1 + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER with special characters +let $lower_special1 = $(lower('TEST@EXAMPLE.COM')); +--echo lower('TEST@EXAMPLE.COM') -> $lower_special1 + +let $lower_special2 = $(lower('FILE.TXT')); +--echo lower('FILE.TXT') -> $lower_special2 + +let $lower_special3 = $(lower('HELLO-WORLD_123')); +--echo lower('HELLO-WORLD_123') -> $lower_special3 + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER with variables +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER with variables +let $lower_text = "HELLO WORLD"; +let $lower_var_result = $(lower($lower_text)); +--echo lower($lower_text) -> $lower_var_result + +--echo # ---------------------------------------------------------------------------- +--echo # LOWER edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # LOWER edge cases +let $lower_edge1 = $(lower('A')); +--echo lower('A') -> $lower_edge1 + +let $lower_edge2 = $(lower('a')); +--echo lower('a') -> $lower_edge2 + +let $lower_edge3 = $(lower('123')); +--echo lower('123') -> $lower_edge3 + +let $lower_edge4 = $(lower('MiXeD cAsE')); +--echo lower('MiXeD cAsE') -> $lower_edge4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test UPPER function +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER function tests +let $up1 = $(upper('hello world')); +--echo upper('hello world') -> $up1 + +let $up2 = $(upper('Hello World')); +--echo upper('Hello World') -> $up2 + +let $up3 = $(upper('HELLO WORLD')); +--echo upper('HELLO WORLD') -> $up3 + +let $up4 = $(upper('abc123')); +--echo upper('abc123') -> $up4 + +let $up5 = $(upper('')); +--echo upper('') -> $up5 + +let $up6 = $(upper('mixed case 123')); +--echo upper('mixed case 123') -> $up6 + +let $up7 = $(upper('special@#\$%')); +--echo upper('special@#\$%') -> $up7 + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER with empty strings +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER with empty strings +let $upper_empty1 = $(upper('')); +--echo upper('') -> $upper_empty1 + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER with special characters +let $upper_special1 = $(upper('test@example.com')); +--echo upper('test@example.com') -> $upper_special1 + +let $upper_special2 = $(upper('file.txt')); +--echo upper('file.txt') -> $upper_special2 + +let $upper_special3 = $(upper('hello-world_123')); +--echo upper('hello-world_123') -> $upper_special3 + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER with variables +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER with variables +let $upper_text = "hello world"; +let $upper_var_result = $(upper($upper_text)); +--echo upper($upper_text) -> $upper_var_result + +--echo # ---------------------------------------------------------------------------- +--echo # UPPER edge cases +--echo # ---------------------------------------------------------------------------- + +--echo # UPPER edge cases +let $upper_edge1 = $(upper('a')); +--echo upper('a') -> $upper_edge1 + +let $upper_edge2 = $(upper('A')); +--echo upper('A') -> $upper_edge2 + +let $upper_edge3 = $(upper('123')); +--echo upper('123') -> $upper_edge3 + +let $upper_edge4 = $(upper('MiXeD cAsE')); +--echo upper('MiXeD cAsE') -> $upper_edge4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REVERSE function +--echo # ---------------------------------------------------------------------------- + +--echo # REVERSE function tests +let $rev1 = $(reverse('hello')); +--echo reverse('hello') -> $rev1 + +let $rev2 = $(reverse('hello world')); +--echo reverse('hello world') -> $rev2 + +let $rev3 = $(reverse('12345')); +--echo reverse('12345') -> $rev3 + +let $rev4 = $(reverse('')); +--echo reverse('') -> $rev4 + +let $rev5 = $(reverse('a')); +--echo reverse('a') -> $rev5 + +let $rev6 = $(reverse('ab')); +--echo reverse('ab') -> $rev6 + +let $rev7 = $(reverse('ABC123')); +--echo reverse('ABC123') -> $rev7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test TRIM function +--echo # ---------------------------------------------------------------------------- + +--echo # TRIM function tests +let $trim1 = $(trim(' hello world ')); +--echo trim(' hello world ') -> $trim1 + +let $trim2 = $(trim('hello world')); +--echo trim('hello world') -> $trim2 + +let $trim3 = $(trim(' ')); +--echo trim(' ') -> $trim3 + +let $trim4 = $(trim('')); +--echo trim('') -> $trim4 + +let $trim5 = $(trim(' hello')); +--echo trim(' hello') -> $trim5 + +let $trim6 = $(trim('hello ')); +--echo trim('hello ') -> $trim6 + +let $trim7 = $(trim(' hello world ')); +--echo trim(' hello world ') -> $trim7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LTRIM function +--echo # ---------------------------------------------------------------------------- + +--echo # LTRIM function tests +let $ltrim1 = $(ltrim(' hello world')); +--echo ltrim(' hello world') -> $ltrim1 + +let $ltrim2 = $(ltrim('hello world')); +--echo ltrim('hello world') -> $ltrim2 + +let $ltrim3 = $(ltrim(' ')); +--echo ltrim(' ') -> $ltrim3 + +let $ltrim4 = $(ltrim('')); +--echo ltrim('') -> $ltrim4 + +let $ltrim5 = $(ltrim(' hello world')); +--echo ltrim(' hello world') -> $ltrim5 + +let $ltrim6 = $(ltrim('hello world')); +--echo ltrim('hello world') -> $ltrim6 + +let $ltrim7 = $(ltrim(' hello')); +--echo ltrim(' hello') -> $ltrim7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test RTRIM function +--echo # ---------------------------------------------------------------------------- + +--echo # RTRIM function tests +let $rtrim1 = $(rtrim('hello world ')); +--echo rtrim('hello world ') -> $rtrim1 + +let $rtrim2 = $(rtrim('hello world')); +--echo rtrim('hello world') -> $rtrim2 + +let $rtrim3 = $(rtrim(' ')); +--echo rtrim(' ') -> $rtrim3 + +let $rtrim4 = $(rtrim('')); +--echo rtrim('') -> $rtrim4 + +let $rtrim5 = $(rtrim(' hello world ')); +--echo rtrim(' hello world ') -> $rtrim5 + +let $rtrim6 = $(rtrim('hello world')); +--echo rtrim('hello world') -> $rtrim6 + +let $rtrim7 = $(rtrim('hello ')); +--echo rtrim('hello ') -> $rtrim7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LPAD function +--echo # ---------------------------------------------------------------------------- + +--echo # LPAD function tests +let $lpad1 = $(lpad('hello', 10, '*')); +--echo lpad('hello', 10, '*') -> $lpad1 + +let $lpad2 = $(lpad('hello', 5, '*')); +--echo lpad('hello', 5, '*') -> $lpad2 + +let $lpad3 = $(lpad('hello', 3, '*')); +--echo lpad('hello', 3, '*') -> $lpad3 + +let $lpad4 = $(lpad('hello', 10, ' ')); +--echo lpad('hello', 10, ' ') -> $lpad4 + +let $lpad5 = $(lpad('', 5, '*')); +--echo lpad('', 5, '*') -> $lpad5 + +let $lpad6 = $(lpad('hello', 10, 'ab')); +--echo lpad('hello', 10, 'ab') -> $lpad6 + +let $lpad7 = $(lpad('hello', 0, '*')); +--echo lpad('hello', 0, '*') -> $lpad7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test RPAD function +--echo # ---------------------------------------------------------------------------- + +--echo # RPAD function tests +let $rpad1 = $(rpad('hello', 10, '*')); +--echo rpad('hello', 10, '*') -> $rpad1 + +let $rpad2 = $(rpad('hello', 5, '*')); +--echo rpad('hello', 5, '*') -> $rpad2 + +let $rpad3 = $(rpad('hello', 3, '*')); +--echo rpad('hello', 3, '*') -> $rpad3 + +let $rpad4 = $(rpad('hello', 10, ' ')); +--echo rpad('hello', 10, ' ') -> $rpad4 + +let $rpad5 = $(rpad('', 5, '*')); +--echo rpad('', 5, '*') -> $rpad5 + +let $rpad6 = $(rpad('hello', 10, 'ab')); +--echo rpad('hello', 10, 'ab') -> $rpad6 + +let $rpad7 = $(rpad('hello', 0, '*')); +--echo rpad('hello', 0, '*') -> $rpad7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LENGTH function +--echo # ---------------------------------------------------------------------------- + +--echo # LENGTH function tests +let $len1 = $(length('hello')); +--echo length('hello') -> $len1 + +let $len2 = $(length('hello world')); +--echo length('hello world') -> $len2 + +let $len3 = $(length('')); +--echo length('') -> $len3 + +let $len4 = $(length('12345')); +--echo length('12345') -> $len4 + +let $len5 = $(length(' hello ')); +--echo length(' hello ') -> $len5 + +let $len6 = $(length('a')); +--echo length('a') -> $len6 + +let $len7 = $(length('special@#\$%')); +--echo length('special@#\$%') -> $len7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test special characters and Latin characters +--echo # ---------------------------------------------------------------------------- + +--echo # Special characters and Latin characters tests +let $latin1 = $(length('Björn')); +--echo length('Björn') -> $latin1 +let $latin2 = $(upper('björn')); +--echo upper('björn') -> $latin2 +let $latin3 = $(lower('BJÖRN')); +--echo lower('BJÖRN') -> $latin3 +let $latin4 = $(reverse('Björn')); +--echo reverse('Björn') -> $latin4 +let $latin5 = $(locate('ö', 'Björn')); +--echo locate('ö', 'Björn') -> $latin5 +let $latin6 = $(substr('Björn', 1, 3)); +--echo substr('Björn', 1, 3) -> $latin6 +let $latin7 = $(trim(' Björn ')); +--echo trim(' Björn ') -> $latin7 +let $latin8 = $(concat('Björn', ' ', 'Müller')); +--echo concat('Björn', ' ', 'Müller') -> $latin8 +let $latin9 = $(replace('Björn Müller', 'Müller', 'Schmidt')); +--echo replace('Björn Müller', 'Müller', 'Schmidt') -> $latin9 +let $latin10 = $(instr('Björn Müller', 'Müller')); +--echo instr('Björn Müller', 'Müller') -> $latin10 +let $latin11 = $(lpad('Björn', 10, '*')); +--echo lpad('Björn', 10, '*') -> $latin11 +let $latin12 = $(rpad('Björn', 10, '*')); +--echo rpad('Björn', 10, '*') -> $latin12 +let $latin13 = $(length('Khåled Rïyad')); +--echo length('Khåled Rïyad') -> $latin13 +let $latin14 = $(upper('josé maría')); +--echo upper('josé maría') -> $latin14 +let $latin15 = $(substr('José María', 1, 4)); +--echo substr('José María', 1, 4) -> $latin15 + +--echo # ---------------------------------------------------------------------------- +--echo # Test special characters and symbols +--echo # ---------------------------------------------------------------------------- + +--echo # Special characters and symbols tests +let $symbols1 = $(concat('path', '/', 'to', '/', 'file.txt')); +--echo concat('path', '/', 'to', '/', 'file.txt') -> $symbols1 +let $symbols2 = $(instr('user@domain.com', 'domain.com')); +--echo instr('user@domain.com', 'domain.com') -> $symbols2 +let $symbols3 = $(length('path/to/file.txt')); +--echo length('path/to/file.txt') -> $symbols3 +let $symbols4 = $(locate('.', 'file.txt')); +--echo locate('.', 'file.txt') -> $symbols4 +let $symbols5 = $(locate('/', 'path/to/file.txt')); +--echo locate('/', 'path/to/file.txt') -> $symbols5 +let $symbols6 = $(upper('test@example.com')); +--echo upper('test@example.com') -> $symbols6 +let $symbols7 = $(lower('TEST@EXAMPLE.COM')); +--echo lower('TEST@EXAMPLE.COM') -> $symbols7 +let $symbols8 = $(lpad('file', 8, '.')); +--echo lpad('file', 8, '.') -> $symbols8 +let $symbols9 = $(rpad('path', 10, '/')); +--echo rpad('path', 10, '/') -> $symbols9 +let $symbols10 = $(replace('file.txt', 'txt', 'doc')); +--echo replace('file.txt', 'txt', 'doc') -> $symbols10 +let $symbols11 = $(replace('path/to/file.txt', 'file.txt', 'document.doc')); +--echo replace('path/to/file.txt', 'file.txt', 'document.doc') -> $symbols11 +let $symbols12 = $(reverse('path/to/file.txt')); +--echo reverse('path/to/file.txt') -> $symbols12 +let $symbols13 = $(substr('path/to/file.txt', 1, 4)); +--echo substr('path/to/file.txt', 1, 4) -> $symbols13 +let $symbols14 = $(trim(' path/to/file.txt ')); +--echo trim(' path/to/file.txt ') -> $symbols14 + +--echo # ---------------------------------------------------------------------------- +--echo # Test complex combinations of string functions +--echo # ---------------------------------------------------------------------------- + +--echo # Complex string function combinations + +let $complex1 = $(length(trim(' hello world '))); +--echo length(trim(' hello world ')) -> $complex1 + +let $complex2 = $(upper(lower('MiXeD CaSe'))); +--echo upper(lower('MiXeD CaSe')) -> $complex2 + +let $complex3 = $(reverse(lpad('hi', 5, '*'))); +--echo reverse(lpad('hi', 5, '*')) -> $complex3 + +let $complex4 = $(locate('o', upper('hello world'))); +--echo locate('o', upper('hello world')) -> $complex4 + +let $complex5 = $(substr(trim(' hello world '), 1, 5)); +--echo substr(trim(' hello world '), 1, 5) -> $complex5 + +let $complex6 = $(length(concat('hello', ' ', 'world'))); +--echo length(concat('hello', ' ', 'world')) -> $complex6 + +let $complex7 = $(reverse(upper('hello'))); +--echo reverse(upper('hello')) -> $complex7 + +let $complex8 = $(lpad(rtrim('hello '), 10, '*')); +--echo lpad(rtrim('hello '), 10, '*') -> $complex8 + +let $complex9 = $(least(length('hello'), length('world'), length('test'))); +--echo least(length('hello'), length('world'), length('test')) -> $complex9 + +let $complex10 = $(greatest(instr('hello world', 'h'), instr('hello world', 'w'), instr('hello world', 'o'))); +--echo greatest(instr('hello world', 'h'), instr('hello world', 'w'), instr('hello world', 'o')) -> $complex10 + +let $complex11 = $(repeat(upper(substr('hello', 1, 2)), 3)); +--echo repeat(upper(substr('hello', 1, 2)), 3) -> $complex11 + +let $complex12 = $(insert(lower('HELLO WORLD'), 7, 5, upper('mariadb'))); +--echo insert(lower('HELLO WORLD'), 7, 5, upper('mariadb')) -> $complex12 + +let $complex13 = $(concat_ws('-', upper('hello'), lower('WORLD'), reverse('test'))); +--echo concat_ws('-', upper('hello'), lower('WORLD'), reverse('test')) -> $complex13 + +let $complex14 = $(ifnull(nullif(trim(' hello '), 'hello'), 'default')); +--echo ifnull(nullif(trim(' hello '), 'hello'), 'default') -> $complex14 + +let $complex15 = $(coalesce(nullif('test', 'test'), upper('backup'))); +--echo coalesce(nullif('test', 'test'), upper('backup')) -> $complex15 + +let $complex16 = $(substring_index(concat('www', '.', 'mariadb', '.', 'org'), '.', 2)); +--echo substring_index(concat('www', '.', 'mariadb', '.', 'org'), '.', 2) -> $complex16 + +--echo # ---------------------------------------------------------------------------- +--echo # Test CONCAT function +--echo # ---------------------------------------------------------------------------- + +--echo # Basic CONCAT function tests + +let $concat1 = $(concat('a','b','c')); +--echo concat('a','b','c') -> $concat1 + +let $concat2 = $(concat(42, 'a')); +--echo concat(42, 'a') -> $concat2 + +let $concat3 = $(concat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '1', 'a')); +--echo concat(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, '1', 'a') -> $concat3 + +let $concat4 = $(concat('')); +--echo concat('') -> $concat4 + +let $concat5 = $(concat('å', 'ñ', 'ç', 'ü', 'é', 'ö', 'ß', 'æ', 'ø', 'î', 'ë', 'ä', 'ï', 'ô', 'à', 'ù', 'ê', 'â', 'ý', 'þ', 'ð', 'ł', 'ś', 'ż', 'ź', 'ć')); +--echo concat('å', 'ñ', 'ç', 'ü', 'é', 'ö', 'ß', 'æ', 'ø', 'î', 'ë', 'ä', 'ï', 'ô', 'à', 'ù', 'ê', 'â', 'ý', 'þ', 'ð', 'ł', 'ś', 'ż', 'ź', 'ć') -> $concat5 + +let $concat6 = $(concat('', 1)); +--echo concat('', 1) -> $concat6 + +--echo # ---------------------------------------------------------------------------- +--echo # Test SUBSTRING_INDEX function +--echo # ---------------------------------------------------------------------------- + +--echo # SUBSTRING_INDEX function tests + +let $substr_idx1 = $(substring_index('www.mariadb.org', '.', 2)); +--echo substring_index('www.mariadb.org', '.', 2) -> $substr_idx1 + +let $substr_idx2 = $(substring_index('www.mariadb.org', '.', -2)); +--echo substring_index('www.mariadb.org', '.', -2) -> $substr_idx2 + +let $substr_idx3 = $(substring_index('www.mariadb.org', '.', 0)); +--echo substring_index('www.mariadb.org', '.', 0) -> $substr_idx3 + +let $substr_idx4 = $(substring_index('www.mariadb.org', '', 1)); +--echo substring_index('www.mariadb.org', '', 1) -> $substr_idx4 + +let $substr_idx5 = $(substring_index('www.mariadb.org', '', -1)); +--echo substring_index('www.mariadb.org', '', -1) -> $substr_idx5 + +let $substr_idx6 = $(substring_index('mariadb', '.', 0)); +--echo substring_index('mariadb', '.', 0) -> $substr_idx6 + +let $substr_idx7 = $(substring_index('mariadb', '.', -1)); +--echo substring_index('mariadb', '.', -1) -> $substr_idx7 + +let $substr_idx8 = $(substring_index('mariadb', '.', 1)); +--echo substring_index('mariadb', '.', 1) -> $substr_idx8 + +let $substr_idx9 = $(substring_index('mariadb', 'A', 1)); +--echo substring_index('mariadb', 'A', 1) -> $substr_idx9 + +let $substr_idx10 = $(substring_index('mariadb', 'A', -1)); +--echo substring_index('mariadb', 'A', -1) -> $substr_idx10 + +let $substr_idx11 = $(substring_index('mariadb', 'A', 0)); +--echo substring_index('mariadb', 'A', 0) -> $substr_idx11 + +let $substr_idx12 = $(substring_index('mariadb', 'z', 2)); +--echo substring_index('mariadb', 'z', 2) -> $substr_idx12 + +let $substr_idx13 = $(substring_index('', 'z', -2)); +--echo substring_index('', 'z', -2) -> $substr_idx13 + +let $substr_idx14 = $(substring_index('mariadb', 'ar', 0)); +--echo substring_index('mariadb', 'ar', 0) -> $substr_idx14 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REGEXP_INSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # REGEXP_INSTR function tests + +let $regexp_instr1 = $(regexp_instr('abc','b')); +--echo regexp_instr('abc','b') -> $regexp_instr1 + +let $regexp_instr2 = $(regexp_instr('abc','x')); +--echo regexp_instr('abc','x') -> $regexp_instr2 + +let $regexp_instr3 = $(regexp_instr('abc','')); +--echo regexp_instr('abc','') -> $regexp_instr3 + +let $regexp_instr4 = $(regexp_instr('','a')); +--echo regexp_instr('','a') -> $regexp_instr4 + +let $regexp_instr5 = $(regexp_instr('','')); +--echo regexp_instr('','') -> $regexp_instr5 + +let $regexp_instr6 = $(regexp_instr('BJÖRN','N')); +--echo regexp_instr('BJÖRN','N') -> $regexp_instr6 + +let $regexp_instr7 = $(regexp_instr('ABC','(?-i)b')); +--echo regexp_instr('ABC','(?-i)b') -> $regexp_instr7 + +let $regexp_instr8 = $(regexp_instr('ABC','(?i)b')); +--echo regexp_instr('ABC','(?i)b') -> $regexp_instr8 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REGEXP_SUBSTR function +--echo # ---------------------------------------------------------------------------- + +--echo # REGEXP_SUBSTR function tests + +let $regexp_substr1 = $(regexp_substr('ab12cd','[0-9]+')); +--echo regexp_substr('ab12cd','[0-9]+') -> $regexp_substr1 + +let $regexp_substr2 = $(regexp_substr('ab12cd','')); +--echo regexp_substr('ab12cd','') -> $regexp_substr2 + +let $regexp_substr3 = $(regexp_substr('abcd','[0-9]+')); +--echo regexp_substr('abcd','[0-9]+') -> $regexp_substr3 + +let $regexp_substr4 = $(regexp_substr('','[0-9]+')); +--echo regexp_substr('','[0-9]+') -> $regexp_substr4 + +let $regexp_substr5 = $(regexp_substr('','')); +--echo regexp_substr('','') -> $regexp_substr5 + +let $regexp_substr6 = $(regexp_substr('See https://mariadb.org/en/foundation/ for details','https?://[^/]*')); +--echo regexp_substr('See https://mariadb.org/en/foundation/ for details','https?://[^/]*') -> $regexp_substr6 + +let $regexp_substr7 = $(regexp_substr('ABC','b')); +--echo regexp_substr('ABC','b') -> $regexp_substr7 + +let $regexp_substr8 = $(regexp_substr('ABC','(?i)b')); +--echo regexp_substr('ABC','(?i)b') -> $regexp_substr8 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REGEXP_REPLACE function +--echo # ---------------------------------------------------------------------------- + +--echo # REGEXP_REPLACE function tests + +let $regexp_replace1 = $(regexp_replace('ABC','b','x')); +--echo regexp_replace('ABC','b','x') -> $regexp_replace1 + +let $regexp_replace2 = $(regexp_replace('ab12cd','[0-9]','')); +--echo regexp_replace('ab12cd','[0-9]','') -> $regexp_replace2 + +let $regexp_replace3 = $(regexp_replace('titlebody', '<.+?>',' ')); +--echo regexp_replace('titlebody', '<.+?>',' ') -> $regexp_replace3 + +let $regexp_replace4 = $(regexp_replace('James Bond','^(.*) (.*)\$','\2, \1')); +--echo regexp_replace('James Bond','^(.*) (.*)\$','\2, \1') -> $regexp_replace4 + +let $regexp_replace5 = $(regexp_replace('ABC','b','-')); +--echo regexp_replace('ABC','b','-') -> $regexp_replace5 + +let $regexp_replace6 = $(regexp_replace('ABC','(?-i)b','-')); +--echo regexp_replace('ABC','(?-i)b','-') -> $regexp_replace6 + +let $regexp_replace7 = $(regexp_replace('ABC','(?i)b','-')); +--echo regexp_replace('ABC','(?i)b','-') -> $regexp_replace7 + +let $regexp_replace8 = $(regexp_replace('ABC','b','')); +--echo regexp_replace('ABC','b','') -> $regexp_replace8 + +let $regexp_replace9 = $(regexp_replace('ABC','(?-i)b','')); +--echo regexp_replace('ABC','(?-i)b','') -> $regexp_replace9 + +let $regexp_replace10 = $(regexp_replace('ABC','','')); +--echo regexp_replace('ABC','','') -> $regexp_replace10 + +let $regexp_replace11 = $(regexp_replace('ABC','','A')); +--echo regexp_replace('ABC','','A') -> $regexp_replace11 + +let $regexp_replace12 = $(regexp_replace('','.','x')); +--echo regexp_replace('','.','x') -> $regexp_replace12 + +let $dollar1 = $(regexp_replace('ABC','b','\$')); +--echo regexp_replace('ABC','b','\$') -> $dollar1 + +let $dollar2 = $(regexp_replace('ABC','b','\$A')); +--echo regexp_replace('ABC','b','\$A') -> $dollar2 + +let $dollar3 = $(regexp_replace('ABCC','C\$','D')); +--echo regexp_replace('ABCC','C\$','D') -> $dollar3 + +let $dollar4 = $(regexp_replace('ABC\$','\\\$','D')); +--echo regexp_replace('ABC\$','\\\$','D') -> $dollar4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test LEAST function +--echo # ---------------------------------------------------------------------------- + +--echo # LEAST function tests + +let $least1 = $(least(1, 2, 3)); +--echo least(1, 2, 3) -> $least1 + +let $least2 = $(least('a', 'b', 'c')); +--echo least('a', 'b', 'c') -> $least2 + +let $least3 = $(least(NULL, 1, 2)); +--echo least(NULL, 1, 2) -> $least3 + +let $least4 = $(least(NULL, NULL, NULL)); +--echo least(NULL, NULL, NULL) -> $least4 + +let $least5 = $(least('a', 1, 'b')); +--echo least('a', 1, 'b') -> $least5 + +let $least6 = $(least(1, 'a', 'b')); +--echo least(1, 'a', 'b') -> $least6 + +let $least7 = $(least('z', '-2', 'a')); +--echo least('z', '-2', 'a') -> $least7 + +let $least8 = $(least('z', -2, 'a')); +--echo least('z', -2, 'a') -> $least8 + +let $least9 = $(least(' -4a', -1, 'b')); +--echo least(' -4a', -1, 'b') -> $least9 + +let $least10 = $(least(' ', 10, 'b')); +--echo least(' ', 10, 'b') -> $least10 + +let $least11 = $(least(' -0 ', 10, 'b')); +--echo least(' -0 ', 10, 'b') -> $least11 + +let $least12 = $(least('', 10, '-b')); +--echo least('', 10, '-b') -> $least12 + +let $least13 = $(least(18446744073709551615, 18446744073709551614, 18446744073709551613)); +--echo least(18446744073709551615, 18446744073709551614, 18446744073709551613) -> $least13 + +let $least14 = $(least(18446744073709551615, -1, 18446744073709551613)); +--echo least(18446744073709551615, -1, 18446744073709551613) -> $least14 + +--echo # ---------------------------------------------------------------------------- +--echo # Test GREATEST function +--echo # ---------------------------------------------------------------------------- + +--echo # GREATEST function tests + +let $greatest1 = $(greatest(1, 2, 3)); +--echo greatest(1, 2, 3) -> $greatest1 + +let $greatest2 = $(greatest('a', 'b', 'c')); +--echo greatest('a', 'b', 'c') -> $greatest2 + +let $greatest3 = $(greatest(NULL, 1, 2)); +--echo greatest(NULL, 1, 2) -> $greatest3 + +let $greatest4 = $(greatest(NULL, NULL, NULL)); +--echo greatest(NULL, NULL, NULL) -> $greatest4 + +let $greatest5 = $(greatest('a', 1, 'b')); +--echo greatest('a', 1, 'b') -> $greatest5 + +let $greatest6 = $(greatest(1, 'a', 'b')); +--echo greatest(1, 'a', 'b') -> $greatest6 + +let $greatest7 = $(greatest('z', '-2', 'a')); +--echo greatest('z', '-2', 'a') -> $greatest7 + +let $greatest8 = $(greatest('z', -2, 'a')); +--echo greatest('z', -2, 'a') -> $greatest8 + +let $greatest9 = $(greatest(' -4a', -1, 'b')); +--echo greatest(' -4a', -1, 'b') -> $greatest9 + +let $greatest10 = $(greatest(' ', 10, 'b')); +--echo greatest(' ', 10, 'b') -> $greatest10 + +let $greatest11 = $(greatest(' -0 ', 10, 'b')); +--echo greatest(' -0 ', 10, 'b') -> $greatest11 + +let $greatest12 = $(greatest('', 10, '-b')); +--echo greatest('', 10, '-b') -> $greatest12 + +let $greatest13 = $(greatest(18446744073709551615, 18446744073709551614, 18446744073709551613)); +--echo greatest(18446744073709551615, 18446744073709551614, 18446744073709551613) -> $greatest13 + +let $greatest14 = $(greatest(18446744073709551615, -1, 18446744073709551613)); +--echo greatest(18446744073709551615, -1, 18446744073709551613) -> $greatest14 + +let $greatest15 = $(greatest(3.14, 2.71, 3.15)); +--echo greatest(3.14, 2.71, 3.15) -> $greatest15 + +let $greatest16 = $(greatest(-10, -5, -20)); +--echo greatest(-10, -5, -20) -> $greatest16 + +let $greatest17 = $(greatest('apple', 'banana', 'cherry')); +--echo greatest('apple', 'banana', 'cherry') -> $greatest17 + +let $greatest18 = $(greatest('100', '20', '3')); +--echo greatest('100', '20', '3') -> $greatest18 + +--echo # ---------------------------------------------------------------------------- +--echo # Test REPEAT function +--echo # ---------------------------------------------------------------------------- + +--echo # REPEAT function tests + +let $repeat1 = $(repeat('MariaDB ',4)); +--echo repeat('MariaDB ',4) -> $repeat1 + +let $repeat2 = $(repeat('a', 0)); +--echo repeat('a', 0) -> $repeat2 + +let $repeat3 = $(repeat('a', 1)); +--echo repeat('a', 1) -> $repeat3 + +let $repeat4 = $(repeat('', 0)); +--echo repeat('', 0) -> $repeat4 + +let $repeat5 = $(repeat('a', -1)); +--echo repeat('a', -1) -> $repeat5 + +let $repeat6 = $(repeat('a', 18446744073709551615)); +--echo repeat('a', 18446744073709551615) -> $repeat6 + +let $repeat7 = $(repeat('', 4)); +--echo repeat('', 4) -> $repeat7 + +let $repeat8 = $(repeat('', -1)); +--echo repeat('', -1) -> $repeat8 + +let $repeat9 = $(repeat('a32423413', 100)); +--echo repeat('a32423413', 10) -> $repeat9 + +--echo # ---------------------------------------------------------------------------- +--echo # Test NULLIF function +--echo # ---------------------------------------------------------------------------- + +--echo # NULLIF function tests + +let $nullif1 = $(nullif('a', 'a')); +--echo nullif('a', 'a') -> $nullif1 + +let $nullif2 = $(nullif('a', 'b')); +--echo nullif('a', 'b') -> $nullif2 + +let $nullif3 = $(nullif('a', NULL)); +--echo nullif('a', NULL) -> $nullif3 + +let $nullif4 = $(nullif(NULL, 'a')); +--echo nullif(NULL, 'a') -> $nullif4 + +let $nullif5 = $(nullif(NULL, NULL)); +--echo nullif(NULL, NULL) -> $nullif5 + +--echo # ---------------------------------------------------------------------------- +--echo # Test COALESCE function +--echo # ---------------------------------------------------------------------------- + +--echo # COALESCE function tests + +let $coalesce1 = $(coalesce(NULL, 'a')); +--echo coalesce(NULL, 'a') -> $coalesce1 + +let $coalesce2 = $(coalesce(NULL, NULL)); +--echo coalesce(NULL, NULL) -> $coalesce2 + +let $coalesce3 = $(coalesce(NULL, 'a', 'b')); +--echo coalesce(NULL, 'a', 'b') -> $coalesce3 + +let $coalesce4 = $(coalesce('a', 'b', 'c')); +--echo coalesce('a', 'b', 'c') -> $coalesce4 + +let $coalesce5 = $(coalesce('a', NULL, 'b')); +--echo coalesce('a', NULL, 'b') -> $coalesce5 + +let $coalesce6 = $(coalesce(NULL, NULL, 'a')); +--echo coalesce(NULL, NULL, 'a') -> $coalesce6 + +let $coalesce7 = $(coalesce(NULL, NULL, NULL)); +--echo coalesce(NULL, NULL, NULL) -> $coalesce7 + +let $coalesce8 = $(coalesce(NULL, 'a', NULL, 'b')); +--echo coalesce(NULL, 'a', NULL, 'b') -> $coalesce8 + +--echo # ---------------------------------------------------------------------------- +--echo # Test IFNULL function +--echo # ---------------------------------------------------------------------------- + +--echo # IFNULL function tests + +let $ifnull1 = $(ifnull(NULL, 'a')); +--echo ifnull(NULL, 'a') -> $ifnull1 + +let $ifnull2 = $(ifnull('a', NULL)); +--echo ifnull('a', NULL) -> $ifnull2 + +let $ifnull3 = $(ifnull(NULL, NULL)); +--echo ifnull(NULL, NULL) -> $ifnull3 + +let $ifnull4 = $(ifnull('a', 'b')); +--echo ifnull('a', 'b') -> $ifnull4 + +let $ifnull5 = $(ifnull('a', 'a')); +--echo ifnull('a', 'a') -> $ifnull5 + +--echo # ---------------------------------------------------------------------------- +--echo # Test INSERT function +--echo # ---------------------------------------------------------------------------- + +--echo # INSERT function tests + +let $insert1 = $(insert('Hello World', 2, 3, 'Xyz')); +--echo insert('Hello World', 2, 3, 'Xyz') -> $insert1 + +let $insert2 = $(insert('Hello World', 2, 3, '')); +--echo insert('Hello World', 2, 3, '') -> $insert2 + +let $insert3 = $(insert('Hello World', 2, 3, NULL)); +--echo insert('Hello World', 2, 3, NULL) -> $insert3 + +let $insert4 = $(insert('Hello World', 0, 0, 'Xyz')); +--echo insert('Hello World', 0, 0, 'Xyz') -> $insert4 + +let $insert5 = $(insert('Hello World', 0, 0, '')); +--echo insert('Hello World', 0, 0, '') -> $insert5 + +let $insert6 = $(insert('Quadratic', 3, 4, 'What')); +--echo insert('Quadratic', 3, 4, 'What') -> $insert6 + +let $insert7 = $(insert('Quadratic', -1, 4, 'What')); +--echo insert('Quadratic', -1, 4, 'What') -> $insert7 + +let $insert8 = $(insert('Quadratic', 3, 100, 'What')); +--echo insert('Quadratic', 3, 100, 'What') -> $insert8 + +let $insert9 = $(insert('Quadratic', -32, -100, 'wow')); +--echo insert('Quadratic', -32, -100, 'wow') -> $insert9 + +let $insert10 = $(insert('Quadratic', 32, 100, 'wow')); +--echo insert('Quadratic', 32, 100, 'wow') -> $insert10 + +let $insert11 = $(insert('Quadratic', 1, 8, 'wow')); +--echo insert('Quadratic', 1, 8, 'wow') -> $insert11 + +let $insert12 = $(insert('Quadratic', 1, 1000, 'wow')); +--echo insert('Quadratic', 1, 1000, 'wow') -> $insert12 + +let $insert13 = $(insert('Quadratic', 4, 2, 'wow')); +--echo insert('Quadratic', 4, 2, 'wow') -> $insert13 + +let $insert14 = $(insert('Quadratic', 4, 2, '')); +--echo insert('Quadratic', 4, 2, '') -> $insert14 + +let $insert15 = $(insert('', 4, 2, 'wow')); +--echo insert('', 4, 2, 'wow') -> $insert15 + +let $insert16 = $(insert('Quadratic', 4, -2, 'wow')); +--echo insert('Quadratic', 4, -2, 'wow') -> $insert16 + +let $insert17 = $(insert('Quadratic', 4, 0, 'wow')); +--echo insert('Quadratic', 4, 0, 'wow') -> $insert17 + +--echo # ---------------------------------------------------------------------------- +--echo # Test CONCAT_WS function +--echo # ---------------------------------------------------------------------------- + +--echo # CONCAT_WS function tests + +let $concat_ws1 = $(concat_ws('-', 'a', 'b', 'c')); +--echo concat_ws('-', 'a', 'b', 'c') -> $concat_ws1 + +let $concat_ws2 = $(concat_ws('#', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z')); +--echo concat_ws('#', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z') -> $concat_ws2 + +let $concat_ws3 = $(concat_ws(' ,', 'a')); +--echo concat_ws(' ,', 'a') -> $concat_ws3 + +let $concat_ws4 = $(concat_ws('', 'abc', 'def', 'ghi')); +--echo concat_ws('', 'abc', 'def', 'ghi') -> $concat_ws4 + +let $concat_ws5 = $(concat_ws('', 'abc')); +--echo concat_ws('', 'abc') -> $concat_ws5 + +let $concat_ws6 = $(concat_ws('&', 'abc')); +--echo concat_ws('&', 'abc') -> $concat_ws6 + +let $concat_ws7 = $(concat_ws(' ,', '')); +--echo concat_ws(' ,', '') -> $concat_ws7 + +let $concat_ws8 = $(concat_ws('&', 'abc', NULL)); +--echo concat_ws('&', 'abc', NULL) -> $concat_ws8 + +let $concat_ws9 = $(concat_ws('...', 'abc', NULL, 'def')); +--echo concat_ws('...', 'abc', NULL, 'def') -> $concat_ws9 + +let $concat_ws10 = $(concat_ws(NULL, 'abc', NULL, 'def')); +--echo concat_ws(NULL, 'abc', NULL, 'def') -> $concat_ws10 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with variables +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with variables + +let $text = 'test string'; +let $search = 'string'; +let $replacement = 'value'; + +let $result1 = $(least($text, $search)); +--echo least($text, $search) -> $result1 + +let $result1a = $(greatest($text, $search)); +--echo greatest($text, $search) -> $result1a + +let $result2 = $(repeat($search, 3)); +--echo repeat($search, 3) -> $result2 + +let $result3 = $(insert($text, 5, 6, $replacement)); +--echo insert($text, 5, 6, $replacement) -> $result3 + +let $result4 = $(concat_ws(' ', $text, $search, $replacement)); +--echo concat_ws(' ', $text, $search, $replacement) -> $result4 + +let $result5 = $(ifnull(NULL, $replacement)); +--echo ifnull(NULL, $replacement) -> $result5 + +let $result6 = $(coalesce(NULL, NULL, $replacement)); +--echo coalesce(NULL, NULL, $replacement) -> $result6 + +let $result7 = $(nullif($text, $search)); +--echo nullif($text, $search) -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with special characters +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with special characters + +let $result1 = $(least('Björn', 'Müller', 'Schmidt')); +--echo least('Björn', 'Müller', 'Schmidt') -> $result1 + +let $result1a = $(greatest('Björn', 'Müller', 'Schmidt')); +--echo greatest('Björn', 'Müller', 'Schmidt') -> $result1a + +let $result2 = $(repeat('ö', 5)); +--echo repeat('ö', 5) -> $result2 + +let $result3 = $(insert('Björn Müller', 7, 6, 'Schmidt')); +--echo insert('Björn Müller', 7, 6, 'Schmidt') -> $result3 + +let $result4 = $(concat_ws(' ', 'José', 'María', 'González')); +--echo concat_ws(' ', 'José', 'María', 'González') -> $result4 + +let $result5 = $(ifnull(NULL, 'François')); +--echo ifnull(NULL, 'François') -> $result5 + +let $result6 = $(coalesce(NULL, 'Håkon', 'Olsen')); +--echo coalesce(NULL, 'Håkon', 'Olsen') -> $result6 + +let $result7 = $(nullif('test@example.com', 'user@domain.com')); +--echo nullif('test@example.com', 'user@domain.com') -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with mixed data types +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with mixed data types + +let $result1 = $(least(123, 'abc', 456)); +--echo least(123, 'abc', 456) -> $result1 + +let $result1a = $(greatest(123, 'abc', 456)); +--echo greatest(123, 'abc', 456) -> $result1a + +let $result2 = $(repeat('test', 3)); +--echo repeat('test', 3) -> $result2 + +let $result3 = $(insert('test123', 5, 3, 'ABC')); +--echo insert('test123', 5, 3, 'ABC') -> $result3 + +let $result4 = $(concat_ws('-', 'prefix', 123, 'suffix')); +--echo concat_ws('-', 'prefix', 123, 'suffix') -> $result4 + +let $result5 = $(ifnull(123, 'fallback')); +--echo ifnull(123, 'fallback') -> $result5 + +let $result6 = $(coalesce(NULL, 456, 'backup')); +--echo coalesce(NULL, 456, 'backup') -> $result6 + +let $result7 = $(nullif(123, 456)); +--echo nullif(123, 456) -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions in complex expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Functions in complex expressions + +let $result1 = $(least(1, 2, 3) + 10); +--echo least(1, 2, 3) + 10 -> $result1 + +let $result1a = $(greatest(1, 2, 3) * 5); +--echo greatest(1, 2, 3) * 5 -> $result1a + +let $result2 = $(length(repeat('ab', 4))); +--echo length(repeat('ab', 4)) -> $result2 + +let $result3 = $(upper(insert('hello world', 7, 5, 'mariadb'))); +--echo upper(insert('hello world', 7, 5, 'mariadb')) -> $result3 + +let $result4 = $(length(concat_ws(' ', 'hello', 'world', 'test'))); +--echo length(concat_ws(' ', 'hello', 'world', 'test')) -> $result4 + +let $result5 = $(ifnull(NULL, 'default') == 'default'); +--echo ifnull(NULL, 'default') == 'default' -> $result5 + +let $result6 = $(coalesce(NULL, NULL, 'found') != 'missing'); +--echo coalesce(NULL, NULL, 'found') != 'missing' -> $result6 + +let $result7 = $(nullif('same', 'same')); +--echo nullif('same', 'same') -> $result7 + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions in conditional expressions +--echo # ---------------------------------------------------------------------------- + +--echo # Functions in conditional expressions + +if ($(least(5, 3, 8) == 3)) +{ + --echo least returns minimum value correctly +} + +if ($(greatest(5, 3, 8) == 8)) +{ + --echo greatest returns maximum value correctly +} + +if ($(repeat('x', 0) == '')) +{ + --echo repeat with count 0 returns empty string +} + +if ($(insert('test', 1, 2, 'best') == 'best')) +{ + --echo insert replaces correctly at start +} + +if ($(concat_ws(',', 'a', 'b') == 'a,b')) +{ + --echo CONCAT_WS joins with separator correctly +} + +if ($(ifnull('value', 'default') == 'value')) +{ + --echo ifnull returns first value when not NULL +} + +if ($(coalesce(NULL, 'second', 'third') == 'second')) +{ + --echo coalesce returns first non-NULL value +} + +if ($(nullif('different', 'values') == 'different')) +{ + --echo nullif returns first value when values differ +} + +--echo # ---------------------------------------------------------------------------- +--echo # Test functions with arithmetic in arguments +--echo # ---------------------------------------------------------------------------- + +--echo # Functions with arithmetic in arguments + +let $result1 = $(least(1+2, 2*2, 3+1)); +--echo least(1+2, 2*2, 3+1) -> $result1 + +let $result1a = $(greatest(1+2, 2*2, 3+1)); +--echo greatest(1+2, 2*2, 3+1) -> $result1a + +let $result2 = $(repeat('x', 2+3)); +--echo repeat('x', 2+3) -> $result2 + +let $result3 = $(insert('hello', 1+1, 2*1, 'hi')); +--echo insert('hello', 1+1, 2*1, 'hi') -> $result3 + +let $start_pos = 2; +let $length_val = 3; +let $result4 = $(insert('testing', $start_pos, $length_val, 'xyz')); +--echo insert('testing', $start_pos, $length_val, 'xyz') -> $result4 + +--echo # ---------------------------------------------------------------------------- +--echo # Test nested function calls +--echo # ---------------------------------------------------------------------------- + +--echo # Nested function calls + +let $result1 = $(least(length('hello'), length('world'), length('test'))); +--echo least(length('hello'), length('world'), length('test')) -> $result1 + +let $result1a = $(greatest(length('hello'), length('world'), length('test'))); +--echo greatest(length('hello'), length('world'), length('test')) -> $result1a + +let $result2 = $(repeat(upper('ab'), 3)); +--echo repeat(upper('ab'), 3) -> $result2 + +let $result3 = $(insert(upper('hello world'), 7, 5, lower('MARIADB'))); +--echo insert(upper('hello world'), 7, 5, lower('MARIADB')) -> $result3 + +let $result4 = $(concat_ws(' ', upper('hello'), lower('WORLD'))); +--echo concat_ws(' ', upper('hello'), lower('WORLD')) -> $result4 + +let $result5 = $(ifnull(nullif('same', 'same'), 'default')); +--echo ifnull(nullif('same', 'same'), 'default') -> $result5 + +let $result6 = $(coalesce(nullif('test', 'test'), 'backup')); +--echo coalesce(nullif('test', 'test'), 'backup') -> $result6 + +--echo # Expression evaluation string functions tests completed successfully diff --git a/mysql-test/main/mysqltest_tracking_info.result b/mysql-test/main/mysqltest_tracking_info.result index 4266e845d3479..5b00f1eff5ef4 100644 --- a/mysql-test/main/mysqltest_tracking_info.result +++ b/mysql-test/main/mysqltest_tracking_info.result @@ -33,7 +33,7 @@ set @save_optimizer_switch=@@optimizer_switch; SET @@session.session_track_system_variables='optimizer_switch'; set optimizer_switch='index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off'; -- Tracker : SESSION_TRACK_SYSTEM_VARIABLES --- optimizer_switch: index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,duplicateweedout=on,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=on,sargable_casefold=on +-- optimizer_switch: index_merge=off,index_merge_union=off,index_merge_sort_union=off,index_merge_intersection=off,index_merge_sort_intersection=on,index_condition_pushdown=off,derived_merge=off,derived_with_keys=off,firstmatch=off,loosescan=off,duplicateweedout=on,materialization=on,in_to_exists=off,semijoin=off,partial_match_rowid_merge=off,partial_match_table_scan=off,subquery_cache=off,mrr=on,mrr_cost_based=on,mrr_sort_keys=on,outer_join_with_cache=off,semijoin_with_cache=off,join_cache_incremental=off,join_cache_hashed=off,join_cache_bka=off,optimize_join_buffer_size=on,table_elimination=off,extended_keys=off,exists_to_in=off,orderby_uses_equalities=off,condition_pushdown_for_derived=off,split_materialized=on,condition_pushdown_for_subquery=on,rowid_filter=on,condition_pushdown_from_having=on,not_null_range_scan=off,hash_join_cardinality=on,cset_narrowing=on,sargable_casefold=on,reorder_outer_joins=off set @@optimizer_switch=@save_optimizer_switch; SET @@session.session_track_system_variables= @save_session_track_system_variables; diff --git a/mysql-test/main/not_embedded_server.test b/mysql-test/main/not_embedded_server.test index 079c0c85bcd96..7e21735284c75 100644 --- a/mysql-test/main/not_embedded_server.test +++ b/mysql-test/main/not_embedded_server.test @@ -89,7 +89,6 @@ SELECT MAX(key1) INTO @dummy FROM t1 WHERE f() < 1; CREATE TABLE t3 (i INT) AS SELECT MAX(key1) FROM t1 WHERE f() < 1; disconnect con1; ---source include/wait_until_disconnected.inc connection default; diff --git a/mysql-test/main/null.result b/mysql-test/main/null.result index 15f6dfd2a36f7..0b8239509e55e 100644 --- a/mysql-test/main/null.result +++ b/mysql-test/main/null.result @@ -440,6 +440,9 @@ NOT NOT NULLIF(2,3) # # MDEV-7146 NULLIF returns unexpected result with a YEAR field # +set old_mode=2_DIGIT_YEAR; +Warnings: +Warning 1287 '2_DIGIT_YEAR' is deprecated and will be removed in a future release CREATE TABLE t1 (a YEAR(2)); Warnings: Warning 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use 'YEAR(4)' instead @@ -451,6 +454,7 @@ SELECT a,NULLIF(a,2001),NULLIF(2001,a) FROM t1; a NULLIF(a,2001) NULLIF(2001,a) 00 0 2001 DROP TABLE t1; +set old_mode=DEFAULT; # # MDEV-7005 NULLIF does not work as documented # diff --git a/mysql-test/main/null.test b/mysql-test/main/null.test index b7180d9d0a5f6..c4262683f653c 100644 --- a/mysql-test/main/null.test +++ b/mysql-test/main/null.test @@ -317,6 +317,7 @@ SELECT NOT NOT NULLIF(2,3); --echo # --echo # MDEV-7146 NULLIF returns unexpected result with a YEAR field --echo # +set old_mode=2_DIGIT_YEAR; --enable_prepare_warnings CREATE TABLE t1 (a YEAR(2)); --disable_prepare_warnings @@ -327,6 +328,7 @@ SELECT a,NULLIF(a,2000),NULLIF(2000,a) FROM t1; SELECT a,NULLIF(a,2001),NULLIF(2001,a) FROM t1; --enable_cursor_protocol DROP TABLE t1; +set old_mode=DEFAULT; --echo # --echo # MDEV-7005 NULLIF does not work as documented diff --git a/mysql-test/main/null_aware_cardinality.result b/mysql-test/main/null_aware_cardinality.result new file mode 100644 index 0000000000000..43aa6d05c1fc1 --- /dev/null +++ b/mysql-test/main/null_aware_cardinality.result @@ -0,0 +1,146 @@ +# Small driving table +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1, 1), (2, 2000),(3,300); +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 +# Table that will be accessed by an index lookup (`ref` access) +CREATE TABLE t2 (a INT, b INT, KEY key_b(b)); +# All t11.b values are NULL +INSERT INTO t2 SELECT seq/100, NULL FROM seq_1_to_1000; +ANALYZE TABLE t2 PERSISTENT FOR ALL; +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status Table is already up to date +# NULL-rejecting equality t1.b = t2.b will not return any matches +# because all values of t2.b are NULL. So "rows" = 1 for t2 where 1 is +# a special value meaning "very few" rows +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 1 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` +# However, rows estimation for not NULL-rejecting conditions +# must not be affected ("rows" > 1 is expected) +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b <=> t2.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 11 100.00 Using index condition; Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t2`.`b` +# Insert some non-NULL values and re-collect the stats +INSERT INTO t2 SELECT 1, 1 FROM seq_1_to_100; +ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (key_b); +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status OK +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t2 ref key_b key_b 5 test.t1.b 100 100.00 Using where +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t2`.`a` AS `a`,`test`.`t2`.`b` AS `b` from `test`.`t1` join `test`.`t2` where `test`.`t2`.`a` = `test`.`t1`.`a` and `test`.`t2`.`b` = `test`.`t1`.`b` +# Test composite index for two columns. Key prefix is used for access +CREATE TABLE t3 (a INT, b INT, KEY key_ab(a,b)); +# All t3.b values are NULL +INSERT INTO t3 SELECT seq/100, NULL FROM seq_1_to_1000; +ANALYZE TABLE t3 PERSISTENT FOR COLUMNS(b) INDEXES(key_ab); +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status Table is already up to date +# NULL-rejecting equality t1.b = t3.b, same as above. +# "rows" must be estimated to 1 +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 1 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` = `test`.`t1`.`b` +# Rows estimation for not NULL-rejecting conditions are not affected +# ("rows" > 1 is expected) +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ref key_ab key_ab 5 test.t1.a 90 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b <=> t3.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 11 100.00 Using where; Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t3`.`b` +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t3.b is NULL; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,const 11 100.00 Using where; Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` is null +# Insert some non-NULL values and re-collect the stats +INSERT INTO t3 SELECT 1, 1 FROM seq_1_to_100; +ANALYZE TABLE t3 PERSISTENT FOR COLUMNS (b) INDEXES (key_ab); +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t3 ref key_ab key_ab 10 test.t1.a,test.t1.b 100 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t3`.`a` AS `a`,`test`.`t3`.`b` AS `b` from `test`.`t1` join `test`.`t3` where `test`.`t3`.`a` = `test`.`t1`.`a` and `test`.`t3`.`b` = `test`.`t1`.`b` +# Test composite index for 3 columns. Key prefix is used for access +CREATE TABLE t4 (a INT, b INT, c INT, KEY key_abc(a,b,c)); +# All t3.b values are NULL +INSERT INTO t4 SELECT seq/10, NULL, seq/10 FROM seq_1_to_1000; +ANALYZE TABLE t4 PERSISTENT FOR COLUMNS(b) INDEXES(key_abc); +Table Op Msg_type Msg_text +test.t4 analyze status Engine-independent statistics collected +test.t4 analyze status Table is already up to date +# NULL-rejecting equality t1.b = t3.b, same as above. +# "rows" must be estimated to 1 +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t4 ref key_abc key_abc 10 test.t1.a,test.t1.b 1 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t4`.`b` = `test`.`t1`.`b` +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b and t1.b = t4.c; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t4 ref key_abc key_abc 15 test.t1.a,test.t1.b,test.t1.b 1 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t4`.`b` = `test`.`t1`.`b` and `test`.`t4`.`c` = `test`.`t1`.`b` +# "rows" expected to be > 1 +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t4 ref key_abc key_abc 5 test.t1.a 9 100.00 Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b <=> t4.c; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 3 100.00 Using where +1 SIMPLE t4 ref key_abc key_abc 5 test.t1.a 9 100.00 Using where; Using index +Warnings: +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t4`.`a` AS `a`,`test`.`t4`.`b` AS `b`,`test`.`t4`.`c` AS `c` from `test`.`t1` join `test`.`t4` where `test`.`t4`.`a` = `test`.`t1`.`a` and `test`.`t1`.`b` <=> `test`.`t4`.`c` +DROP TABLE t1, t2, t3, t4; +# Test for partially covered column +CREATE TABLE t1 (a VARCHAR(10)); +INSERT INTO t1 SELECT seq FROM seq_1_to_10; +CREATE TABLE t2 ( +a VARCHAR(10), +b VARCHAR(10), +INDEX i1(a, b(5)) +); +INSERT INTO t2 SELECT seq, NULL FROM seq_1_to_1000; +ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (i1); +Table Op Msg_type Msg_text +test.t2 analyze status Engine-independent statistics collected +test.t2 analyze status Table is already up to date +EXPLAIN SELECT * FROM t1, t2 WHERE t2.a=t1.a AND t2.b=t1.a; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where +1 SIMPLE t2 ref i1 i1 66 test.t1.a,test.t1.a 1 Using where +DROP TABLE t1, t2; diff --git a/mysql-test/main/null_aware_cardinality.test b/mysql-test/main/null_aware_cardinality.test new file mode 100644 index 0000000000000..716643a2297b0 --- /dev/null +++ b/mysql-test/main/null_aware_cardinality.test @@ -0,0 +1,93 @@ +--source include/have_sequence.inc + +--echo # Small driving table +CREATE TABLE t1 (a INT, b INT); +INSERT INTO t1 VALUES (1, 1), (2, 2000),(3,300); + +ANALYZE TABLE t1 PERSISTENT FOR ALL; + +--echo # Table that will be accessed by an index lookup (`ref` access) +CREATE TABLE t2 (a INT, b INT, KEY key_b(b)); +--echo # All t11.b values are NULL +INSERT INTO t2 SELECT seq/100, NULL FROM seq_1_to_1000; + +ANALYZE TABLE t2 PERSISTENT FOR ALL; + +--echo # NULL-rejecting equality t1.b = t2.b will not return any matches +--echo # because all values of t2.b are NULL. So "rows" = 1 for t2 where 1 is +--echo # a special value meaning "very few" rows +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; + +--echo # However, rows estimation for not NULL-rejecting conditions +--echo # must not be affected ("rows" > 1 is expected) +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b <=> t2.b; + +--echo # Insert some non-NULL values and re-collect the stats +INSERT INTO t2 SELECT 1, 1 FROM seq_1_to_100; + +ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (key_b); + +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t2 ON t1.a = t2.a AND t1.b = t2.b; + +--echo # Test composite index for two columns. Key prefix is used for access +CREATE TABLE t3 (a INT, b INT, KEY key_ab(a,b)); +--echo # All t3.b values are NULL +INSERT INTO t3 SELECT seq/100, NULL FROM seq_1_to_1000; + +ANALYZE TABLE t3 PERSISTENT FOR COLUMNS(b) INDEXES(key_ab); + +--echo # NULL-rejecting equality t1.b = t3.b, same as above. +--echo # "rows" must be estimated to 1 +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b; + +--echo # Rows estimation for not NULL-rejecting conditions are not affected +--echo # ("rows" > 1 is expected) +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a; + +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b <=> t3.b; + +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t3.b is NULL; + +--echo # Insert some non-NULL values and re-collect the stats +INSERT INTO t3 SELECT 1, 1 FROM seq_1_to_100; + +ANALYZE TABLE t3 PERSISTENT FOR COLUMNS (b) INDEXES (key_ab); + +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t3 ON t1.a = t3.a AND t1.b = t3.b; + +--echo # Test composite index for 3 columns. Key prefix is used for access +CREATE TABLE t4 (a INT, b INT, c INT, KEY key_abc(a,b,c)); + +--echo # All t3.b values are NULL +INSERT INTO t4 SELECT seq/10, NULL, seq/10 FROM seq_1_to_1000; + +ANALYZE TABLE t4 PERSISTENT FOR COLUMNS(b) INDEXES(key_abc); + +--echo # NULL-rejecting equality t1.b = t3.b, same as above. +--echo # "rows" must be estimated to 1 +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b; + +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b = t4.b and t1.b = t4.c; + +--echo # "rows" expected to be > 1 +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a; + +EXPLAIN EXTENDED SELECT * FROM t1 JOIN t4 ON t1.a = t4.a AND t1.b <=> t4.c; + +DROP TABLE t1, t2, t3, t4; + +--echo # Test for partially covered column +CREATE TABLE t1 (a VARCHAR(10)); +INSERT INTO t1 SELECT seq FROM seq_1_to_10; + +CREATE TABLE t2 ( + a VARCHAR(10), + b VARCHAR(10), + INDEX i1(a, b(5)) +); +INSERT INTO t2 SELECT seq, NULL FROM seq_1_to_1000; +ANALYZE TABLE t2 PERSISTENT FOR COLUMNS (b) INDEXES (i1); + +EXPLAIN SELECT * FROM t1, t2 WHERE t2.a=t1.a AND t2.b=t1.a; + +DROP TABLE t1, t2; \ No newline at end of file diff --git a/mysql-test/main/olap.result b/mysql-test/main/olap.result index 4c81f76432f25..b8aea1c7c2b96 100644 --- a/mysql-test/main/olap.result +++ b/mysql-test/main/olap.result @@ -905,5 +905,19 @@ f NULL NULL DROP TABLE t1; -# End of 10.3 Tests +# End of 10.3 tests +# +# MDEV-34984 rr_from_cache does not update generated columns +# +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048) GENERATED ALWAYS AS (i)); +INSERT INTO t1 (i) SELECT seq FROM seq_1_to_6000; +SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP limit 5; +MAX(c) +1 +10 +100 +1000 +1001 +DROP TABLE t1; +# End of 10.11 tests ALTER DATABASE test CHARACTER SET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci; diff --git a/mysql-test/main/olap.test b/mysql-test/main/olap.test index c6864d1751c0f..d6b3c41747f43 100644 --- a/mysql-test/main/olap.test +++ b/mysql-test/main/olap.test @@ -1,3 +1,4 @@ +--source include/have_sequence.inc --source include/test_db_charset_latin1.inc set @sav_dpi= @@div_precision_increment; @@ -534,6 +535,15 @@ SELECT NULLIF( CAST( 'foo' AS DATE ), NULL & 'bar' ) AS f FROM t1 GROUP BY f WIT --enable_warnings DROP TABLE t1; ---echo # End of 10.3 Tests +--echo # End of 10.3 tests + +--echo # +--echo # MDEV-34984 rr_from_cache does not update generated columns +--echo # +CREATE TABLE t1 (i INT DEFAULT 0, c VARCHAR(2048) GENERATED ALWAYS AS (i)); +INSERT INTO t1 (i) SELECT seq FROM seq_1_to_6000; +SELECT MAX(c) FROM t1 GROUP BY c WITH ROLLUP limit 5; +DROP TABLE t1; +--echo # End of 10.11 tests --source include/test_db_charset_restore.inc diff --git a/mysql-test/main/old-mode.opt b/mysql-test/main/old-mode.opt deleted file mode 100644 index 840ee0dedcffd..0000000000000 --- a/mysql-test/main/old-mode.opt +++ /dev/null @@ -1 +0,0 @@ ---old=1 diff --git a/mysql-test/main/old-mode.result b/mysql-test/main/old-mode.result index 9f911f8d17c56..fe5682260ebed 100644 --- a/mysql-test/main/old-mode.result +++ b/mysql-test/main/old-mode.result @@ -1,3 +1,6 @@ +set old_mode=COMPAT_5_1_CHECKSUM; +Warnings: +Warning 1287 'COMPAT_5_1_CHECKSUM' is deprecated and will be removed in a future release create table t1 (a int, b varchar(200), c text not null) checksum=1; create table t2 (a int, b varchar(200), c text not null) checksum=0; insert t1 values (1, "aaa", "bbb"), (NULL, "", "ccccc"), (0, NULL, ""); @@ -15,6 +18,9 @@ Table Checksum test.t1 2948697075 test.t2 2948697075 drop table t1,t2; +set old_mode=NO_PROGRESS_INFO; +Warnings: +Warning 1287 'NO_PROGRESS_INFO' is deprecated and will be removed in a future release SHOW PROCESSLIST; Id User Host db Command Time State Info root test Query