Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CBRD-25542] Problem with partition pruning when using multi-column indexes with IN and range predicates #5689

Draft
wants to merge 8 commits into
base: feature/partition-table
Choose a base branch
from
63 changes: 37 additions & 26 deletions src/query/partition.c
Original file line number Diff line number Diff line change
Expand Up @@ -1517,6 +1517,7 @@ static MATCH_STATUS
partition_prune (PRUNING_CONTEXT * pinfo, const REGU_VARIABLE * arg, const PRUNING_OP op, PRUNING_BITSET * pruned)
{
MATCH_STATUS status = MATCH_NOT_FOUND;
PRUNING_BITSET new_pruned;
DB_VALUE val;
bool is_value = false;

Expand All @@ -1543,7 +1544,19 @@ partition_prune (PRUNING_CONTEXT * pinfo, const REGU_VARIABLE * arg, const PRUNI
return MATCH_NOT_FOUND;
}

status = partition_prune_db_val (pinfo, &val, op, pruned);
if (pruningset_popcount (pruned) != 0)
{
pruningset_init (&new_pruned, PARTITIONS_COUNT (pinfo));
status = partition_prune_db_val (pinfo, &val, op, &new_pruned);
if (status == MATCH_OK)
{
pruningset_intersect (pruned, &new_pruned);
}
}
else
{
status = partition_prune_db_val (pinfo, &val, op, pruned);
}

pr_clear_value (&val);

Expand Down Expand Up @@ -2845,6 +2858,8 @@ partition_prune_spec (THREAD_ENTRY * thread_p, val_descr * vd, access_spec_node
{
int error = NO_ERROR;
PRUNING_CONTEXT pinfo;
PRUNING_BITSET pruned;
MATCH_STATUS status = MATCH_NOT_FOUND;

if (spec == NULL)
{
Expand Down Expand Up @@ -2888,45 +2903,41 @@ partition_prune_spec (THREAD_ENTRY * thread_p, val_descr * vd, access_spec_node
pinfo.spec = spec;
pinfo.vd = vd;

if (spec->access == ACCESS_METHOD_SEQUENTIAL || spec->access == ACCESS_METHOD_SEQUENTIAL_RECORD_INFO
|| spec->access == ACCESS_METHOD_SEQUENTIAL_PAGE_SCAN || spec->access == ACCESS_METHOD_SEQUENTIAL_SAMPLING_SCAN)
pruningset_init (&pruned, PARTITIONS_COUNT (&pinfo));
if (pinfo.spec->where_pred != NULL)
{
error = partition_prune_heap_scan (&pinfo);
if (error != NO_ERROR)
{
ASSERT_ERROR ();
}
status = partition_match_pred_expr (&pinfo, pinfo.spec->where_pred, &pruned);
}
else

if (pinfo.spec->where_key != NULL)
{
if (spec->indexptr == NULL)
{
assert (false);
status = partition_match_pred_expr (&pinfo, pinfo.spec->where_key, &pruned);
}

er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_GENERIC_ERROR, 0);
partition_clear_pruning_context (&pinfo);
return ER_FAILED;
}
if (pinfo.spec->where_range != NULL)
Hamkua marked this conversation as resolved.
Show resolved Hide resolved
{
status = partition_match_pred_expr (&pinfo, pinfo.spec->where_range, &pruned);
}

if (pinfo.partition_pred->func_regu->type != TYPE_ATTR_ID)
if (status == MATCH_NOT_FOUND)
shparkcubrid marked this conversation as resolved.
Show resolved Hide resolved
{
if (pinfo.error_code != NO_ERROR)
{
/* In the case of index keys, we will only apply pruning if the partition expression is actually an
* attribute. This is because we will not have expressions in the index key, only attributes (except for
* function and filter indexes which are not handled yet) */
pinfo.attr_position = -1;
ASSERT_ERROR ();
}
else
{
BTID *btid = &spec->indexptr->btid;
error = partition_get_position_in_key (&pinfo, btid);
pruningset_set_all (&pruned);
error = pruningset_to_spec_list (&pinfo, &pruned);
if (error != NO_ERROR)
{
ASSERT_ERROR ();
partition_clear_pruning_context (&pinfo);
return error;
}
}
error = partition_prune_index_scan (&pinfo);
}
else
{
error = pruningset_to_spec_list (&pinfo, &pruned);
if (error != NO_ERROR)
{
ASSERT_ERROR ();
Expand Down
Loading