Skip to content

Commit bd94e80

Browse files
authored
Merge pull request github#2809 from jf205/update-rc123
docs: port some more changes onto rc/1.23
2 parents cb94c95 + a460d90 commit bd94e80

File tree

8 files changed

+63
-199
lines changed

8 files changed

+63
-199
lines changed

docs/language/learn-ql/advanced/abstract-classes.rst

Lines changed: 0 additions & 110 deletions
This file was deleted.

docs/language/learn-ql/advanced/advanced-ql.rst

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ Advanced QL
1010

1111
Topics on advanced uses of QL. These topics assume that you are familiar with QL and the basics of query writing.
1212

13-
- :doc:`Semantics of abstract classes <abstract-classes>`
1413
- :doc:`Choosing appropriate ways to constrain types <constraining-types>`
1514
- :doc:`Determining the most specific types of a variable <determining-specific-types-variables>`
16-
- :doc:`Folding predicates <folding-predicates>`
17-
- :doc:`Understanding the difference between != and not(=) <equivalence>`
1815
- :doc:`Monotonic aggregates in QL <monotonic-aggregates>`

docs/language/learn-ql/advanced/equivalence.rst

Lines changed: 0 additions & 44 deletions
This file was deleted.

docs/language/learn-ql/advanced/folding-predicates.rst

Lines changed: 0 additions & 36 deletions
This file was deleted.

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,48 @@ That is, you should define a *base case* that allows the predicate to *bottom ou
8181
The query optimizer has special data structures for dealing with `transitive closures <https://help.semmle.com/QL/ql-handbook/recursion.html#transitive-closures>`__.
8282
If possible, use a transitive closure over a simple recursive predicate, as it is likely to be computed faster.
8383

84+
Fold predicates
85+
~~~~~~~~~~~~~~~~~~
86+
87+
Sometimes you can assist the query optimizer by "folding" parts of large predicates out into smaller predicates.
88+
89+
The general principle is to split off chunks of work that are:
90+
91+
- **linear**, so that there is not too much branching.
92+
- **tightly bound**, so that the chunks join with each other on as many variables as possible.
93+
94+
95+
In the following example, we explore some lookups on two ``Element``\ s:
96+
97+
.. code-block:: ql
98+
99+
predicate similar(Element e1, Element e2) {
100+
e1.getName() = e2.getName() and
101+
e1.getFile() = e2.getFile() and
102+
e1.getLocation().getStartLine() = e2.getLocation().getStartLine()
103+
}
104+
105+
Going from ``Element -> File`` and ``Element -> Location -> StartLine`` is linear--that is, there is only one ``File``, ``Location``, etc. for each ``Element``.
106+
107+
However, as written it is difficult for the optimizer to pick out the best ordering. Joining first and then doing the linear lookups later would likely result in poor performance. Generally, we want to do the quick, linear parts first, and then join on the resultant larger tables. We can initiate this kind of ordering by splitting the above predicate as follows:
108+
109+
.. code-block:: ql
110+
111+
predicate locInfo(Element e, string name, File f, int startLine) {
112+
name = e.getName() and
113+
f = e.getFile() and
114+
startLine = e.getLocation().getStartLine()
115+
}
116+
117+
predicate sameLoc(Element e1, Element e2) {
118+
exists(string name, File f, int startLine |
119+
locInfo(e1, name, f, startLine) and
120+
locInfo(e2, name, f, startLine)
121+
)
122+
}
123+
124+
Now the structure we want is clearer. We've separated out the easy part into its own predicate ``locInfo``, and the main predicate ``sameLoc`` is just a larger join.
125+
84126
Further information
85127
-------------------
86128

docs/language/ql-handbook/modules.rst

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ into the :ref:`namespace <namespaces>` of the current module.
160160
Import statements
161161
=================
162162

163-
Import statements are used for importing modules and are of the form::
163+
Import statements are used for importing modules. They are of the form::
164164

165165
import <module_expression1> as <name>
166166
import <module_expression2>
@@ -175,3 +175,6 @@ for example ``import javascript as js``.
175175

176176
The ``<module_expression>`` itself can be a module name, a selection, or a qualified
177177
reference. See :ref:`name-resolution` for more details.
178+
179+
For information about how import statements are looked up, see `Module resolution <https://help.semmle.com/QL/ql-spec/language.html#module-resolution>`__
180+
in the QL language specification.

docs/language/ql-handbook/types.rst

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ by declaring them in the ``from`` part.
208208
You can also annotate predicates and fields. See the list of :ref:`annotations <annotations-overview>`
209209
that are available.
210210

211-
Kinds of classes
211+
.. _concrete-classes:
212+
213+
Concrete classes
212214
================
213215

214216
The classes in the above examples are all **concrete** classes. They are defined by
@@ -218,6 +220,9 @@ values in the intersection of the base types that also satisfy the
218220

219221
.. _abstract-classes:
220222

223+
Abstract classes
224+
================
225+
221226
A class :ref:`annotated <abstract>` with ``abstract``, known as an **abstract** class, is also a restriction of
222227
the values in a larger type. However, an abstract class is defined as the union of its
223228
subclasses. In particular, for a value to be in an abstract class, it must satisfy the
@@ -247,6 +252,13 @@ The abstract class ``SqlExpr`` refers to all of those different expressions. If
247252
support for another database system later on, you can simply add a new subclass to ``SqlExpr``;
248253
there is no need to update the queries that rely on it.
249254

255+
.. pull-quote:: Important
256+
257+
258+
You must take care when you add a new subclass to an existing abstract class. Adding a subclass
259+
is not an isolated change, it also extends the abstract class since that is a union of its
260+
subclasses.
261+
250262
.. _overriding-member-predicates:
251263

252264
Overriding member predicates

docs/language/ql-spec/language.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ Identifiers are used in following syntactic constructs:
502502
simpleId ::= lowerId | upperId
503503
modulename ::= simpleId
504504
classname ::= upperId
505-
dbasetype ::= atlowerId
505+
dbasetype ::= atLowerId
506506
predicateRef ::= (moduleId "::")? literalId
507507
predicateName ::= lowerId
508508
varname ::= simpleId
@@ -1798,7 +1798,7 @@ The complete grammar for QL is as follows:
17981798

17991799
::
18001800

1801-
ql ::= moduleBody ;
1801+
ql ::= moduleBody
18021802

18031803
module ::= annotation* "module" modulename "{" moduleBody "}"
18041804

@@ -1970,11 +1970,11 @@ The complete grammar for QL is as follows:
19701970

19711971
simpleId ::= lowerId | upperId
19721972

1973-
modulename :: = simpleId
1973+
modulename ::= simpleId
19741974

19751975
classname ::= upperId
19761976

1977-
dbasetype ::= atlowerId
1977+
dbasetype ::= atLowerId
19781978

19791979
predicateRef ::= (moduleId "::")? literalId
19801980

0 commit comments

Comments
 (0)