Merge pull request #20127 from aschackmull/java/joinorder3

Java: Improve a couple of join-orders
This commit is contained in:
Anders Schack-Mulligen
2025-08-05 14:15:42 +02:00
committed by GitHub
3 changed files with 53 additions and 30 deletions

View File

@@ -348,6 +348,16 @@ predicate expectsContent(Node n, ContentSet c) {
FlowSummaryImpl::Private::Steps::summaryExpectsContent(n.(FlowSummaryNode).getSummaryNode(), c)
}
pragma[nomagic]
private predicate numericRepresentative(RefType t) {
t.(BoxedType).getPrimitiveType().getName() = "double"
}
pragma[nomagic]
private predicate booleanRepresentative(RefType t) {
t.(BoxedType).getPrimitiveType().getName() = "boolean"
}
/**
* Gets a representative (boxed) type for `t` for the purpose of pruning
* possible flow. A single type is used for all numeric types to account for
@@ -356,10 +366,10 @@ predicate expectsContent(Node n, ContentSet c) {
RefType getErasedRepr(Type t) {
exists(Type e | e = t.getErasure() |
if e instanceof NumericOrCharType
then result.(BoxedType).getPrimitiveType().getName() = "double"
then numericRepresentative(result)
else
if e instanceof BooleanType
then result.(BoxedType).getPrimitiveType().getName() = "boolean"
then booleanRepresentative(result)
else result = e
)
or

View File

@@ -214,24 +214,35 @@ private predicate relevantNode(ObjNode n) {
exists(ObjNode mid | relevantNode(mid) and objStep(mid, n) and relevantNodeBack(n))
}
pragma[noinline]
private predicate objStepPruned(ObjNode n1, ObjNode n2) {
objStep(n1, n2) and relevantNode(n1) and relevantNode(n2)
private newtype TObjFlowNode =
TObjNode(ObjNode n) { relevantNode(n) } or
TObjType(RefType t) { source(t, _) }
private predicate objStepPruned(TObjFlowNode node1, TObjFlowNode node2) {
exists(ObjNode n1, ObjNode n2 |
node1 = TObjNode(n1) and
node2 = TObjNode(n2) and
objStep(n1, n2)
)
or
exists(RefType t, ObjNode n |
node1 = TObjType(t) and
node2 = TObjNode(n) and
source(t, n)
)
}
private predicate stepPlus(Node n1, Node n2) = fastTC(objStepPruned/2)(n1, n2)
private predicate flowSrc(TObjFlowNode src) { src instanceof TObjType }
private predicate flowSink(TObjFlowNode sink) { exists(ObjNode n | sink = TObjNode(n) and sink(n)) }
private predicate stepPlus(TObjFlowNode n1, TObjFlowNode n2) =
doublyBoundedFastTC(objStepPruned/2, flowSrc/1, flowSink/1)(n1, n2)
/**
* Holds if the qualifier `n` of an `Object.toString()` call might have type `t`.
*/
pragma[noopt]
private predicate objType(ObjNode n, RefType t) {
exists(ObjNode n2 |
sink(n) and
(stepPlus(n2, n) or n2 = n) and
source(t, n2)
)
}
private predicate objType(ObjNode n, RefType t) { stepPlus(TObjType(t), TObjNode(n)) }
private VirtualMethodCall objectToString(ObjNode n) {
result.getQualifier() = n.asExpr() and sink(n)