# CodeQL
官方文档 https://codeql.github.com/docs/ql-language-reference/
# 1. QL 语言特性
逻辑语言,继承自 Datalog。例如,针对一个包含父子关系数据库,查询一个人的所有后代总数。逻辑表达
- 找到这个人的后代,孩子或者孩子的后代
- 计算总数
QL 查询语句如下
1 | Person getADescendant(Person p) { |
# 2. Predicates 谓词
谓词用来描述逻辑关系,一个谓词测试一组元组。
1 | predicate isCountry(string country) { |
谓词 isCountry
是一元元组 {("Belgium"),("Germany"),("France")}
# 谓词定义规则:
predicate
- 没有返回结果 / 返回值类型 - 有返回结果- 名字,以小写字母开头
- 参数,类型 + 名字,如果有多个参数,以逗号分隔
- 主体
-
没有返回结果
1
2
3predicate isSmall(int i) {
i in [1 .. 9]
} -
有返回结果
1
2
3
4int getSuccessor(int i) {
result = i + 1 and
i in [1 .. 9]
}
# 谓词类型
- 非成员谓词 class 之外定义
- 特征谓词 class 内定义,且所有变量都被
this
限制 - 成员谓词 class 内定义
1 | int getSuccessor(int i) { // 1. Non-member predicate |
# 谓词绑定
谓词必须能在有限时间内验证,所以其对应的集合不能是无限的,否则会报错
1 | /* |
绑定集合
如果想创建 “无限谓词”,然后在有限集合上使用。必须添加注解 bindingset
1 | bindingset[i] |
# 数据集谓词
每个数据集都包含着一个记录值关系的表格,“database predicates”。其被认为是另一种 QL 中的谓词
# 3. Queries 查询
Queries 是 QL 程序的输出,对结果进行评估
两类 Queries
select clause
选择子句,在 module 中定义query predicates
查询谓词,在 module 的谓词作用域,可以由模块自己定义,也可以从其他模块进行导入
# Select clauses
写一个查询模块(一般是 .ql
文件)时,可以包含一个选择子句,一般在文件末尾
1 | from /* ... variable declarations ... */ |
from
和 where
是可选项
expressions
的两个关键词
as
,紧跟一个名字,设置结果栏的标签order by
,紧跟结果栏的名字,可以按顺序排列结果 两个顺序关键词,asc
/desc
1 | from int x, int y |
结果
x | y | product | [3] |
---|---|---|---|
3 | 0 | 0 | 0 |
3 | 1 | 3 | 3 |
3 | 2 | 6 | 6 |
可以在选择子句的最后添加 order by y desc
,结果会按照 y 的降序排列
1 | from int x, int y |
结果
x | y | product | [3] |
---|---|---|---|
3 | 2 | 6 | 6 |
3 | 1 | 3 | 3 |
3 | 0 | 0 | 0 |
# Query predicates
查询谓词就是带有 query
注解的非成员谓词,会返回所有谓词评估通过的元组
1 | query int getProduct(int x, int y) { |
结果
x | y | result |
---|---|---|
3 | 0 | 0 |
3 | 1 | 3 |
3 | 2 | 6 |
查询谓词的好处是可以在代码的其他部分调用,而选择子句不行。例如,你可以在类中使用 getProduct
1 | class MultipleOfThree extends int { |