关于 QL 语言¶
QL 是一种功能强大的查询语言,它是 CodeQL 的基础,CodeQL 用于分析代码。
关于查询语言和数据库¶
QL 是一种声明式面向对象的查询语言,经过优化,可以有效地分析层次数据结构,特别是代表软件工件的数据库。
数据库是有组织的数据集合。最常用的数据库模型是关系模型,它将数据存储在表格中,SQL(结构化查询语言)是关系数据库最常用的查询语言。
查询语言的目的是提供一个编程平台,您可以在其中询问有关存储在数据库中的信息的问题。数据库管理系统管理数据的存储和管理,并提供查询机制。查询通常是指相关数据库实体,并指定结果必须满足的各种条件(称为谓词)。查询评估涉及检查这些谓词并生成结果。良好的查询语言及其实现的一些理想特性包括
- 声明式规范 - 声明式规范描述了结果必须满足的属性,而不是提供计算结果的过程。在数据库查询语言的上下文中,声明式规范抽象了底层数据库管理系统和查询处理技术的细节。这极大地简化了查询编写。
- 表现力 - 功能强大的查询语言允许您编写复杂的查询。这使得语言得到广泛应用。
- 高效执行 - 查询可能很复杂,数据库可能非常大,因此查询语言实现高效处理和执行查询至关重要。
QL 的属性¶
QL 的语法类似于 SQL,但 QL 的语义基于 Datalog,Datalog 是一种声明式逻辑编程语言,通常用作查询语言。这使得 QL 成为主要的一种逻辑语言,并且 QL 中的所有操作都是逻辑操作。此外,QL 从 Datalog 中继承了递归谓词,并添加了对聚合的支持,使即使是最复杂的查询也能简洁明了。例如,考虑一个包含人员的父子关系的数据库。如果我们想找到某个人的后代数量,通常我们会
- 找到给定人员的后代,即孩子的后代或孩子的后代。
- 使用上一步找到的后代数量。
当您用 QL 编写此过程时,它与上述结构非常相似。请注意,我们使用递归来查找给定人员的所有后代,并使用聚合来计算后代的数量。由于语言的声明性,将这些步骤转换为最终查询而无需添加任何过程细节是可能的。QL 代码将类似于以下内容
Person getADescendant(Person p) {
result = p.getAChild() or
result = getADescendant(p.getAChild())
}
int getNumberOfDescendants(Person p) {
result = count(getADescendant(p))
}
有关 QL 的重要概念和语法结构的更多信息,请参阅各个参考主题,例如“表达式”和“递归”。解释和示例可以帮助您了解语言的工作原理以及如何编写更高级的 QL 代码。
有关 QL 语言的正式规范,请参阅“QL 语言规范”。
QL 和面向对象¶
面向对象是 QL 的重要功能。面向对象的优势是众所周知的——它提高了模块化,实现了信息隐藏,并允许代码重用。QL 在不影响其逻辑基础的情况下提供了所有这些优势。这是通过定义一个简单的对象模型来实现的,其中类被建模为谓词,继承被建模为蕴含。为所有支持的语言提供的库广泛使用类和继承。
QL 和通用编程语言¶
以下是一些通用编程语言和 QL 之间的突出概念和功能差异
- QL 不具有任何命令式功能,例如对变量的赋值或文件系统操作。
- QL 在元组集上运行,查询可以被视为定义查询结果的复杂集合操作序列。
- QL 的基于集合的语义使其非常自然地处理值集合,而无需担心有效地存储、索引和遍历它们。
- 在面向对象的编程语言中,实例化一个类涉及通过分配物理内存来创建对象以保存该类实例的状态。在 QL 中,类只是描述已存在值的集合的逻辑属性。