QL: Fix bad join

```
[2023-06-22 10:44:20] (92s) Tuple counts for Predicate#23818b54::Cached::resolveSelfClassCalls#2#ff/2@06fd3bf5 after 1m9s:
                      30500      ~567%     {3} r1 = JOIN Ast#8e1d5bcf::ClassPredicate::getName#0#dispred#ff WITH Ast#8e1d5bcf::PredicateOrBuiltin::getArity#0#dispred#ff ON FIRST 1 OUTPUT Lhs.0 'p', Lhs.1, Rhs.1
                      26500      ~573%     {4} r2 = JOIN r1 WITH Ast#8e1d5bcf::Class::getAClassPredicate#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Lhs.2, Lhs.0 'p', Lhs.1, Rhs.1
                      3059915597 ~605%     {4} r3 = JOIN r2 WITH Ast#8e1d5bcf::Call::getNumberOfArguments#0#dispred#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1 'mc', Lhs.2, Lhs.1 'p', Lhs.3
                      20999389   ~701%     {3} r4 = JOIN r3 WITH Ast#8e1d5bcf::MemberCall::getMemberName#0#dispred#ff ON FIRST 2 OUTPUT Lhs.0 'mc', Lhs.2 'p', Lhs.3
                      20995877   ~711%     {4} r5 = JOIN r4 WITH Ast#8e1d5bcf::MemberCall::getBase#0#dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'p', Lhs.2, Lhs.0 'mc'
                      1240332    ~700%     {3} r6 = JOIN r5 WITH Ast#8e1d5bcf::ThisAccess#ff ON FIRST 1 OUTPUT Lhs.3 'mc', Lhs.1 'p', Lhs.2
                      1236711    ~716%     {4} r7 = JOIN r6 WITH Ast#8e1d5bcf::AstNode::getEnclosingPredicate#0#dispred#ff ON FIRST 1 OUTPUT Rhs.1, Lhs.2, Lhs.1 'p', Lhs.0 'mc'
                      4476       ~347%     {2} r8 = JOIN r7 WITH Ast#8e1d5bcf::AstNode::getParent#0#dispred#ff ON FIRST 2 OUTPUT Lhs.3 'mc', Lhs.2 'p'
                                           return r8
```
This commit is contained in:
Tom Hvitved
2023-06-22 10:53:10 +02:00
parent 277dbdf410
commit 6942925899

View File

@@ -90,16 +90,28 @@ private module Cached {
)
}
pragma[nomagic]
private ClassPredicate getClassPredicate(Class c, string name, int arity) {
result = c.getClassPredicate(name) and
arity = result.getArity()
}
pragma[nomagic]
private predicate resolveSelfClassCalls0(Class c, string name, int arity, MemberCall mc) {
mc.getBase() instanceof ThisAccess and
c = mc.getEnclosingPredicate().getParent() and
name = mc.getMemberName() and
arity = mc.getNumberOfArguments()
}
/**
* Holds if `mc` is a `this.method()` call to a predicate defined in the same class.
* helps avoid spuriously resolving to predicates in super-classes.
*/
private predicate resolveSelfClassCalls(MemberCall mc, PredicateOrBuiltin p) {
exists(Class c |
mc.getBase() instanceof ThisAccess and
c = mc.getEnclosingPredicate().getParent() and
p = c.getClassPredicate(mc.getMemberName()) and
p.getArity() = mc.getNumberOfArguments()
exists(Class c, string name, int arity |
resolveSelfClassCalls0(c, name, arity, mc) and
p = getClassPredicate(c, name, arity)
)
}