mirror of
https://github.com/github/codeql.git
synced 2026-04-26 17:25:19 +02:00
Data flow: Fix bad join-order in TPathNodeSink
Avoids a Cartesian product on nodes:
```
[2020-02-07 11:01:22] (432s) Tuple counts for dom#DataFlowImpl::TPathNodeSink#ff:
0 ~0% {2} r1 = JOIN DataFlowImpl::Configuration::isSource_dispred#ff AS L WITH DataFlowImpl::Configuration::isSink_dispred#ff AS R ON FIRST 2 OUTPUT R.<1>, R.<0>
101611 ~0% {2} r2 = SCAN DataFlowImpl::PathNodeMid#class#ffffff AS I OUTPUT I.<5>, I.<0>
3534537047 ~3% {3} r3 = JOIN r2 WITH DataFlowImpl::Configuration::isSink_dispred#ff AS R ON FIRST 1 OUTPUT r2.<1>, R.<1>, R.<0>
251 ~41% {3} r4 = JOIN r3 WITH project#DataFlowImpl::pathStep#fffff AS R ON FIRST 2 OUTPUT R.<2>, r3.<2>, r3.<1>
251 ~50% {2} r5 = JOIN r4 WITH DataFlowImpl::TNil#ff_1#join_rhs AS R ON FIRST 1 OUTPUT r4.<2>, r4.<1>
251 ~50% {2} r6 = r1 \/ r5
323 ~67% {3} r7 = JOIN r6 WITH DataFlowImpl::flow#ff AS R ON FIRST 1 OUTPUT r6.<1>, r6.<0>, R.<1>
288 ~58% {3} r8 = SELECT r7 ON r7.<2> >= r7.<0>
251 ~53% {3} r9 = SELECT r8 ON r8.<2> <= r8.<0>
251 ~50% {2} r10 = SCAN r9 OUTPUT r9.<1>, r9.<0>
```
This commit is contained in:
@@ -2076,13 +2076,18 @@ private newtype TPathNode =
|
||||
config.isSource(node)
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
pathStepNil(node, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStepNil(Node node, Configuration config) {
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
|
||||
* Only those `PathNode`s that are reachable from a source are generated.
|
||||
|
||||
@@ -2076,13 +2076,18 @@ private newtype TPathNode =
|
||||
config.isSource(node)
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
pathStepNil(node, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStepNil(Node node, Configuration config) {
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
|
||||
* Only those `PathNode`s that are reachable from a source are generated.
|
||||
|
||||
@@ -2076,13 +2076,18 @@ private newtype TPathNode =
|
||||
config.isSource(node)
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
pathStepNil(node, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStepNil(Node node, Configuration config) {
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
|
||||
* Only those `PathNode`s that are reachable from a source are generated.
|
||||
|
||||
@@ -2076,13 +2076,18 @@ private newtype TPathNode =
|
||||
config.isSource(node)
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
pathStepNil(node, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStepNil(Node node, Configuration config) {
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
|
||||
* Only those `PathNode`s that are reachable from a source are generated.
|
||||
|
||||
@@ -2076,13 +2076,18 @@ private newtype TPathNode =
|
||||
config.isSource(node)
|
||||
or
|
||||
// ... or a sink that can be reached from a source
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
pathStepNil(node, config)
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate pathStepNil(Node node, Configuration config) {
|
||||
exists(PathNodeMid mid |
|
||||
pathStep(mid, node, _, _, any(AccessPathNil nil)) and
|
||||
config = mid.getConfiguration()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `Node` augmented with a call context (except for sinks), an access path, and a configuration.
|
||||
* Only those `PathNode`s that are reachable from a source are generated.
|
||||
|
||||
Reference in New Issue
Block a user