1 /* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved. 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License, version 2.0, 5 as published by the Free Software Foundation. 6 7 This program is also distributed with certain software (including 8 but not limited to OpenSSL) that is licensed under separate terms, 9 as designated in a particular file or component or in included license 10 documentation. The authors of MySQL hereby grant you an additional 11 permission to link the program and your derivative works with the 12 separately licensed software that they have included with MySQL. 13 14 This program is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License, version 2.0, for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with this program; if not, write to the Free Software 21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ 22 23 #ifndef DD__OBJECT_TABLE_DEFINITION_IMPL_INCLUDED 24 #define DD__OBJECT_TABLE_DEFINITION_IMPL_INCLUDED 25 26 #include <map> 27 #include <memory> 28 #include <vector> 29 30 #include "my_dbug.h" 31 #include "sql/dd/string_type.h" // dd::String_type 32 #include "sql/dd/types/object_table_definition.h" // dd::Object_table_definition 33 #include "sql/mysqld.h" // lower_case_table_names 34 35 namespace dd { 36 37 class Properties; 38 39 /////////////////////////////////////////////////////////////////////////// 40 41 class Object_table_definition_impl : public Object_table_definition { 42 public: 43 typedef std::map<String_type, int> Element_numbers; 44 typedef std::map<int, String_type> Element_definitions; 45 46 private: 47 enum class Label { 48 NAME, 49 FIELDS, 50 INDEXES, 51 FOREIGN_KEYS, 52 OPTIONS, 53 LABEL, 54 POSITION, 55 DEFINITION, 56 ELEMENT 57 }; 58 key(Label label)59 static const char *key(Label label) { 60 switch (label) { 61 case Label::NAME: 62 return "name"; 63 case Label::FIELDS: 64 return "fields"; 65 case Label::INDEXES: 66 return "indexes"; 67 case Label::FOREIGN_KEYS: 68 return "foreign_keys"; 69 case Label::OPTIONS: 70 return "options"; 71 case Label::LABEL: 72 return "lbl"; 73 case Label::POSITION: 74 return "pos"; 75 case Label::DEFINITION: 76 return "def"; 77 case Label::ELEMENT: 78 return "elem"; 79 default: 80 DBUG_ASSERT(false); 81 return ""; 82 } 83 } 84 85 static bool s_dd_tablespace_encrypted; 86 87 String_type m_schema_name; 88 String_type m_table_name; 89 90 String_type m_ddl_statement; 91 92 Element_numbers m_field_numbers; 93 Element_definitions m_field_definitions; 94 95 Element_numbers m_index_numbers; 96 Element_definitions m_index_definitions; 97 98 Element_numbers m_foreign_key_numbers; 99 Element_definitions m_foreign_key_definitions; 100 101 Element_numbers m_option_numbers; 102 Element_definitions m_option_definitions; 103 104 std::vector<String_type> m_dml_statements; 105 add_element(int element_number,const String_type & element_name,const String_type & element_definition,Element_numbers * element_numbers,Element_definitions * element_definitions)106 void add_element(int element_number, const String_type &element_name, 107 const String_type &element_definition, 108 Element_numbers *element_numbers, 109 Element_definitions *element_definitions) { 110 DBUG_ASSERT(element_numbers != nullptr && element_definitions != nullptr && 111 element_numbers->find(element_name) == element_numbers->end() && 112 element_definitions->find(element_number) == 113 element_definitions->end()); 114 115 (*element_numbers)[element_name] = element_number; 116 (*element_definitions)[element_number] = element_definition; 117 } 118 element_number(const String_type & element_name,const Element_numbers & element_numbers)119 int element_number(const String_type &element_name, 120 const Element_numbers &element_numbers) const { 121 DBUG_ASSERT(element_numbers.find(element_name) != element_numbers.end()); 122 return element_numbers.find(element_name)->second; 123 } 124 125 void get_element_properties(dd::Properties *properties, 126 const Element_numbers &element_numbers, 127 const Element_definitions &element_defs) const; 128 129 bool set_element_properties(const String_type &prop_str, 130 Element_numbers *element_numbers, 131 Element_definitions *element_defs); 132 133 public: Object_table_definition_impl()134 Object_table_definition_impl() {} 135 Object_table_definition_impl(const String_type & schema_name,const String_type & table_name,const String_type & ddl_statement)136 Object_table_definition_impl(const String_type &schema_name, 137 const String_type &table_name, 138 const String_type &ddl_statement) 139 : m_schema_name(schema_name), 140 m_table_name(table_name), 141 m_ddl_statement(ddl_statement) {} 142 ~Object_table_definition_impl()143 virtual ~Object_table_definition_impl() {} 144 set_dd_tablespace_encrypted(bool is_encrypted)145 static void set_dd_tablespace_encrypted(bool is_encrypted) { 146 s_dd_tablespace_encrypted = is_encrypted; 147 } 148 is_dd_tablespace_encrypted()149 static bool is_dd_tablespace_encrypted() { return s_dd_tablespace_encrypted; } 150 151 /** 152 Get the collation which is used for names related to the file 153 system (e.g. a schema name or table name). This collation is 154 case sensitive or not, depending on the setting of lower_case- 155 table_names. 156 157 @return Pointer to CHARSET_INFO. 158 */ 159 fs_name_collation()160 static const CHARSET_INFO *fs_name_collation() { 161 if (lower_case_table_names == 0) return &my_charset_utf8_bin; 162 return &my_charset_utf8_tolower_ci; 163 } 164 165 /** 166 Get the collation which is used for the name field in the table. 167 Table collation UTF8_BIN is used when collation for the name field 168 is not specified. Tables using different collation must override this 169 method. 170 171 TODO: Changing table collation is not supporting during upgrade as of now. 172 To support this, static definition of this method should be avoided 173 and should provide a possibility to have different collations for 174 actual and target table definition. 175 176 @return Pointer to CHARSET_INFO. 177 */ name_collation()178 static const CHARSET_INFO *name_collation() { return &my_charset_utf8_bin; } 179 180 /** 181 Convert to lowercase if lower_case_table_names == 2. This is needed 182 e.g when reconstructing name keys from a dictionary object in order 183 to remove the object. 184 185 @param src String to possibly convert to lowercase. 186 @param [in,out] buf Buffer for storing lowercase'd string. Supplied 187 by the caller. 188 189 @retval A pointer to the src string if l_c_t_n != 2 190 @retval A pointer to the buf supplied by the caller, into which 191 the src string has been copied and lowercase'd, if l_c_t_n == 2 192 */ 193 fs_name_case(const String_type & src,char * buf)194 static const char *fs_name_case(const String_type &src, char *buf) { 195 const char *tmp_name = src.c_str(); 196 if (lower_case_table_names == 2) { 197 // Lower case table names == 2 is tested on OSX. 198 /* purecov: begin tested */ 199 my_stpcpy(buf, tmp_name); 200 my_casedn_str(fs_name_collation(), buf); 201 tmp_name = buf; 202 /* purecov: end */ 203 } 204 return tmp_name; 205 } 206 get_table_name()207 const String_type &get_table_name() const { return m_table_name; } 208 set_table_name(const String_type & name)209 void set_table_name(const String_type &name) { m_table_name = name; } 210 set_schema_name(const String_type & name)211 void set_schema_name(const String_type &name) { m_schema_name = name; } 212 add_field(int field_number,const String_type & field_name,const String_type field_definition)213 void add_field(int field_number, const String_type &field_name, 214 const String_type field_definition) { 215 add_element(field_number, field_name, field_definition, &m_field_numbers, 216 &m_field_definitions); 217 } 218 219 void add_sql_mode_field(int field_number, const String_type &field_name); 220 add_index(int index_number,const String_type & index_name,const String_type & index_definition)221 virtual void add_index(int index_number, const String_type &index_name, 222 const String_type &index_definition) { 223 add_element(index_number, index_name, index_definition, &m_index_numbers, 224 &m_index_definitions); 225 } 226 add_foreign_key(int foreign_key_number,const String_type & foreign_key_name,const String_type & foreign_key_definition)227 virtual void add_foreign_key(int foreign_key_number, 228 const String_type &foreign_key_name, 229 const String_type &foreign_key_definition) { 230 add_element(foreign_key_number, foreign_key_name, foreign_key_definition, 231 &m_foreign_key_numbers, &m_foreign_key_definitions); 232 } 233 add_option(int option_number,const String_type & option_name,const String_type & option_definition)234 virtual void add_option(int option_number, const String_type &option_name, 235 const String_type &option_definition) { 236 add_element(option_number, option_name, option_definition, 237 &m_option_numbers, &m_option_definitions); 238 } 239 add_populate_statement(const String_type & statement)240 virtual void add_populate_statement(const String_type &statement) { 241 m_dml_statements.push_back(statement); 242 } 243 field_number(const String_type & field_name)244 virtual int field_number(const String_type &field_name) const { 245 return element_number(field_name, m_field_numbers); 246 } 247 index_number(const String_type & index_name)248 virtual int index_number(const String_type &index_name) const { 249 return element_number(index_name, m_index_numbers); 250 } 251 option_number(const String_type & option_name)252 virtual int option_number(const String_type &option_name) const { 253 return element_number(option_name, m_option_numbers); 254 } 255 256 virtual String_type get_ddl() const; 257 get_dml()258 virtual const std::vector<String_type> &get_dml() const { 259 return m_dml_statements; 260 } 261 262 virtual void store_into_properties(Properties *table_def_properties) const; 263 restore_from_string(const String_type & ddl_statement)264 virtual bool restore_from_string(const String_type &ddl_statement) { 265 m_ddl_statement = ddl_statement; 266 return false; 267 } 268 269 virtual bool restore_from_properties(const Properties &table_def_properties); 270 }; 271 272 /////////////////////////////////////////////////////////////////////////// 273 274 } // namespace dd 275 276 #endif // DD__OBJECT_TABLE_DEFINITION_IMPL_INCLUDED 277