2021SC@SDUSC SQLite源码分析(七)————VDBE结构分析

VDBE是SQLite的核心。用户程序发出的SQL语句请求,由前端编译器处理,生成字节代码程序,然后由VM解释执行。VM执行时,又会调用B-tree模块的相关的接口,并输出执行的结果。

一、vdbeInt.h

是vdbe.c的私有头文件,定义了VDBE的常用数据结构。
主要包含一些结构体和方法的声明或者预定义

struct VdbeCursor(vdbe游标)

struct VdbeFrame(vdbe框架)

struct Mem(仅对vdbe可见的数据结构)

struct VdbeFunc(辅助数据)

struct sqlite3_context(上下文和返回值等信息)

struct Explain(vdbe的信息)

struct Vdbe(vdbe整体结构)
定义了一个虚拟机的实体。这个结构体包含了虚拟机完整的状态。 sqlite3_stmt这个结构的指针由sqlite3_prepare()方法返回,它是这个结构实体的一个真实指针。

struct VdbeCursor

int iDb (检索数据库)
Bool isTable; (查看表是否存在)
Bool rowidIsValid(某一行的数据是否有效)
i64 lastRowid
int seekResult(查询结构)

}(树形结构,数据库页为子节点)
游标,是一个数据库文件中单一BTree的指示器。
游标能够找到拥有特定值的一个BTree的入口,或者遍历BTree的所有入口。你能够从新的BTree入口或者从这个指针通常指向的的入口检索值或者数据。每一个虚拟机已经开启的指针都代表着一个一下结构的常量。

typedef struct VdbeFrame VdbeFrame;
struct VdbeFrame {
  Vdbe *v;
  VdbeFrame *pParent;
  Op *aOp;
  i64 *anExec;
  Mem *aMem;
  VdbeCursor **apCsr;
  u8 *aOnce;
  void *token;
  i64 lastRowid;
  AuxData *pAuxData;
#if SQLITE_DEBUG
  u32 iFrameMagic;
#endif
  int nCursor;
  int pc;
  int nOp;
  int nMem;
  int nChildMem;
  int nChildCsr;
  int nChange;
  int nDbChange;
};

一个虚拟机框架对象的内存由父框架的一个存储单元中被分配和管理。当内存单元被删除或者重写,虚拟机框架对象不会被立即释放。
当虚拟机在中重启后,Vdbe.pDelFrame的目录清单被删除。这么做而不是立刻删除虚拟机框架对象是为了避免当属于子框架的存储单元被释放时循环调用sqlite3VdbeMemRelease()方法。

二、解释引擎

经过编译器生成的vdbe最终都是由 解释引擎 解释执行的,SQLite的解释引擎实现的原理非常简单,本质上就是一个包含大量case语句的for循环

删减后代码如下 (位于vdbe.c中):


int sqlite3VdbeExec(
  Vdbe *p
){

  int pc;

  Op *pOp;
  int rc = SQLITE_OK;

  sqlite3 *db = p->db;
  u8 encoding = ENC(db);

  Mem *pTos;
  if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE;

  pTos = p->pTos;
  if( p->rc==SQLITE_NOMEM ){

    goto no_mem;
  }
  p->rc = SQLITE_OK;

  if( p->popStack ){
    popStack(&pTos, p->popStack);
    p->popStack = 0;
  }

  p->resOnStack = 0;
  db->busyHandler.nBusy = 0;

  for(pc=p->pc; rc==SQLITE_OK; pc++){

    pOp = &p->aOp[pc];
    switch( pOp->opcode ){

        case OP_Goto: {
          CHECK_FOR_INTERRUPT;

          pc = pOp->p2 - 1;
          break;
        }

        case OP_Integer: {

          pTos++;

          pTos->flags = MEM_Int;

          pTos->i = pOp->p1;
          break;
        }

    }
  }
}

参考资料:《inside SQLite》

Original: https://blog.csdn.net/qq_45936073/article/details/121407383
Author: 神明不自知
Title: 2021SC@SDUSC SQLite源码分析(七)————VDBE结构分析

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/816180/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球