@@ -368,6 +368,7 @@ void ha_partition::init_handler_variables()
368
368
part_share= NULL ;
369
369
m_new_partitions_share_refs.empty ();
370
370
m_part_ids_sorted_by_num_of_records= NULL ;
371
+ m_partitions_to_open= NULL ;
371
372
372
373
m_range_info= NULL ;
373
374
m_mrr_full_buffer_size= 0 ;
@@ -389,6 +390,7 @@ void ha_partition::init_handler_variables()
389
390
my_bitmap_clear (&m_partitions_to_reset);
390
391
my_bitmap_clear (&m_key_not_found_partitions);
391
392
my_bitmap_clear (&m_mrr_used_partitions);
393
+ my_bitmap_clear (&m_opened_partitions);
392
394
393
395
#ifdef DONT_HAVE_TO_BE_INITALIZED
394
396
m_start_key.flag = 0 ;
@@ -3360,6 +3362,7 @@ void ha_partition::free_partition_bitmaps()
3360
3362
my_bitmap_free (&m_locked_partitions);
3361
3363
my_bitmap_free (&m_partitions_to_reset);
3362
3364
my_bitmap_free (&m_key_not_found_partitions);
3365
+ my_bitmap_free (&m_opened_partitions);
3363
3366
my_bitmap_free (&m_mrr_used_partitions);
3364
3367
}
3365
3368
@@ -3401,6 +3404,9 @@ bool ha_partition::init_partition_bitmaps()
3401
3404
if (bitmap_init (&m_mrr_used_partitions, NULL , m_tot_parts, TRUE ))
3402
3405
DBUG_RETURN (true );
3403
3406
3407
+ if (my_bitmap_init (&m_opened_partitions, NULL , m_tot_parts, FALSE ))
3408
+ DBUG_RETURN (true );
3409
+
3404
3410
/* Initialize the bitmap for read/lock_partitions */
3405
3411
if (!m_is_clone_of)
3406
3412
{
@@ -3437,8 +3443,8 @@ bool ha_partition::init_partition_bitmaps()
3437
3443
3438
3444
int ha_partition::open (const char *name, int mode, uint test_if_locked)
3439
3445
{
3440
- char *name_buffer_ptr;
3441
3446
int error= HA_ERR_INITIALIZATION;
3447
+ handler *file_sample= NULL ;
3442
3448
handler **file;
3443
3449
char name_buff[FN_REFLEN + 1 ];
3444
3450
ulonglong check_table_flags;
@@ -3451,7 +3457,6 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3451
3457
m_part_field_array= m_part_info->full_part_field_array ;
3452
3458
if (get_from_handler_file (name, &table->mem_root , MY_TEST (m_is_clone_of)))
3453
3459
DBUG_RETURN (error);
3454
- name_buffer_ptr= m_name_buffer_ptr;
3455
3460
if (populate_partition_name_hash ())
3456
3461
{
3457
3462
DBUG_RETURN (HA_ERR_INITIALIZATION);
@@ -3473,6 +3478,9 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3473
3478
if (init_partition_bitmaps ())
3474
3479
goto err_alloc;
3475
3480
3481
+ if ((error= m_part_info->set_partition_bitmaps (m_partitions_to_open)))
3482
+ goto err_alloc;
3483
+
3476
3484
/* Allocate memory used with MMR */
3477
3485
if (!(m_range_info= (void **)
3478
3486
my_multi_malloc (MYF (MY_WME),
@@ -3498,6 +3506,7 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3498
3506
if (m_is_clone_of)
3499
3507
{
3500
3508
uint i, alloc_len;
3509
+ char *name_buffer_ptr;
3501
3510
DBUG_ASSERT (m_clone_mem_root);
3502
3511
/* Allocate an array of handler pointers for the partitions handlers. */
3503
3512
alloc_len= (m_tot_parts + 1 ) * sizeof (handler*);
@@ -3507,13 +3516,17 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3507
3516
goto err_alloc;
3508
3517
}
3509
3518
memset (m_file, 0 , alloc_len);
3519
+ name_buffer_ptr= m_name_buffer_ptr;
3510
3520
/*
3511
3521
Populate them by cloning the original partitions. This also opens them.
3512
3522
Note that file->ref is allocated too.
3513
3523
*/
3514
3524
file= m_is_clone_of->m_file ;
3515
3525
for (i= 0 ; i < m_tot_parts; i++)
3516
3526
{
3527
+ if (!bitmap_is_set (&m_is_clone_of->m_opened_partitions , i))
3528
+ continue ;
3529
+
3517
3530
if ((error= create_partition_name (name_buff, sizeof (name_buff), name,
3518
3531
name_buffer_ptr, NORMAL_PART_NAME, FALSE )))
3519
3532
goto err_handler;
@@ -3524,30 +3537,18 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3524
3537
file= &m_file[i];
3525
3538
goto err_handler;
3526
3539
}
3540
+ if (!file_sample)
3541
+ file_sample= m_file[i];
3527
3542
name_buffer_ptr+= strlen (name_buffer_ptr) + 1 ;
3543
+ bitmap_set_bit (&m_opened_partitions, i);
3528
3544
}
3529
3545
}
3530
3546
else
3531
3547
{
3532
- file= m_file;
3533
- do
3534
- {
3535
- LEX_CSTRING save_connect_string= table->s ->connect_string ;
3536
- if ((error= create_partition_name (name_buff, sizeof (name_buff), name,
3537
- name_buffer_ptr, NORMAL_PART_NAME, FALSE )))
3538
- goto err_handler;
3539
- if (!((*file)->ht ->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
3540
- table->s ->connect_string = m_connect_string[(uint)(file-m_file)];
3541
- error= (*file)->ha_open (table, name_buff, mode,
3542
- test_if_locked | HA_OPEN_NO_PSI_CALL);
3543
- table->s ->connect_string = save_connect_string;
3544
- if (error)
3545
- goto err_handler;
3546
- if (m_file == file)
3547
- m_num_locks= (*file)->lock_count ();
3548
- DBUG_ASSERT (m_num_locks == (*file)->lock_count ());
3549
- name_buffer_ptr+= strlen (name_buffer_ptr) + 1 ;
3550
- } while (*(++file));
3548
+ if ((error= open_read_partitions (name_buff, sizeof (name_buff),
3549
+ &file_sample)))
3550
+ goto err_handler;
3551
+ m_num_locks= file_sample->lock_count ();
3551
3552
}
3552
3553
/*
3553
3554
We want to know the upper bound for locks, to allocate enough memory.
@@ -3558,12 +3559,14 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3558
3559
m_num_locks*= m_tot_parts;
3559
3560
3560
3561
file= m_file;
3561
- ref_length= (*file) ->ref_length ;
3562
- check_table_flags= (((*file) ->ha_table_flags () &
3562
+ ref_length= file_sample ->ref_length ;
3563
+ check_table_flags= ((file_sample ->ha_table_flags () &
3563
3564
~(PARTITION_DISABLED_TABLE_FLAGS)) |
3564
3565
(PARTITION_ENABLED_TABLE_FLAGS));
3565
3566
while (*(++file))
3566
3567
{
3568
+ if (!bitmap_is_set (&m_opened_partitions, file - m_file))
3569
+ continue ;
3567
3570
/* MyISAM can have smaller ref_length for partitions with MAX_ROWS set */
3568
3571
set_if_bigger (ref_length, ((*file)->ref_length ));
3569
3572
/*
@@ -3580,8 +3583,8 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3580
3583
goto err_handler;
3581
3584
}
3582
3585
}
3583
- key_used_on_scan= m_file[ 0 ] ->key_used_on_scan ;
3584
- implicit_emptied= m_file[ 0 ] ->implicit_emptied ;
3586
+ key_used_on_scan= file_sample ->key_used_on_scan ;
3587
+ implicit_emptied= file_sample ->implicit_emptied ;
3585
3588
/*
3586
3589
Add 2 bytes for partition id in position ref length.
3587
3590
ref_length=max_in_all_partitions(ref_length) + PARTITION_BYTES_IN_POS
@@ -3612,8 +3615,12 @@ int ha_partition::open(const char *name, int mode, uint test_if_locked)
3612
3615
3613
3616
err_handler:
3614
3617
DEBUG_SYNC (ha_thd (), " partition_open_error" );
3618
+ file= &m_file[m_tot_parts - 1 ];
3615
3619
while (file-- != m_file)
3616
- (*file)->ha_close ();
3620
+ {
3621
+ if (bitmap_is_set (&m_opened_partitions, file - m_file))
3622
+ (*file)->ha_close ();
3623
+ }
3617
3624
err_alloc:
3618
3625
free_partition_bitmaps ();
3619
3626
my_free (m_range_info);
@@ -3744,7 +3751,6 @@ int ha_partition::close(void)
3744
3751
DBUG_ASSERT (m_part_info);
3745
3752
3746
3753
destroy_record_priority_queue ();
3747
- free_partition_bitmaps ();
3748
3754
3749
3755
for (; ft_first ; ft_first= tmp_ft_info)
3750
3756
{
@@ -3795,9 +3801,12 @@ int ha_partition::close(void)
3795
3801
repeat:
3796
3802
do
3797
3803
{
3798
- (*file)->ha_close ();
3804
+ if (!first || bitmap_is_set (&m_opened_partitions, file - m_file))
3805
+ (*file)->ha_close ();
3799
3806
} while (*(++file));
3800
3807
3808
+ free_partition_bitmaps ();
3809
+
3801
3810
if (first && m_added_file && m_added_file[0 ])
3802
3811
{
3803
3812
file= m_added_file;
@@ -8246,15 +8255,18 @@ int ha_partition::info(uint flag)
8246
8255
do
8247
8256
{
8248
8257
file= *file_array;
8249
- /* Get variables if not already done */
8250
- if (!(flag & HA_STATUS_VARIABLE) ||
8251
- !bitmap_is_set (&(m_part_info->read_partitions ),
8252
- (uint)(file_array - m_file)))
8253
- file->info (HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
8254
- if (file->stats .records > max_records)
8258
+ if (bitmap_is_set (&(m_opened_partitions), (file_array - m_file)))
8255
8259
{
8256
- max_records= file->stats .records ;
8257
- handler_instance= i;
8260
+ /* Get variables if not already done */
8261
+ if (!(flag & HA_STATUS_VARIABLE) ||
8262
+ !bitmap_is_set (&(m_part_info->read_partitions ),
8263
+ (uint) (file_array - m_file)))
8264
+ file->info (HA_STATUS_VARIABLE | no_lock_flag | extra_var_flag);
8265
+ if (file->stats .records > max_records)
8266
+ {
8267
+ max_records= file->stats .records ;
8268
+ handler_instance= i;
8269
+ }
8258
8270
}
8259
8271
i++;
8260
8272
} while (*(++file_array));
@@ -8335,6 +8347,96 @@ void ha_partition::get_dynamic_partition_info(PARTITION_STATS *stat_info,
8335
8347
}
8336
8348
8337
8349
8350
+ void ha_partition::set_partitions_to_open (List<String> *partition_names)
8351
+ {
8352
+ m_partitions_to_open= partition_names;
8353
+ }
8354
+
8355
+
8356
+ int ha_partition::open_read_partitions (char *name_buff, size_t name_buff_size,
8357
+ handler **sample)
8358
+ {
8359
+ handler **file;
8360
+ char *name_buffer_ptr;
8361
+ int error;
8362
+
8363
+ name_buffer_ptr= m_name_buffer_ptr;
8364
+ file= m_file;
8365
+ *sample= NULL ;
8366
+ do
8367
+ {
8368
+ int n_file= file-m_file;
8369
+ int is_open= bitmap_is_set (&m_opened_partitions, n_file);
8370
+ int should_be_open= bitmap_is_set (&m_part_info->read_partitions , n_file);
8371
+
8372
+ if (is_open && !should_be_open)
8373
+ {
8374
+ if ((error= (*file)->ha_close ()))
8375
+ goto err_handler;
8376
+ bitmap_clear_bit (&m_opened_partitions, n_file);
8377
+ }
8378
+ else if (!is_open && should_be_open)
8379
+ {
8380
+ LEX_CSTRING save_connect_string= table->s ->connect_string ;
8381
+ if ((error= create_partition_name (name_buff, name_buff_size,
8382
+ table->s ->normalized_path .str ,
8383
+ name_buffer_ptr, NORMAL_PART_NAME, FALSE )))
8384
+ goto err_handler;
8385
+ if (!((*file)->ht ->flags & HTON_CAN_READ_CONNECT_STRING_IN_PARTITION))
8386
+ table->s ->connect_string = m_connect_string[(uint)(file-m_file)];
8387
+ error= (*file)->ha_open (table, name_buff, m_mode,
8388
+ m_open_test_lock | HA_OPEN_NO_PSI_CALL);
8389
+ table->s ->connect_string = save_connect_string;
8390
+ if (error)
8391
+ goto err_handler;
8392
+ if (!(*sample))
8393
+ *sample= *file;
8394
+ bitmap_set_bit (&m_opened_partitions, n_file);
8395
+ }
8396
+ name_buffer_ptr+= strlen (name_buffer_ptr) + 1 ;
8397
+ } while (*(++file));
8398
+
8399
+ err_handler:
8400
+ return error;
8401
+ }
8402
+
8403
+
8404
+ int ha_partition::change_partitions_to_open (List<String> *partition_names)
8405
+ {
8406
+ char name_buff[FN_REFLEN+1 ];
8407
+ int error= 0 ;
8408
+ handler *sample;
8409
+
8410
+ if (m_is_clone_of)
8411
+ return 0 ;
8412
+
8413
+ m_partitions_to_open= partition_names;
8414
+ if ((error= m_part_info->set_partition_bitmaps (partition_names)))
8415
+ goto err_handler;
8416
+
8417
+ if (m_lock_type != F_UNLCK)
8418
+ {
8419
+ /*
8420
+ That happens after the LOCK TABLE statement.
8421
+ Do nothing in this case.
8422
+ */
8423
+ return 0 ;
8424
+ }
8425
+
8426
+ if (bitmap_cmp (&m_opened_partitions, &m_part_info->read_partitions ) != 0 )
8427
+ return 0 ;
8428
+
8429
+ if ((error= read_par_file (table->s ->normalized_path .str )) ||
8430
+ (error= open_read_partitions (name_buff, sizeof (name_buff), &sample)))
8431
+ goto err_handler;
8432
+
8433
+ clear_handler_file ();
8434
+
8435
+ err_handler:
8436
+ return error;
8437
+ }
8438
+
8439
+
8338
8440
/* *
8339
8441
General function to prepare handler for certain behavior.
8340
8442
@@ -8831,7 +8933,8 @@ int ha_partition::reset(void)
8831
8933
i < m_tot_parts;
8832
8934
i= bitmap_get_next_set (&m_partitions_to_reset, i))
8833
8935
{
8834
- if ((tmp= m_file[i]->ha_reset ()))
8936
+ if (bitmap_is_set (&m_opened_partitions, i) &&
8937
+ (tmp= m_file[i]->ha_reset ()))
8835
8938
result= tmp;
8836
8939
}
8837
8940
bitmap_clear_all (&m_partitions_to_reset);
@@ -8948,7 +9051,12 @@ int ha_partition::loop_extra(enum ha_extra_function operation)
8948
9051
i < m_tot_parts;
8949
9052
i= bitmap_get_next_set (&m_part_info->lock_partitions , i))
8950
9053
{
8951
- if ((tmp= m_file[i]->extra (operation)))
9054
+ /*
9055
+ This can be called after an error in ha_open.
9056
+ In this case calling 'extra' can crash.
9057
+ */
9058
+ if (bitmap_is_set (&m_opened_partitions, i) &&
9059
+ (tmp= m_file[i]->extra (operation)))
8952
9060
result= tmp;
8953
9061
}
8954
9062
/* Add all used partitions to be called in reset(). */
0 commit comments