Skip to content

Commit d6202da

Browse files
author
james
committed
docs: address max's comments
1 parent 61576ca commit d6202da

File tree

1 file changed

+11
-16
lines changed

1 file changed

+11
-16
lines changed

docs/language/learn-ql/writing-queries/debugging-queries.rst

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Query writing: common performance issues
22
========================================
33

4-
This topic offers some simple tips on how to avoid commons problems that can affect the performance of your queries.
4+
This topic offers some simple tips on how to avoid common problems that can affect the performance of your queries.
55
Before reading the tips below, it is worth reiterating a few important points about CodeQL and the QL language:
66

77
- CodeQL `predicates <https://help.semmle.com/QL/ql-handbook/predicates.html>`__ and `classes <https://help.semmle.com/QL/ql-handbook/types.html#classes>`__ are evaluated to database `tables <https://en.wikipedia.org/wiki/Table_(database)>`__. Large predicates generate large tables with many rows, and are therefore expensive to compute.
@@ -22,13 +22,18 @@ This leads to computing the `Cartesian product <https://en.wikipedia.org/wiki/Ca
2222

2323
This can occur whenever you inadvertently fail to specify restrictions on your variables.
2424

25-
For instance, in the following case none of the parameters are related in the example predicate ``methodAndAClass``, and therefore the results are unrestricted::
25+
For instance, consider the following predicate that checks whether a Java method ``m`` may access a field ``f``::
2626

27-
// BAD! Cross-product
28-
predicate methodAndAClass(Method m, Class c) {
29-
any()
27+
predicate mayAccess(Method m, Field f) {
28+
f.getAnAccess().getEnclosingCallable() = m
29+
or
30+
not exists(m.getBody())
3031
}
3132

33+
The predicate holds if ``m`` contains an access to ``f``, but also conservatively assumes that methods without bodies (for example, native methods) may access *any* field.
34+
35+
However, if ``m`` is a native method, the table computed by ``mayAccess`` will contain a row ``m, f`` for *all* fields ``f`` in the codebase, which could potentially be very large.
36+
3237
This example shows a similar mistake in a member predicate::
3338

3439
class Foo extends Class {
@@ -40,19 +45,9 @@ This example shows a similar mistake in a member predicate::
4045
...
4146
}
4247

43-
Note that while `getToString()` does not declare any parameters, it has two implicit parameters `result` and `this`, which it fails to relate. Hence the table computed by `getToString()` contains a row for every combination of values of `result` and `this`, that is, for every combination of a method named `"ToString"` and an instance of `Foo`.
48+
Note that while ``getToString()`` does not declare any parameters, it has two implicit parameters, ``result`` and ``this``, which it fails to relate. Therefore, the table computed by ``getToString()`` contains a row for every combination of ``result`` and ``this``. That is, a row for every combination of a method named ``"ToString"`` that is an instance of ``Foo``.
4449
To avoid making this mistake, ``this`` should be restricted in the member predicate ``getToString()`` on the class ``Foo``.
4550

46-
Finally, consider a predicate of the following form::
47-
48-
predicate p(T1 x1, T2 x2) {
49-
<disjunction 1> or
50-
<disjunction 2> or
51-
...
52-
}
53-
54-
In this situation, if ``x1`` and ``x2`` are not mentioned in all ``<disjunction i>`` terms, the compiler will produce the Cartesian product between what you wanted and all possible values of the unused parameter.
55-
5651
Use specific types
5752
~~~~~~~~~~~~~~~~~~
5853

0 commit comments

Comments
 (0)