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

DB-12133 Fix predicate packing logic for multiple IN lists MultiProbeScan #5671

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

msirek
Copy link
Contributor

@msirek msirek commented Jul 14, 2021

Short Description

Fixes loss of a predicate during packing of useful MultiProbeScan predicates, which may show up in a query as "ERROR 42Y63: Hash join requires an optimizable equijoin predicate", or possibly incorrect results.

Long Description

When we have a tables such as:
create table t1
(a1 int, b1 int, c1 int, primary key (a1, b1, c1));
create table t2
(a2 int, b2 int, c2 int, primary key (a2, b2, c2));

...and a query such as :
select a1, t2.a2 from t1 INNER JOIN t2 on t1.a1=t2.a2
where a1=(SELECT MAX(a2) FROM t2 ) and a1 in (0,1,2)
and b1 in (0,1,2,3,4,5) and c1 in (0,1,2,3,4,5,6,7,8) order by t2.a2;

The 3 IN list predicates may be collected into a usefulPredicates array, along with pushable predicate t1.a1=t2.a2.
The IN list predicates are then combined into one a single multicolumn IN list, and the usefulPredicates is packed into a smaller size, removing the original IN predicates. This logic is faulty and does not increment variable "j" when the source and destination position in usefulPredicates are identical, so the predicate t1.a1=t2.a2 which enables a hashable join is lost:

                for (int i = firstPred + 1; i < usefulCount && j < usefulCount; i++) {
                    while(i < usefulCount && foundPred[i])
                        i++;
                    if (i != j && i < usefulCount) {
                        usefulPredicates[j] = usefulPredicates[i];
                        j++;
                    }

The solution is to move the incrementing of j outside of the conditional code which skips NoOp assignments.

How to test

The following test case should not error out:

create table t1
(a1 int, b1 int, c1 int, primary key (a1, b1, c1));

create table t2
(a2 int, b2 int, c2 int, primary key (a2, b2, c2));

select a1, t2.a2 from t1 INNER JOIN t2 on t1.a1=t2.a2 
where a1=(SELECT MAX(a2) FROM t2   )   and  a1 in (0,1,2) 
and b1 in (0,1,2,3,4,5) and c1 in (0,1,2,3,4,5,6,7,8) order by t2.a2;

@msirek
Copy link
Contributor Author

msirek commented Jul 14, 2021

jenkins please test branch @dbaas3.0,skipTestsLongerThan2Minutes

@cloudspliceci
Copy link
Contributor

@msirek
Copy link
Contributor Author

msirek commented Jul 14, 2021

jenkins please test branch @dbaas3.0,skipTestsLongerThan2Minutes

@cloudspliceci
Copy link
Contributor

TEST SUCCEEDED +1

Copy link
Contributor

@hatyo hatyo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice catch

Copy link

@carolp-503 carolp-503 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants