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:
Tom Hvitved
2020-02-07 12:08:31 +01:00
parent b3af3ad12f
commit f30a42ce26
19 changed files with 171 additions and 76 deletions

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.

View File

@@ -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.