Metadata

ql 脚本开头的一段注释,描述脚本的一些关键信息

PropertyValueDescription
@description<text>一段描述文字
@id<text>多个简短的单词组成的 id,小写,单词间用横杠连接
@kindproblem, path-problem查询的类型,an alert (@kind problem) or a path (@kind path-problem)
@name<text>名字
@tagscorrectness, maintainability, readability, securityThese tags group queries together in broad categories to make it easier to search for them and identify them.
@precisionlow, medium, high, very-highIndicates the percentage of query results that are true positives (as opposed to false positive results).
@problem.severityerror, warning, recommendationDefines the level of severity of any alerts generated by a non-security query.
@security-severity<score>Defines the level of severity, between 0.0 and 10.0, for queries with @tags security.

逻辑连接词

import tutorial
 
from Person t
where
  /* 1 */ t.getHeight() > 150 and
  /* 2 */ not t.getHairColor() = "blond" and
  /* 3 */ exists (string c | t.getHairColor() = c) and
  /* 4 */ not t.getAge() < 30 and
  /* 5 */ t.getLocation() = "east" and
  /* 6 */ (t.getHairColor() = "black" or t.getHairColor() = "brown") and
  /* 7 */ not (t.getHeight() > 180 and t.getHeight() < 190) and
  /* 8 */ exists(Person p | p.getAge() > t.getAge()) and
  /* 9 */ not t = max(Person p | | p order by p.getHeight()) and
  /* 10 */ t.getHeight() < avg(float i | exists(Person p | p.getHeight() = i) | i) and
  /* 11 */ t = max(Person p | p.getLocation() = "east" | p order by p.getAge())
select "The thief is " + t + "!"
Code Snippet 1: find the thief

Class

class Southerner extends Person {
  Southerner() { isSouthern(this) }
}

QL 中的类表示一个逻辑属性: 当一个值满足该属性时,它就是该类的成员。这意味着一个 值可以在很多个类中ーー属于某个特定的类并不妨碍它也属于其他类

表达式 isSouthern(this) 定义了由类表示的逻辑属性,称为其特征谓词。它使用一个特殊 的变量 this,并指示如果谓词 isSouthern(this) 命中,则 Person “this” 是 Southerner(南方人)

注意上面 class 中的 Southerner() 是一个特征谓词,并不是构造函数,不会创建任何对 象

除了特征谓词,class 中还存在成员谓词,比如 southerner.getAge() 。成员谓词需要显 式调用,而且可以很方便地通过逻辑连接词连接起来

递归

假设有一个谓词 parentOf(Person p) ,它会返回 p 的父母

我们可以通过两个特殊符号 * 和 + 来递归调用这个谓词:

  • parentOf+(p): 表示调用一次或多次,相当于查询 p 的祖先
  • parentOf*(p): 表示调用零次或多次,相当于查询 p 的祖先或者 p 的本身