mirror of
https://github.com/MariaDB/server.git
synced 2025-04-15 03:35:31 +02:00

This patch also fixes: MDEV-33050 Build-in schemas like oracle_schema are accent insensitive MDEV-33084 LASTVAL(t1) and LASTVAL(T1) do not work well with lower-case-table-names=0 MDEV-33085 Tables T1 and t1 do not work well with ENGINE=CSV and lower-case-table-names=0 MDEV-33086 SHOW OPEN TABLES IN DB1 -- is case insensitive with lower-case-table-names=0 MDEV-33088 Cannot create triggers in the database `MYSQL` MDEV-33103 LOCK TABLE t1 AS t2 -- alias is not case sensitive with lower-case-table-names=0 MDEV-33109 DROP DATABASE MYSQL -- does not drop SP with lower-case-table-names=0 MDEV-33110 HANDLER commands are case insensitive with lower-case-table-names=0 MDEV-33119 User is case insensitive in INFORMATION_SCHEMA.VIEWS MDEV-33120 System log table names are case insensitive with lower-cast-table-names=0 - Removing the virtual function strnncoll() from MY_COLLATION_HANDLER - Adding a wrapper function CHARSET_INFO::streq(), to compare two strings for equality. For now it calls strnncoll() internally. In the future it will turn into a virtual function. - Adding new accent sensitive case insensitive collations: - utf8mb4_general1400_as_ci - utf8mb3_general1400_as_ci They implement accent sensitive case insensitive comparison. The weight of a character is equal to the code point of its upper case variant. These collations use Unicode-14.0.0 casefolding data. The result of my_charset_utf8mb3_general1400_as_ci.strcoll() is very close to the former my_charset_utf8mb3_general_ci.strcasecmp() There is only a difference in a couple dozen rare characters, because: - the switch from "tolower" to "toupper" comparison, to make utf8mb3_general1400_as_ci closer to utf8mb3_general_ci - the switch from Unicode-3.0.0 to Unicode-14.0.0 This difference should be tolarable. See the list of affected characters in the MDEV description. Note, utf8mb4_general1400_as_ci correctly handles non-BMP characters! Unlike utf8mb4_general_ci, it does not treat all BMP characters as equal. - Adding classes representing names of the file based database objects: Lex_ident_db Lex_ident_table Lex_ident_trigger Their comparison collation depends on the underlying file system case sensitivity and on --lower-case-table-names and can be either my_charset_bin or my_charset_utf8mb3_general1400_as_ci. - Adding classes representing names of other database objects, whose names have case insensitive comparison style, using my_charset_utf8mb3_general1400_as_ci: Lex_ident_column Lex_ident_sys_var Lex_ident_user_var Lex_ident_sp_var Lex_ident_ps Lex_ident_i_s_table Lex_ident_window Lex_ident_func Lex_ident_partition Lex_ident_with_element Lex_ident_rpl_filter Lex_ident_master_info Lex_ident_host Lex_ident_locale Lex_ident_plugin Lex_ident_engine Lex_ident_server Lex_ident_savepoint Lex_ident_charset engine_option_value::Name - All the mentioned Lex_ident_xxx classes implement a method streq(): if (ident1.streq(ident2)) do_equal(); This method works as a wrapper for CHARSET_INFO::streq(). - Changing a lot of "LEX_CSTRING name" to "Lex_ident_xxx name" in class members and in function/method parameters. - Replacing all calls like system_charset_info->coll->strcasecmp(ident1, ident2) to ident1.streq(ident2) - Taking advantage of the c++11 user defined literal operator for LEX_CSTRING (see m_strings.h) and Lex_ident_xxx (see lex_ident.h) data types. Use example: const Lex_ident_column primary_key_name= "PRIMARY"_Lex_ident_column; is now a shorter version of: const Lex_ident_column primary_key_name= Lex_ident_column({STRING_WITH_LEN("PRIMARY")});
226 lines
6.2 KiB
C++
226 lines
6.2 KiB
C++
/*****************************************************************************
|
|
|
|
Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
|
Copyright (c) 2017, 2021, MariaDB Corporation.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with
|
|
this program; if not, write to the Free Software Foundation, Inc.,
|
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file fsp/fsp0space.cc
|
|
Shared tablespace implementation.
|
|
|
|
Created 2012-11-16 by Sunny Bains as srv/srv0space.cc
|
|
*******************************************************/
|
|
|
|
#include "fsp0sysspace.h"
|
|
#include "fsp0fsp.h"
|
|
#include "os0file.h"
|
|
#include "my_sys.h"
|
|
#include "lex_ident.h"
|
|
|
|
/** Check if two tablespaces have common data file names.
|
|
@param other_space Tablespace to check against this.
|
|
@return true if they have the same data filenames and paths */
|
|
bool
|
|
Tablespace::intersection(
|
|
const Tablespace* other_space)
|
|
{
|
|
for (files_t::const_iterator it(other_space->begin()),
|
|
end(other_space->end()); it != end; ++it) {
|
|
|
|
if (find(it->m_filename)) {
|
|
|
|
return(true);
|
|
}
|
|
}
|
|
|
|
return(false);
|
|
}
|
|
|
|
/** Frees the memory allocated by the SysTablespace object. */
|
|
void
|
|
Tablespace::shutdown()
|
|
{
|
|
for (iterator it = begin(); it != end(); ++it) {
|
|
it->shutdown();
|
|
}
|
|
|
|
m_files.clear();
|
|
ut_free(m_path);
|
|
m_path = NULL;
|
|
m_space_id = UINT32_MAX;
|
|
}
|
|
|
|
/** Note that the data file was found.
|
|
@param[in,out] file Data file object to set */
|
|
void
|
|
Tablespace::file_found(Datafile& file)
|
|
{
|
|
/* Note that the file exists and can be opened
|
|
in the appropriate mode. */
|
|
file.m_exists = true;
|
|
|
|
file.set_open_flags(
|
|
&file == &m_files.front()
|
|
? OS_FILE_OPEN_RETRY : OS_FILE_OPEN);
|
|
}
|
|
|
|
/** Open or Create the data files if they do not exist.
|
|
@param[in] is_temp whether this is a temporary tablespace
|
|
@return DB_SUCCESS or error code */
|
|
dberr_t
|
|
Tablespace::open_or_create(bool is_temp)
|
|
{
|
|
fil_space_t* space = NULL;
|
|
dberr_t err = DB_SUCCESS;
|
|
|
|
ut_ad(!m_files.empty());
|
|
|
|
for (iterator it = begin(); it != end(); ++it) {
|
|
if (it->m_exists) {
|
|
err = it->open_or_create(
|
|
m_ignore_read_only
|
|
? false : srv_read_only_mode);
|
|
if (err != DB_SUCCESS) {
|
|
return err;
|
|
}
|
|
} else {
|
|
err = it->open_or_create(
|
|
m_ignore_read_only
|
|
? false : srv_read_only_mode);
|
|
|
|
if (err != DB_SUCCESS) {
|
|
return err;
|
|
}
|
|
|
|
/* Set the correct open flags now that we have
|
|
successfully created the file. */
|
|
file_found(*it);
|
|
}
|
|
|
|
/* We can close the handle now and open the tablespace
|
|
the proper way. */
|
|
it->close();
|
|
|
|
if (it == begin()) {
|
|
/* First data file. */
|
|
|
|
/* Create the tablespace entry for the multi-file
|
|
tablespace in the tablespace manager. */
|
|
uint32_t fsp_flags;
|
|
|
|
switch (srv_checksum_algorithm) {
|
|
case SRV_CHECKSUM_ALGORITHM_FULL_CRC32:
|
|
case SRV_CHECKSUM_ALGORITHM_STRICT_FULL_CRC32:
|
|
fsp_flags = (FSP_FLAGS_FCRC32_MASK_MARKER
|
|
| FSP_FLAGS_FCRC32_PAGE_SSIZE());
|
|
break;
|
|
default:
|
|
fsp_flags = FSP_FLAGS_PAGE_SSIZE();
|
|
}
|
|
|
|
mysql_mutex_lock(&fil_system.mutex);
|
|
space = fil_space_t::create(
|
|
m_space_id, fsp_flags,
|
|
is_temp
|
|
? FIL_TYPE_TEMPORARY : FIL_TYPE_TABLESPACE,
|
|
NULL);
|
|
if (!space) {
|
|
mysql_mutex_unlock(&fil_system.mutex);
|
|
return DB_ERROR;
|
|
}
|
|
} else {
|
|
mysql_mutex_lock(&fil_system.mutex);
|
|
}
|
|
space->add(it->m_filepath, OS_FILE_CLOSED, it->m_size,
|
|
false, true);
|
|
mysql_mutex_unlock(&fil_system.mutex);
|
|
}
|
|
|
|
return(err);
|
|
}
|
|
|
|
/** Find a filename in the list of Datafiles for a tablespace
|
|
@return true if the filename exists in the data files */
|
|
bool
|
|
Tablespace::find(const char* filename) const
|
|
{
|
|
const Lex_ident_column filename_ident = Lex_cstring_strlen(filename);
|
|
for (const_iterator it = begin(); it != end(); ++it) {
|
|
|
|
if (filename_ident.streq(Lex_cstring_strlen(it->m_filename))) {
|
|
return(true);
|
|
}
|
|
}
|
|
|
|
return(false);
|
|
}
|
|
|
|
/** Delete all the data files. */
|
|
void
|
|
Tablespace::delete_files()
|
|
{
|
|
for (iterator it = begin(); it != end(); ++it) {
|
|
|
|
it->close();
|
|
|
|
bool file_pre_exists;
|
|
bool success = os_file_delete_if_exists(
|
|
innodb_data_file_key, it->m_filepath, &file_pre_exists);
|
|
|
|
if (success && file_pre_exists) {
|
|
ib::info() << "Removed temporary tablespace data"
|
|
" file: \"" << it->m_filepath << "\"";
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Use the ADD DATAFILE path to create a Datafile object and add it to the
|
|
front of m_files.
|
|
Parse the datafile path into a path and a filename with extension 'ibd'.
|
|
This datafile_path provided may or may not be an absolute path, but it
|
|
must end with the extension .ibd and have a basename of at least 1 byte.
|
|
|
|
Set tablespace m_path member and add a Datafile with the filename.
|
|
@param[in] datafile_path full path of the tablespace file. */
|
|
dberr_t Tablespace::add_datafile(const char *filepath)
|
|
{
|
|
/* The path provided ends in ".ibd". This was assured by
|
|
validate_create_tablespace_info() */
|
|
ut_d(const char* dot = strrchr(filepath, '.'));
|
|
ut_ad(dot != NULL && 0 == strcmp(dot, DOT_IBD));
|
|
|
|
/* If the path is an absolute path, separate it onto m_path and a
|
|
basename. For relative paths, make the whole thing a basename so that
|
|
it can be appended to the datadir. */
|
|
bool is_abs_path = is_absolute_path(filepath);
|
|
size_t dirlen = (is_abs_path ? dirname_length(filepath) : 0);
|
|
const char* basename = filepath + dirlen;
|
|
|
|
/* If the pathname contains a directory separator, fill the
|
|
m_path member which is the default directory for files in this
|
|
tablespace. Leave it null otherwise. */
|
|
if (dirlen > 0) {
|
|
set_path(filepath, dirlen);
|
|
}
|
|
|
|
/* Now add a new Datafile and set the filepath
|
|
using the m_path created above. */
|
|
m_files.push_back(Datafile(m_flags, FIL_IBD_FILE_INITIAL_SIZE, 0));
|
|
m_files.back().make_filepath(m_path, {basename, strlen(basename) - 4},
|
|
IBD);
|
|
|
|
return(DB_SUCCESS);
|
|
}
|