@@ -214,36 +214,14 @@ const char *ha_myisammrg::index_type(uint key_number)
214
214
static int myisammrg_parent_open_callback (void *callback_param,
215
215
const char *filename)
216
216
{
217
- ha_myisammrg *ha_myrg;
218
- TABLE *parent;
217
+ ha_myisammrg *ha_myrg= (ha_myisammrg*) callback_param ;
218
+ TABLE *parent= ha_myrg-> table_ptr () ;
219
219
TABLE_LIST *child_l;
220
- const char *db;
221
- const char *table_name;
222
220
size_t dirlen;
223
221
char dir_path[FN_REFLEN];
222
+ char name_buf[NAME_LEN];
224
223
DBUG_ENTER (" myisammrg_parent_open_callback" );
225
224
226
- /* Extract child table name and database name from filename. */
227
- dirlen= dirname_length (filename);
228
- if (dirlen >= FN_REFLEN)
229
- {
230
- /* purecov: begin inspected */
231
- DBUG_PRINT (" error" , (" name too long: '%.64s'" , filename));
232
- my_errno= ENAMETOOLONG;
233
- DBUG_RETURN (1 );
234
- /* purecov: end */
235
- }
236
- table_name= filename + dirlen;
237
- dirlen--; /* Strip off trailing '/'. */
238
- memcpy (dir_path, filename, dirlen);
239
- dir_path[dirlen]= ' \0 ' ;
240
- db= base_name (dir_path);
241
- dirlen-= db - dir_path; /* This is now the length of 'db'. */
242
- DBUG_PRINT (" myrg" , (" open: '%s'.'%s'" , db, table_name));
243
-
244
- ha_myrg= (ha_myisammrg*) callback_param;
245
- parent= ha_myrg->table_ptr ();
246
-
247
225
/* Get a TABLE_LIST object. */
248
226
if (!(child_l= (TABLE_LIST*) alloc_root (&parent->mem_root ,
249
227
sizeof (TABLE_LIST))))
@@ -255,13 +233,69 @@ static int myisammrg_parent_open_callback(void *callback_param,
255
233
}
256
234
bzero ((char *) child_l, sizeof (TABLE_LIST));
257
235
258
- /* Set database (schema) name. */
259
- child_l->db_length = dirlen;
260
- child_l->db = strmake_root (&parent->mem_root , db, dirlen);
261
- /* Set table name. */
262
- child_l->table_name_length = strlen (table_name);
263
- child_l->table_name = strmake_root (&parent->mem_root , table_name,
264
- child_l->table_name_length );
236
+ /*
237
+ Depending on MySQL version, filename may be encoded by table name to
238
+ file name encoding or not. Always encoded if parent table is created
239
+ by 5.1.46+. Encoded if parent is created by 5.1.6+ and child table is
240
+ in different database.
241
+ */
242
+ if (!has_path (filename))
243
+ {
244
+ /* Child is in the same database as parent. */
245
+ child_l->db_length = parent->s ->db .length ;
246
+ child_l->db = strmake_root (&parent->mem_root , parent->s ->db .str ,
247
+ child_l->db_length );
248
+ /* Child table name is encoded in parent dot-MRG starting with 5.1.46. */
249
+ if (parent->s ->mysql_version >= 50146 )
250
+ {
251
+ child_l->table_name_length = filename_to_tablename (filename, name_buf,
252
+ sizeof (name_buf));
253
+ child_l->table_name = strmake_root (&parent->mem_root , name_buf,
254
+ child_l->table_name_length );
255
+ }
256
+ else
257
+ {
258
+ child_l->table_name_length = strlen (filename);
259
+ child_l->table_name = strmake_root (&parent->mem_root , filename,
260
+ child_l->table_name_length );
261
+ }
262
+ }
263
+ else
264
+ {
265
+ DBUG_ASSERT (strlen (filename) < sizeof (dir_path));
266
+ fn_format (dir_path, filename, " " , " " , 0 );
267
+ /* Extract child table name and database name from filename. */
268
+ dirlen= dirname_length (dir_path);
269
+ /* Child db/table name is encoded in parent dot-MRG starting with 5.1.6. */
270
+ if (parent->s ->mysql_version >= 50106 )
271
+ {
272
+ child_l->table_name_length = filename_to_tablename (dir_path + dirlen,
273
+ name_buf,
274
+ sizeof (name_buf));
275
+ child_l->table_name = strmake_root (&parent->mem_root , name_buf,
276
+ child_l->table_name_length );
277
+ dir_path[dirlen - 1 ]= 0 ;
278
+ dirlen= dirname_length (dir_path);
279
+ child_l->db_length = filename_to_tablename (dir_path + dirlen, name_buf,
280
+ sizeof (name_buf));
281
+ child_l->db = strmake_root (&parent->mem_root , name_buf, child_l->db_length );
282
+ }
283
+ else
284
+ {
285
+ child_l->table_name_length = strlen (dir_path + dirlen);
286
+ child_l->table_name = strmake_root (&parent->mem_root , dir_path + dirlen,
287
+ child_l->table_name_length );
288
+ dir_path[dirlen - 1 ]= 0 ;
289
+ dirlen= dirname_length (dir_path);
290
+ child_l->db_length = strlen (dir_path + dirlen);
291
+ child_l->db = strmake_root (&parent->mem_root , dir_path + dirlen,
292
+ child_l->db_length );
293
+ }
294
+ }
295
+
296
+ DBUG_PRINT (" myrg" , (" open: '%.*s'.'%.*s'" , child_l->db_length , child_l->db ,
297
+ child_l->table_name_length , child_l->table_name ));
298
+
265
299
/* Convert to lowercase if required. */
266
300
if (lower_case_table_names && child_l->table_name_length )
267
301
child_l->table_name_length = my_casedn_str (files_charset_info,
@@ -1132,7 +1166,7 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
1132
1166
/* Create child path names. */
1133
1167
for (pos= table_names; tables; tables= tables->next_local )
1134
1168
{
1135
- const char *table_name;
1169
+ const char *table_name= buff ;
1136
1170
1137
1171
/*
1138
1172
Construct the path to the MyISAM table. Try to meet two conditions:
@@ -1158,10 +1192,12 @@ int ha_myisammrg::create(const char *name, register TABLE *form,
1158
1192
as the MyISAM tables are from the same database as the MERGE table.
1159
1193
*/
1160
1194
if ((dirname_length (buff) == dirlgt) && ! memcmp (buff, name, dirlgt))
1161
- table_name= tables->table_name ;
1162
- else
1163
- if (! (table_name= thd->strmake (buff, length)))
1164
- DBUG_RETURN (HA_ERR_OUT_OF_MEM); /* purecov: inspected */
1195
+ {
1196
+ table_name+= dirlgt;
1197
+ length-= dirlgt;
1198
+ }
1199
+ if (!(table_name= thd->strmake (table_name, length)))
1200
+ DBUG_RETURN (HA_ERR_OUT_OF_MEM); /* purecov: inspected */
1165
1201
1166
1202
*pos++= table_name;
1167
1203
}
@@ -1182,7 +1218,7 @@ void ha_myisammrg::append_create_info(String *packet)
1182
1218
const char *current_db;
1183
1219
size_t db_length;
1184
1220
THD *thd= current_thd;
1185
- MYRG_TABLE *open_table, *first;
1221
+ TABLE_LIST *open_table, *first;
1186
1222
1187
1223
if (file->merge_insert_method != MERGE_INSERT_DISABLED)
1188
1224
{
@@ -1200,14 +1236,11 @@ void ha_myisammrg::append_create_info(String *packet)
1200
1236
current_db= table->s ->db .str ;
1201
1237
db_length= table->s ->db .length ;
1202
1238
1203
- for (first=open_table=file->open_tables ;
1204
- open_table != file->end_table ;
1205
- open_table++)
1239
+ for (first= open_table= table->child_l ;;
1240
+ open_table= open_table->next_global )
1206
1241
{
1207
- LEX_STRING db, name;
1208
- LINT_INIT (db.str );
1242
+ LEX_STRING db= { open_table->db , open_table->db_length };
1209
1243
1210
- split_file_name (open_table->table ->filename , &db, &name);
1211
1244
if (open_table != first)
1212
1245
packet->append (' ,' );
1213
1246
/* Report database for mapped table if it isn't in current database */
@@ -1218,7 +1251,10 @@ void ha_myisammrg::append_create_info(String *packet)
1218
1251
append_identifier (thd, packet, db.str , db.length );
1219
1252
packet->append (' .' );
1220
1253
}
1221
- append_identifier (thd, packet, name.str , name.length );
1254
+ append_identifier (thd, packet, open_table->table_name ,
1255
+ open_table->table_name_length );
1256
+ if (&open_table->next_global == table->child_last_l )
1257
+ break ;
1222
1258
}
1223
1259
packet->append (' )' );
1224
1260
}
0 commit comments