3226
Find the sub-array part_info->list_array that corresponds to given interval
3229
get_list_array_idx_for_endpoint()
3230
part_info Partitioning info (partitioning type must be LIST)
3231
left_endpoint TRUE - the interval is [a; +inf) or (a; +inf)
3232
FALSE - the interval is (-inf; a] or (-inf; a)
3233
include_endpoint TRUE iff the interval includes the endpoint
3236
This function finds the sub-array of part_info->list_array where values of
3237
list_array[idx].list_value are contained within the specifed interval.
3238
list_array is ordered by list_value, so
3239
1. For [a; +inf) or (a; +inf)-type intervals (left_endpoint==TRUE), the
3240
sought sub-array starts at some index idx and continues till array end.
3241
The function returns first number idx, such that
3242
list_array[idx].list_value is contained within the passed interval.
3244
2. For (-inf; a] or (-inf; a)-type intervals (left_endpoint==FALSE), the
3245
sought sub-array starts at array start and continues till some last
3247
The function returns first number idx, such that
3248
list_array[idx].list_value is NOT contained within the passed interval.
3249
If all array elements are contained, part_info->num_list_values is
3253
The caller will call this function and then will run along the sub-array of
3254
list_array to collect partition ids. If the number of list values is
3255
significantly higher then number of partitions, this could be slow and
3256
we could invent some other approach. The "run over list array" part is
3257
already wrapped in a get_next()-like function.
3260
The edge of corresponding sub-array of part_info->list_array
3263
3226
uint32 get_partition_id_cols_list_for_endpoint(partition_info *part_info,
3264
3227
bool left_endpoint,
3265
3228
bool include_endpoint,
3268
3231
part_column_list_val *list_col_array= part_info->list_col_array;
3269
3232
uint num_columns= part_info->part_field_list.elements;
3270
int list_index, cmp;
3271
3234
uint min_list_index= 0;
3272
uint max_list_index= part_info->num_list_values - 1;
3273
bool tailf= !(left_endpoint ^ include_endpoint);
3235
uint max_list_index= part_info->num_list_values;
3274
3236
DBUG_ENTER("get_partition_id_cols_list_for_endpoint");
3238
/* Find the matching partition (including taking endpoint into account). */
3241
/* Midpoint, adjusted down, so it can never be > last index. */
3278
3242
list_index= (max_list_index + min_list_index) >> 1;
3279
cmp= cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
3243
if (cmp_rec_and_tuple_prune(list_col_array + list_index*num_columns,
3244
nparts, left_endpoint, include_endpoint) > 0)
3282
3245
min_list_index= list_index + 1;
3287
max_list_index= list_index - 1;
3291
DBUG_RETURN(list_index + test(!tailf));
3293
} while (max_list_index >= min_list_index);
3247
max_list_index= list_index;
3248
} while (max_list_index > min_list_index);
3249
list_index= max_list_index;
3251
/* Given value must be LESS THAN or EQUAL to the found partition. */
3252
DBUG_ASSERT(list_index == part_info->num_list_values ||
3253
(0 >= cmp_rec_and_tuple_prune(list_col_array +
3254
list_index*num_columns,
3255
nparts, left_endpoint,
3256
include_endpoint)));
3257
/* Given value must be GREATER THAN the previous partition. */
3258
DBUG_ASSERT(list_index == 0 ||
3259
(0 < cmp_rec_and_tuple_prune(list_col_array +
3260
(list_index - 1)*num_columns,
3261
nparts, left_endpoint,
3262
include_endpoint)));
3266
/* Set the end after this list tuple if not already after the last. */
3267
if (list_index < part_info->num_parts)
3297
3271
DBUG_RETURN(list_index);
3276
Find the sub-array part_info->list_array that corresponds to given interval.
3278
@param part_info Partitioning info (partitioning type must be LIST)
3279
@param left_endpoint TRUE - the interval is [a; +inf) or (a; +inf)
3280
FALSE - the interval is (-inf; a] or (-inf; a)
3281
@param include_endpoint TRUE iff the interval includes the endpoint
3283
This function finds the sub-array of part_info->list_array where values of
3284
list_array[idx].list_value are contained within the specifed interval.
3285
list_array is ordered by list_value, so
3286
1. For [a; +inf) or (a; +inf)-type intervals (left_endpoint==TRUE), the
3287
sought sub-array starts at some index idx and continues till array end.
3288
The function returns first number idx, such that
3289
list_array[idx].list_value is contained within the passed interval.
3291
2. For (-inf; a] or (-inf; a)-type intervals (left_endpoint==FALSE), the
3292
sought sub-array starts at array start and continues till some last
3294
The function returns first number idx, such that
3295
list_array[idx].list_value is NOT contained within the passed interval.
3296
If all array elements are contained, part_info->num_list_values is
3299
@note The caller will call this function and then will run along the
3300
sub-array of list_array to collect partition ids. If the number of list
3301
values is significantly higher then number of partitions, this could be slow
3302
and we could invent some other approach. The "run over list array" part is
3303
already wrapped in a get_next()-like function.
3305
@return The index of corresponding sub-array of part_info->list_array.
3301
3308
uint32 get_list_array_idx_for_endpoint_charset(partition_info *part_info,
3302
3309
bool left_endpoint,
3303
3310
bool include_endpoint)
7398
Compare record and columns partition tuple including endpoint handling.
7400
@param val Columns partition tuple
7401
@param n_vals_in_rec Number of columns to compare
7402
@param is_left_endpoint True if left endpoint (part_tuple < rec or
7404
@param include_endpoint If endpoint is included (part_tuple <= rec or
7407
@return Less than/Equal to/Greater than 0 if the record is L/E/G than
7408
the partition tuple.
7410
@see get_list_array_idx_for_endpoint() and
7411
get_partition_id_range_for_endpoint().
7386
7414
static int cmp_rec_and_tuple_prune(part_column_list_val *val,
7387
7415
uint32 n_vals_in_rec,
7416
bool is_left_endpoint,
7417
bool include_endpoint)
7392
partition_info *part_info;
7393
7421
if ((cmp= cmp_rec_and_tuple(val, n_vals_in_rec)))
7395
part_info= val->part_info;
7396
field= part_info->part_field_array + n_vals_in_rec;
7397
for (; *field; field++, val++)
7423
field= val->part_info->part_field_array + n_vals_in_rec;
7401
if (!tail_is_min && !val->max_value)
7427
Full match, if right endpoint and not including the endpoint,
7428
(rec < part) return lesser.
7430
if (!is_left_endpoint && !include_endpoint)
7433
/* Otherwise they are equal! */
7437
The prefix is equal and there are more partition columns to compare.
7439
If including left endpoint or not including right endpoint
7440
then the record is considered lesser compared to the partition.
7443
part(10, x) <= rec(10, unknown) and rec(10, unknown) < part(10, x)
7444
part <= rec -> lesser (i.e. this or previous partitions)
7445
rec < part -> lesser (i.e. this or previous partitions)
7447
if (is_left_endpoint == include_endpoint)
7451
If right endpoint and the first additional partition value
7452
is MAXVALUE, then the record is lesser.
7454
if (!is_left_endpoint && (val + n_vals_in_rec)->max_value)
7458
Otherwise the record is considered greater.
7460
rec <= part -> greater (i.e. does not match this partition, seek higher).
7461
part < rec -> greater (i.e. does not match this partition, seek higher).
7412
7471
bool include_endpoint,
7413
7472
uint32 num_parts);
7416
Partitioning Interval Analysis: Initialize the iterator for "mapping" case
7419
get_part_iter_for_interval_via_mapping()
7420
part_info Partition info
7421
is_subpart TRUE - act for subpartitioning
7422
FALSE - act for partitioning
7423
min_value minimum field value, in opt_range key format.
7424
max_value minimum field value, in opt_range key format.
7425
flags Some combination of NEAR_MIN, NEAR_MAX, NO_MIN_RANGE,
7427
part_iter Iterator structure to be initialized
7430
Initialize partition set iterator to walk over the interval in
7431
ordered-array-of-partitions (for RANGE partitioning) or
7432
ordered-array-of-list-constants (for LIST partitioning) space.
7435
This function is used when partitioning is done by
7436
<RANGE|LIST>(ascending_func(t.field)), and we can map an interval in
7437
t.field space into a sub-array of partition_info::range_int_array or
7438
partition_info::list_array (see get_partition_id_range_for_endpoint,
7439
get_list_array_idx_for_endpoint for details).
7441
The function performs this interval mapping, and sets the iterator to
7442
traverse the sub-array and return appropriate partitions.
7445
0 - No matching partitions (iterator not initialized)
7446
1 - Ok, iterator intialized for traversal of matching partitions.
7447
-1 - All partitions would match (iterator not initialized)
7475
Get partition for RANGE COLUMNS endpoint.
7477
@param part_info Partitioning metadata.
7478
@param is_left_endpoint True if left endpoint (const <=/< cols)
7479
@param include_endpoint True if range includes the endpoint (<=/>=)
7480
@param nparts Total number of partitions
7482
@return Partition id of matching partition.
7484
@see get_partition_id_cols_list_for_endpoint and
7485
get_partition_id_range_for_endpoint.
7450
7488
uint32 get_partition_id_cols_range_for_endpoint(partition_info *part_info,
7489
bool is_left_endpoint,
7452
7490
bool include_endpoint,
7455
uint max_partition= part_info->num_parts - 1;
7456
uint min_part_id= 0, max_part_id= max_partition, loc_part_id;
7493
uint min_part_id= 0, max_part_id= part_info->num_parts, loc_part_id;
7457
7494
part_column_list_val *range_col_array= part_info->range_col_array;
7458
7495
uint num_columns= part_info->part_field_list.elements;
7459
bool tailf= !(left_endpoint ^ include_endpoint);
7460
7496
DBUG_ENTER("get_partition_id_cols_range_for_endpoint");
7462
/* Get the partitioning function value for the endpoint */
7463
while (max_part_id > min_part_id)
7465
loc_part_id= (max_part_id + min_part_id + 1) >> 1;
7466
if (cmp_rec_and_tuple_prune(range_col_array + loc_part_id*num_columns,
7467
nparts, tailf) >= 0)
7468
min_part_id= loc_part_id + 1;
7470
max_part_id= loc_part_id - 1;
7472
loc_part_id= max_part_id;
7473
if (loc_part_id < max_partition &&
7474
cmp_rec_and_tuple_prune(range_col_array + (loc_part_id+1)*num_columns,
7482
if (cmp_rec_and_tuple_prune(range_col_array + loc_part_id*num_columns,
7483
nparts, tailf) >= 0)
7488
if (loc_part_id < max_partition)
7490
int res= cmp_rec_and_tuple_prune(range_col_array +
7498
/* Find the matching partition (including taking endpoint into account). */
7501
/* Midpoint, adjusted down, so it can never be > last partition. */
7502
loc_part_id= (max_part_id + min_part_id) >> 1;
7503
if (0 <= cmp_rec_and_tuple_prune(range_col_array +
7491
7504
loc_part_id * num_columns,
7494
loc_part_id += test(include_endpoint);
7508
min_part_id= loc_part_id + 1;
7510
max_part_id= loc_part_id;
7511
} while (max_part_id > min_part_id);
7512
loc_part_id= max_part_id;
7514
/* Given value must be LESS THAN the found partition. */
7515
DBUG_ASSERT(loc_part_id == part_info->num_parts ||
7516
(0 > cmp_rec_and_tuple_prune(range_col_array +
7517
loc_part_id * num_columns,
7518
nparts, is_left_endpoint,
7519
include_endpoint)));
7520
/* Given value must be GREATER THAN or EQUAL to the previous partition. */
7521
DBUG_ASSERT(loc_part_id == 0 ||
7522
(0 <= cmp_rec_and_tuple_prune(range_col_array +
7523
(loc_part_id - 1) * num_columns,
7524
nparts, is_left_endpoint,
7525
include_endpoint)));
7527
if (!is_left_endpoint)
7529
/* Set the end after this partition if not already after the last. */
7530
if (loc_part_id < part_info->num_parts)
7500
7533
DBUG_RETURN(loc_part_id);
7605
Partitioning Interval Analysis: Initialize the iterator for "mapping" case
7607
@param part_info Partition info
7608
@param is_subpart TRUE - act for subpartitioning
7609
FALSE - act for partitioning
7610
@param store_length_array Ignored.
7611
@param min_value minimum field value, in opt_range key format.
7612
@param max_value minimum field value, in opt_range key format.
7613
@param min_len Ignored.
7614
@param max_len Ignored.
7615
@param flags Some combination of NEAR_MIN, NEAR_MAX, NO_MIN_RANGE,
7617
@param part_iter Iterator structure to be initialized
7619
@details Initialize partition set iterator to walk over the interval in
7620
ordered-array-of-partitions (for RANGE partitioning) or
7621
ordered-array-of-list-constants (for LIST partitioning) space.
7623
This function is used when partitioning is done by
7624
<RANGE|LIST>(ascending_func(t.field)), and we can map an interval in
7625
t.field space into a sub-array of partition_info::range_int_array or
7626
partition_info::list_array (see get_partition_id_range_for_endpoint,
7627
get_list_array_idx_for_endpoint for details).
7629
The function performs this interval mapping, and sets the iterator to
7630
traverse the sub-array and return appropriate partitions.
7632
@return Status of iterator
7633
@retval 0 No matching partitions (iterator not initialized)
7634
@retval 1 Ok, iterator intialized for traversal of matching partitions.
7635
@retval -1 All partitions would match (iterator not initialized)
7571
7638
int get_part_iter_for_interval_via_mapping(partition_info *part_info,
7572
7639
bool is_subpart,
7573
7640
uint32 *store_length_array, /* ignored */