2021SC@SDUSC
概述
????????SQLite的工作方式是将SQL语句转换为字节码,然后在虚拟机中运行该字节码。本节描述字节码引擎如何工作。
字节码引擎(Bytecode Engine)
????????代码生成器创建的字节码程序由虚拟机运行。
????????虚拟机本身完全包含在单个源文件vdbe.c中。vdbe.h头文件定义了虚拟机与SQLite库其余部分之间的接口,vdbeInt.h定义了虚拟机本身专用的结构和接口。各种其他vdbe*.c文件是虚拟机的助手。vdbeaux.c文件包含虚拟机使用的实用程序和库的其余部分用于构造VM程序的接口模块。vdbeapi.c文件包含虚拟机的外部接口,如sqlite3_bind_int()和sqlite3_step()。单个值(字符串、整数、浮点数和blob)存储在名为“Mem”的内部对象中,该对象由vdbemem.c实现。
????????SQLite使用对C语言例程的回调来实现SQL函数。甚至内置的SQL函数也是这样实现的。大多数内置SQL函数(例如:abs()、count()、substr()等)都可以在func.c源文件中找到。日期和时间转换函数可在Date.c中找到。代码生成器直接将一些函数(如coalesce()和typeof()实现为字节码。
????????VDBE全称为虚拟数据库引擎(virtual database engine);它是对真实计算机资源环境的一个抽象。它的原理类似于Java中的JVM(java虚拟机),它们实现了这两种语言跨平台性。
vdbeInt.h代码分析
一些方法和结构体的条件编译和预处理
typedef struct VdbeOp Op;
typedef unsigned char Bool;
typedef struct VdbeSorter VdbeSorter;
typedef struct Explain Explain;
#define MEM_Null 0x0001
#define MEM_Str 0x0002
#define MEM_Int 0x0004
#define MEM_Real 0x0008
#define MEM_Blob 0x0010
#define MEM_RowSet 0x0020
#define MEM_Frame 0x0040
#define MEM_Invalid 0x0080
#define MEM_TypeMask 0x00ff
几个重要结构体的分析
struct VdbeCursor(vdbe游标)
struct VdbeFrame(vdbe框架)
struct Mem(仅对vdbe可见的数据结构)
struct VdbeFunc(辅助数据)
struct sqlite3_context
(上下文和返回值等信息)
struct Explain(vdbe的信息)
struct Vdbe(vdbe整体结构)
struct VdbeCursor
{
…
int iDb (检索数据库)
Bool isTable; (查看表是否存在)
Bool rowidIsValid(某一行的数据是否有效)
i64 lastRowid
int seekResult(查询结构)
…
}(树形结构,数据库页为子节点)
游标是一个数据库文件中单一BTree的指示器。
游标能够找到拥有特定值的一个BTree的入口,或者遍历BTree的所有入口。你能够从新的BTree入口或者从这个指针通常指向的的入口检索值或者数据。每一个虚拟机已经开启的指针都代表着一个一下结构的常量。
struct VdbeFrame {
Vdbe *v;
Op *aOp;
Mem *aMem (父框架信息)
…
Vdbe *v;
VdbeFrame *pParent;
Op *aOp;
Mem *aMem;(子框架信息)
}
????????一个虚拟机框架对象的内存由父框架的一个存储单元中被分配和管理。当内存单元被删除或者重写,虚拟机框架对象不会被立即释放。相反的,它将被链接到Vdbe.pDelFrame清单中。当虚拟机在中重启后,Vdbe.pDelFrame的目录清单被删除。这么做而不是立刻删除虚拟机框架对象是为了避免当属于子框架的存储单元被释放时循环调用sqlite3VdbeMemRelease()方法。
struct Vdbe{
sqlite3 *db;
Op *aOp;
Mem *aMem;
Mem **apArg
Mem *aColName;
Mem *pResultSet;
int pc;
int rc;
…}
????????这个结构体定义了一个虚拟机的实体。这个结构体包含了虚拟机完整的状态。 sqlite3_stmt这个结构的指针由sqlite3_prepare()方法返回,它是这个结构实体的一个真实指针。Vdbe.inVtab方法的变量在vdbe程序产生的任何虚拟表方法调用期间被置为零。 这个变量主要用于两个目的:允许xDestroy方法实现删除表的声明以及为了防止分配内存失败产生的副作用。sqlite3_stmt这个结构的指针由sqlite3_prepare()方法返回,它是这个虚拟机实体的一个真实指针。
附(源代码):
vdbe.h vdbeInt.h vdbe.c
|