1/***************************************************************************** 2 3Copyright (c) 1996, 2019, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify it under 6the terms of the GNU General Public License, version 2.0, as published by the 7Free Software Foundation. 8 9This program is also distributed with certain software (including but not 10limited to OpenSSL) that is licensed under separate terms, as designated in a 11particular file or component or in included license documentation. The authors 12of MySQL hereby grant you an additional permission to link the program and 13your derivative works with the separately licensed software that they have 14included with MySQL. 15 16This program is distributed in the hope that it will be useful, but WITHOUT 17ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 18FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0, 19for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 25*****************************************************************************/ 26 27/** @file include/dict0crea.ic 28 Database object creation 29 30 Created 1/8/1996 Heikki Tuuri 31 *******************************************************/ 32 33#include "ha_prototypes.h" 34 35#include "mem0mem.h" 36 37/** Checks if a table name contains the string "/#sql" which denotes temporary 38 tables in MySQL. 39 @return true if temporary table */ 40bool row_is_mysql_tmp_table_name(const char *name) 41 MY_ATTRIBUTE((warn_unused_result)); 42/*!< in: table name in the form 43'database/tablename' */ 44 45/** Generate a foreign key constraint name when it was not named by the user. 46 A generated constraint has a name of the format dbname/tablename_ibfk_NUMBER, 47 where the numbers start from 1, and are given locally for this table, that is, 48 the number is not global, as it used to be before MySQL 4.0.18. */ 49UNIV_INLINE 50dberr_t dict_create_add_foreign_id( 51 ulint *id_nr, /*!< in/out: number to use in id generation; 52 incremented if used */ 53 const char *name, /*!< in: table name */ 54 dict_foreign_t *foreign) /*!< in/out: foreign key */ 55{ 56 DBUG_TRACE; 57 58 if (foreign->id == nullptr) { 59 /* Generate a new constraint id */ 60 ulint namelen = strlen(name); 61 char *id = static_cast<char *>(mem_heap_alloc(foreign->heap, namelen + 20)); 62 63 if (row_is_mysql_tmp_table_name(name)) { 64 /* no overflow if number < 1e13 */ 65 sprintf(id, "%s_ibfk_%lu", name, (ulong)(*id_nr)++); 66 } else { 67 char table_name[MAX_TABLE_NAME_LEN + 20 + 1] = ""; 68 uint errors = 0; 69 70 strncpy(table_name, name, MAX_TABLE_NAME_LEN + 20); 71 72 innobase_convert_to_system_charset(strchr(table_name, '/') + 1, 73 strchr(name, '/') + 1, 74 MAX_TABLE_NAME_LEN, &errors); 75 76 if (errors) { 77 strncpy(table_name, name, MAX_TABLE_NAME_LEN + 20); 78 } 79 80 /* no overflow if number < 1e13 */ 81 sprintf(id, "%s_ibfk_%lu", table_name, (ulong)(*id_nr)++); 82 83 if (innobase_check_identifier_length(strchr(id, '/') + 1)) { 84 /* Server has already done this check, 85 So assert here */ 86 ut_ad(0); 87 return DB_IDENTIFIER_TOO_LONG; 88 } 89 } 90 foreign->id = id; 91 92 DBUG_PRINT("dict_create_add_foreign_id", ("generated foreign id: %s", id)); 93 } 94 95 return DB_SUCCESS; 96} 97 98/** Compose a column number for a virtual column, stored in the "POS" field 99of Sys_columns. The column number includes both its virtual column sequence 100(the "nth" virtual column) and its actual column position in original table 101@param[in] v_pos virtual column sequence 102@param[in] col_pos column position in original table definition 103@return composed column position number */ 104UNIV_INLINE 105ulint dict_create_v_col_pos(ulint v_pos, ulint col_pos) { 106 ut_ad(v_pos <= REC_MAX_N_FIELDS); 107 ut_ad(col_pos <= REC_MAX_N_FIELDS); 108 109 return (((v_pos + 1) << 16) + col_pos); 110} 111 112/** Get the column number for a virtual column (the column position in 113original table), stored in the "POS" field of Sys_columns 114@param[in] pos virtual column position 115@return column position in original table */ 116UNIV_INLINE 117ulint dict_get_v_col_mysql_pos(ulint pos) { return (pos & 0xFFFF); } 118 119/** Get a virtual column sequence (the "nth" virtual column) for a 120virtual column, stord in the "POS" field of Sys_columns 121@param[in] pos virtual column position 122@return virtual column sequence */ 123UNIV_INLINE 124ulint dict_get_v_col_pos(ulint pos) { return ((pos >> 16) - 1); } 125