Defining ‘select’ statements

The information contained in the results of a query is controlled by the select statement. Part of the process of developing a useful query is to make the results clear and easy for other users to understand.

When you write queries in LGTM, there are no constraints on what can be selected. However, if you want to use a query to create alerts in LGTM, you’ll need to make the select statement report results in the required format.

Overview

In their most basic form, LGTM alert queries must select:

  • Element—a code element that’s identified by the query. This defines the location of the alert.
  • String—a message to display for this code element, describing why the alert was generated.

If you look at some of the LGTM alert queries, you’ll see that they select extra element/string pairs, which are combined with $@ placeholder markers in the message to form links. For example, Dereferenced variable may be null (Java), or Duplicate switch case (JavaScript).

Developing a select statement

Here’s a simple query that uses the standard QL CodeDuplication.qll library to identify similar files.

Basic select statement

import java
import external.CodeDuplication

from File f, File other, int percent
where similarFiles(f, other, percent)
select f, "This file is similar to another file."

This basic select statement has two columns:

  1. Element to display the alert on: f corresponds to File.
  2. String message to display: "This file is similar to another file."
Results of basic select statement

Including the name of the similar file

The alert message defined by the basic select statement is constant and doesn’t give users much information. Since the query identifies the similar file (other), it’s easy to extend the select statement to report the name of the similar file. For example:

select f, "This file is similar to " + other.getBaseName()
  1. Element: f as before.
  2. String message: "This file is similar to "—the string text is combined with the file name for the other, similar file, returned by getBaseName().
Results of extended select statement

While this is more informative than the original select statement, the user still needs to find the other file manually.

Adding details of the extent of similarity

You could go further and change the select statement to report on the similarity of content in the two files, since this information is already available in the query. For example:

select f, percent + "% of the lines in " + f.getBaseName() + " are similar to lines in $@.", other, other.getBaseName()

The new elements added here don’t need to be clickable, so we added them directly to the description string.

Results showing the extent of similarity