QL语言参考-7表达式
表达式(Expressions)
Expressions — CodeQL (github.com)
表达式计算为一组值,并具有类型。
例如,表达式1 + 2
计算为整数3
,表达式“ QL”
计算为字符串“ QL”
。1 + 2
类型为 int
,“ QL”
类型为 string
。
变量引用(Variable references)
变量引用是已声明变量的名称。这种类型的表达式与它引用的变量具有相同的类型。
例如,如果声明了 int i
和 LocalScopeVariable lsv
变量,那么表达式 i
和 lsv
分别具有 int
和 LocalScopeVariable
类型。
您还可以引用 this
和 result
变量。它们在谓词定义中使用,并以与其他变量引用相同的方式工作。
文字(Literals)
您可以直接在 QL 中表示某些值,例如数字、布尔值和字符串。
-
Boolean 文字: 这些是 true 和 false 值。
-
整数字面值: 这些是十进制数字序列(0到9) ,可能以减号(-)开头。例如:
-
浮点字面值: 这些是由点(.)分隔的十进制数字序列,可能以减号(-)开始。例如:
-
字符串字面值: 这些是16位字符的有限字符串。可以通过将字符括在引号中(“ ...”)来定义字符串文本。大多数字符表示它们自己,但有一些字符需要用反斜杠“转义”。下面是字符串文字的例子:
带括号的表达式(Parenthesized expressions)
括号表达式是由括号包围的表达式(
和)
。此表达式的类型和值与原始表达式完全相同。括号对于将表达式组合在一起以消除歧义和提高可读性非常有用。
范围(Ranges)
范围表达式表示两个表达式之间排序的值范围。它由两个表达式组成..
以括号([
及]
)括起来。例如,[3..7]是一个有效的范围表达式。它的值是介于3和7之间的任何整数(包括3和7本身)。
设置文字表达式(Set literal expressions)
Set literal 表达式允许在多个值之间进行选择的显式列表。它由一个逗号分隔的表达式集合组成,这些表达式被括在方括号中([和])。例如,[2,3,5,7,11,13,17,19,23,29]
是一个有效的 set literal 表达式。它的值是前十个素数。
所包含的表达式的值必须为有效的集文字表达式的兼容类型。此外,集合元素中至少有一个必须是所有其他所包含表达式的类型的超类型。
超级表达式(Super expressions)
QL 中的超级表达式类似于其他编程语言中的超级表达式,比如 Java。当您希望使用来自超类型的谓词定义时,可以在谓词调用中使用它们。在实践中,当谓词从其超类型继承两个定义时,这种方法非常有用。在这种情况下,谓词必须重写这些定义以避免歧义。但是,如果您希望使用来自特定超类型的定义,而不是编写新的定义,则可以使用超表达式。
在下面的示例中,类 C 继承了谓词 getANumber ()
的两个定义ーー一个来自A,一个来自 B。
class A extends int {
A() { this = 1 }
int getANumber() { result = 2 }
}
class B extends int {
B() { this = 1 }
int getANumber() { result = 3 }
}
class C extends A, B {
// Need to define `int getANumber()`; otherwise it would be ambiguous
int getANumber() {
result = B.super.getANumber()
}
}
from C c
select c, c.getANumber()
这个查询的结果是1,3
。
7、调用含返回值的谓词
8、聚合表达式(Aggregations)
聚合在信息科学中是指对有关的数据进行内容挑选、分析、归类,最后分析得到人们想要的结果,主要是指任何能够从数组产生标量值的数据转换过程。
https://baike.baidu.com/item/聚合/20367464
通用语法格式
<aggregate>(<variable declarations> | <formula> | <expression>)
在
可以在
count
min
max
avg
sum
concat
concat(int i | i = [0 .. 3] | i.toString() order by i desc)
如下示例输出:0|1|2|3
concat(int i | i = [0 .. 3] | i.toString(), "|")
rank
unique
Evaluation of aggregates
TODO
省略部分内容
Omitting parts of an aggregation
1、当你要写的聚合表达式形式这样时<aggregate>(<type> v | <expression> = v | v)
,你可以省略<variable declarations>
部分和<formula>
部分
count(int i | i = "hello".indexOf("l") | i)
=>
count("hello".indexOf("l"))
2、当只有一个聚合变量时,可以省略
avg(int i | i = [0 .. 3] | i)
=>
avg(int i | i = [0 .. 3])
3、特例,即使有多个聚合变量时,你可以在count事件中省略
count(int i, int j | i in [1 .. 3] and j in [1 .. 3] | 1)
=>
count(int i, int j | i in [1 .. 3] and j in [1 .. 3])
4、你可以省略
<aggregate>(<variable declarations> | | <expression>)
max(File f | | f.getTotalNumberOfLines())
5、你可以同时省略
count(File f | any() | 1)
=>
count(File f | | 1)
=>
count(File f)
Monotonic aggregates
TODO
9、ANY
10、一元操作符(Unary operations)
一个一元操作由一个一元操作符+一个表达式构成
-6.28
+(10 - 4)
11、二元操作符(Binary operations)
一个二元操作由一个表达式+一个二元操作符+一个表达式构成
5 % 2
(9 + 1) / (-2)
"Q" + "L"
注意:221 + "B"
的值是 "221B"
12、类型转换(casts)
import java
from Type t
后缀型类型转换
where t.(Class).getASupertype().hasName("List")
前缀型类型转换
where ((Class)t).getASupertype().hasName("List")
13、临时表达式(Don’t-care expressions)
from string s
where s = "hello".charAt(_)
select s
等价于
from string s,int i
where s = "hello".charAt(i)
select s