Skip to content

Commit 3e1d49a

Browse files
committed
First draft update tutorials
1 parent 5898615 commit 3e1d49a

File tree

8 files changed

+679
-25
lines changed

8 files changed

+679
-25
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
For information about installing the CodeQL extension for Visual Studio code, see ":ref:`Setting up CodeQL in Visual Studio Code <setting-up-codeql-in-visual-studio-code>`."

docs/codeql/writing-codeql-queries/catch-the-fire-starter.rst

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ Now try applying ``isAllowedIn(string region)`` to a person ``p``. If ``p`` is n
105105

106106
You know that the fire starters live in the south *and* that they must have been able to travel to the north. Write a query to find the possible suspects. You could also extend the ``select`` clause to list the age of the suspects. That way you can clearly see that all the children have been excluded from the list.
107107

108-
➤ `See the answer in the query console on LGTM.com <https://lgtm.com/query/2551838470440192723/>`__
108+
➤ `Check your answer <#exercise-1>`__
109109

110110
You can now continue to gather more clues and find out which of your suspects started the fire...
111111

@@ -142,11 +142,73 @@ The predicate ``isBald`` is defined to take a ``Person``, so it can also take a
142142

143143
You can now write a query to select the bald southerners who are allowed into the north.
144144

145-
➤ `See the answer in the query console on LGTM.com <https://lgtm.com/query/2572701606358725253/>`__
145+
➤ `Check your answer <#exercise-2>`__
146146

147147
You have found the two fire starters! They are arrested and the villagers are once again impressed with your work.
148148

149149
Further reading
150150
---------------
151151

152152
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
153+
154+
--------------
155+
156+
Answers
157+
-------
158+
159+
In these answers, we use ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is treated as a *comment*.
160+
161+
Exercise 1
162+
~~~~~~~~~~
163+
164+
.. code-block:: ql
165+
166+
import tutorial
167+
168+
predicate isSouthern(Person p) { p.getLocation() = "south" }
169+
170+
class Southerner extends Person {
171+
/* the characteristic predicate */
172+
Southerner() { isSouthern(this) }
173+
}
174+
175+
class Child extends Person {
176+
/* the characteristic predicate */
177+
Child() { this.getAge() < 10 }
178+
179+
/* a member predicate */
180+
override predicate isAllowedIn(string region) { region = this.getLocation() }
181+
}
182+
183+
from Southerner s
184+
where s.isAllowedIn("north")
185+
select s, s.getAge()
186+
187+
Exercise 2
188+
~~~~~~~~~~
189+
190+
.. code-block:: ql
191+
192+
import tutorial
193+
194+
predicate isSouthern(Person p) { p.getLocation() = "south" }
195+
196+
class Southerner extends Person {
197+
/* the characteristic predicate */
198+
Southerner() { isSouthern(this) }
199+
}
200+
201+
class Child extends Person {
202+
/* the characteristic predicate */
203+
Child() { this.getAge() < 10 }
204+
205+
/* a member predicate */
206+
override predicate isAllowedIn(string region) { region = this.getLocation() }
207+
}
208+
209+
predicate isBald(Person p) { not exists(string c | p.getHairColor() = c) }
210+
211+
from Southerner s
212+
where s.isAllowedIn("north") and isBald(s)
213+
select s
214+

docs/codeql/writing-codeql-queries/cross-the-river.rst

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -260,21 +260,34 @@ Alternative solutions
260260

261261
Here are some more example queries that solve the river crossing puzzle:
262262

263-
#. This query uses a modified ``path`` variable to describe the resulting path in
264-
more detail.
263+
.. container:: toggle
265264

266-
➤ `See solution in the query console on LGTM.com <https://lgtm.com/query/659603593702729237/>`__
265+
.. container:: name
267266

268-
#. This query models the man and the cargo items in a different way, using an
269-
:ref:`abstract <abstract>`
270-
class and predicate. It also displays the resulting path in a more visual way.
267+
*Show/hide eaxmple query - modified path*
271268

272-
➤ `See solution in the query console on LGTM.com <https://lgtm.com/query/1025323464423811143/>`__
269+
.. literalinclude:: river-answer-1-path.ql
270+
:language: ql
273271

274-
#. This query introduces :ref:`algebraic datatypes <algebraic-datatypes>`
275-
to model the situation, instead of defining everything as a subclass of ``string``.
276272

277-
➤ `See solution in the query console on LGTM.com <https://lgtm.com/query/7260748307619718263/>`__
273+
.. container:: toggle
274+
275+
.. container:: name
276+
277+
*Show/hide eaxmple query - abstract class*
278+
279+
.. literalinclude:: river-answer-2-abstract-class.ql
280+
:language: ql
281+
282+
283+
.. container:: toggle
284+
285+
.. container:: name
286+
287+
*Show/hide eaxmple query - datatypes*
288+
289+
.. literalinclude:: river-answer-3-datatypes.ql
290+
:language: ql
278291

279292
Further reading
280293
---------------

docs/codeql/writing-codeql-queries/crown-the-rightful-heir.rst

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ Here is one way to define ``relativeOf()``:
129129
130130
Don't forget to use the predicate ``isDeceased()`` to find relatives that are still alive.
131131

132-
➤ `See the answer in the query console on LGTM.com <https://lgtm.com/query/6710025057257064639/>`__
132+
➤ `Check your answer <#exercise-1>`__
133133

134134
Select the true heir
135135
--------------------
@@ -142,7 +142,7 @@ To decide who should inherit the king's fortune, the villagers carefully read th
142142

143143
As your final challenge, define a predicate ``hasCriminalRecord`` so that ``hasCriminalRecord(p)`` holds if ``p`` is any of the criminals you unmasked earlier (in the ":doc:`Find the thief <find-the-thief>`" and ":doc:`Catch the fire starter <catch-the-fire-starter>`" tutorials).
144144

145-
➤ `See the answer in the query console on LGTM.com <https://lgtm.com/query/1820692755164273290/>`__
145+
➤ `Check your answer <#exercise-2>`__
146146

147147
Experimental explorations
148148
-------------------------
@@ -164,3 +164,47 @@ Further reading
164164
---------------
165165

166166
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
167+
168+
--------------
169+
170+
Answers
171+
-------
172+
173+
In these answers, we use ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is treated as a *comment*.
174+
175+
Exercise 1
176+
~~~~~~~~~~
177+
178+
.. code-block:: ql
179+
180+
import tutorial
181+
182+
Person relativeOf(Person p) { parentOf*(result) = parentOf*(p) }
183+
184+
from Person p
185+
where
186+
not p.isDeceased() and
187+
p = relativeOf("King Basil")
188+
select p
189+
190+
Exercise 2
191+
~~~~~~~~~~
192+
193+
.. code-block:: ql
194+
195+
import tutorial
196+
197+
Person relativeOf(Person p) { parentOf*(result) = parentOf*(p) }
198+
199+
predicate hasCriminalRecord(Person p) {
200+
p = "Hester" or
201+
p = "Hugh" or
202+
p = "Charlie"
203+
}
204+
205+
from Person p
206+
where
207+
not p.isDeceased() and
208+
p = relativeOf("King Basil") and
209+
not hasCriminalRecord(p)
210+
select p

docs/codeql/writing-codeql-queries/find-the-thief.rst

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ You start asking some creative questions and making notes of the answers so you
5050

5151
There is too much information to search through by hand, so you decide to use your newly acquired QL skills to help you with your investigation...
5252

53-
#. Open the `query console on LGTM.com <https://lgtm.com/query>`__ to get started.
54-
#. Select a language and a demo project. For this tutorial, any language and project will do.
55-
#. Delete the default code ``import <language> select "hello world"``.
53+
.. include:: ../reusables/setup-to-run-tutorials.rst
5654

5755
QL libraries
5856
------------
@@ -209,13 +207,7 @@ Hints
209207
210208
Once you have finished, you will have a list of possible suspects. One of those people must be the thief!
211209

212-
➤ `See the answer in the query console on LGTM.com <https://lgtm.com/query/1505743955992/>`__
213-
214-
.. pull-quote::
215-
216-
Note
217-
218-
In the answer, we used ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is just a *comment*.
210+
➤ `Check your answer <#exercise-1>`__
219211

220212
You are getting closer to solving the mystery! Unfortunately, you still have quite a long list of suspects... To find out which of your suspects is the thief, you must gather more information and refine your query in the next step.
221213

@@ -291,9 +283,59 @@ You can now translate the remaining questions into QL:
291283

292284
Have you found the thief?
293285

294-
➤ `See the answer in the query console on LGTM.com <https://lgtm.com/query/1505744186085/>`__
286+
➤ `Check your answer <#exercise-2>`__
295287

296288
Further reading
297289
---------------
298290

299291
.. include:: ../reusables/codeql-ref-tools-further-reading.rst
292+
293+
294+
--------------
295+
296+
Answers
297+
-------
298+
299+
In these answers, we use ``/*`` and ``*/`` to label the different parts of the query. Any text surrounded by ``/*`` and ``*/`` is not evaluated as part of the QL code, but is treated as a *comment*.
300+
301+
Exercise 1
302+
^^^^^^^^^^
303+
304+
.. code-block:: ql
305+
306+
import tutorial
307+
308+
from Person t
309+
where
310+
/* 1 */ t.getHeight() > 150 and
311+
/* 2 */ not t.getHairColor() = "blond" and
312+
/* 3 */ exists (string c | t.getHairColor() = c) and
313+
/* 4 */ not t.getAge() < 30 and
314+
/* 5 */ t.getLocation() = "east" and
315+
/* 6 */ (t.getHairColor() = "black" or t.getHairColor() = "brown") and
316+
/* 7 */ not (t.getHeight() > 180 and t.getHeight() < 190) and
317+
/* 8 */ exists(Person p | p.getAge() > t.getAge())
318+
select t
319+
320+
Exercise 2
321+
^^^^^^^^^^
322+
323+
.. code-block:: ql
324+
325+
import tutorial
326+
327+
from Person t
328+
where
329+
/* 1 */ t.getHeight() > 150 and
330+
/* 2 */ not t.getHairColor() = "blond" and
331+
/* 3 */ exists (string c | t.getHairColor() = c) and
332+
/* 4 */ not t.getAge() < 30 and
333+
/* 5 */ t.getLocation() = "east" and
334+
/* 6 */ (t.getHairColor() = "black" or t.getHairColor() = "brown") and
335+
/* 7 */ not (t.getHeight() > 180 and t.getHeight() < 190) and
336+
/* 8 */ exists(Person p | p.getAge() > t.getAge()) and
337+
/* 9 */ not t = max(Person p | | p order by p.getHeight()) and
338+
/* 10 */ t.getHeight() < avg(float i | exists(Person p | p.getHeight() = i) | i) and
339+
/* 11 */ t = max(Person p | p.getLocation() = "east" | p order by p.getAge())
340+
select "The thief is " + t + "!"
341+

0 commit comments

Comments
 (0)