Ruby: Fix bad join-order in resolveConstant

```
[2021-11-09 11:35:47] (99s) Starting to evaluate predicate Module::Cached::resolveConstant#ff#antijoin_rhs/3@f6dcd6
[2021-11-09 11:35:58] (111s) Tuple counts for Module::Cached::resolveConstant#ff#antijoin_rhs/3@f6dcd6 after 11.5s:
                      165960683 ~0%     {4} r1 = JOIN Module::Cached::resolveConstant#ff#shared WITH Module::constantDefinition0#ff_10#join_rhs ON FIRST 1 OUTPUT Rhs.1, Lhs.1 'arg1', Lhs.0 'arg0', Lhs.2 'arg2'

                      0         ~0%     {3} r2 = JOIN r1 WITH Module::ClassDeclaration::getSuperclassExpr_dispred#ff ON FIRST 2 OUTPUT Lhs.2 'arg0', Lhs.1 'arg1', Lhs.3 'arg2'

                      0         ~0%     {3} r3 = JOIN r1 WITH Constant::ConstantAccess::getScopeExpr_dispred#ff ON FIRST 2 OUTPUT Lhs.2 'arg0', Lhs.1 'arg1', Lhs.3 'arg2'

                      0         ~0%     {3} r4 = r2 UNION r3
                                        return r4
```
This commit is contained in:
Tom Hvitved
2021-11-09 11:48:26 +01:00
parent 55ea715ce9
commit 19e6da517b

View File

@@ -106,6 +106,15 @@ private module Cached {
exists(string qname | qname = resolveConstant(r) and result = TResolved(qname))
}
pragma[nomagic]
private string constantDefinition1(ConstantReadAccess r) {
exists(ConstantWriteAccess w | result = constantDefinition0(w) |
r = w.getScopeExpr()
or
r = w.(ClassDeclaration).getSuperclassExpr()
)
}
/**
* Resolve constant access (class, module or otherwise) to a qualified module name.
* `resolveScopeExpr/1` picks the best (lowest priority number) result of
@@ -121,11 +130,7 @@ private module Cached {
isDefinedConstant(qn) and
qn = resolveScopeExpr(r, p) and
// prevent classes/modules that contain/extend themselves
not exists(ConstantWriteAccess w | qn = constantDefinition0(w) |
r = w.getScopeExpr()
or
r = w.(ClassDeclaration).getSuperclassExpr()
)
not qn = constantDefinition1(r)
|
qn order by p
)