SQLite源码学习(36) Btree杂记

1.在newDatabase函数中写入数据库头100字节时为什么不会把原来的覆盖掉

关键代码如下:

  if( pBt->nPage>0 ){
    return SQLITE_OK;
  }

只有在数据库为空的时候才写入,不为空的时候直接返回了,不会往下执行。

2.sqlite3VdbePrintOp函数中下面这行如何打印出来

30 TableLock 0 1 1 sqlite_master 00 iDb=0 root=1 write=1

首先定义字符数组

    /* 161 */ "TableLock"        OpHelp("iDb=P1 root=P2 write=P3"),
    # define OpHelp(X) "\0" X

sqlite3OpcodeName(pOp->opcode)获取TableLock字符串,displayComment解析注释,并把注释中的P1,P2,P3用真实值替换掉

3.打开调试追踪虚拟机执行过程

file delete -force example1.db
sqlite3 db example1.db
db eval {PRAGMA vdbe_trace = 1}
db eval {CREATE TABLE t1(a TEXT, b INTEGER)}

执行结果如下

OPEN 537402416 E:\qxqb\open_source\sqlite-src-3310100\test\example1.db
SQL: [PRAGMA vdbe_trace = 1]
VDBE Trace:
   0 Init             0    1    0               00 Start at 1
   1 Expire           0    0    0               00 
   2 Halt             0    0    0               00 
......
//此处未打印SQL语句----(1)
VDBE Trace:
   0 Init             0   13    0               00 Start at 13
  13 Transaction      0    0    0 0             00 usesStmtJournal=0
  14 TableLock        0    1    0 sqlite_master 00 iDb=0 root=1 write=0
  15 Goto             0    1    0               00 
......
SQL: [CREATE TABLE t1(a TEXT, b INTEGER)]
VDBE Trace:
   0 Init             0   29    0               00 Start at 29
  29 Transaction      0    1    0 0             01 usesStmtJournal=0
 30 TableLock        0    1    1 sqlite_master 00 iDb=0 root=1 write=1
  31 Goto             0    1    0               00 
   1 ReadCookie       0    3    2               00 
......
  27 ParseSchema      0    0    0 tbl_name='t1' AND type!='trigger' 00 
  //此处未打印SQL语句----(1)
VDBE Trace:
   0 Init             0   19    0               00 Start at 19
  19 Transaction      0    0    1 0             00 usesStmtJournal=0
  20 TableLock        0    1    0 sqlite_master 00 iDb=0 root=1 write=0
  21 String8          0    2    0 t1            00 r[2]='t1'

每执行一句SQL代码对应一段VDBE 字节码程序,为什么有2处没有SQL语句?

这是内部执行的SQL语句,并不是外部输入,第(1)处是
SELECT*FROM\"main\".sqlite_master ORDER BY rowid
第(2)处是
SELECT*FROM\"main\".sqlite_master WHERE tbl_name='t1' AND type!='trigger' ORDER BY rowid

SQL语句的解释执行sqlite3_exec包括sqlite3_prepare_v2和sqlite3_step两部分,第(1)处的执行流程如下
在这里插入图片描述
第(2)处执行流程如下
在这里插入图片描述

4.为什么sqlite3VdbePrintSql不打印上述2条SQL语句呢

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
如上三张图所示,只有db->init.busy为0时才打印,但是Create Table语句已经把db->init.busy置1了,所有内部sql语句不会打印。

5 数据库的第一页的前100个字节作为头部,那么第101个字节是在什么时候写入的

其实就在newDatabase的zeroPage里,前100个字节初始化完成后,紧接着新建一张sqlite_master表用来存放所有的表

  data[hdr] = (char)flags;
  first = hdr + ((flags&PTF_LEAF)==0 ? 12 : 8);
  memset(&data[hdr+1], 0, 4);
  data[hdr+7] = 0;
  put2byte(&data[hdr+5], pBt->usableSize);

6 make -j24 testfixture.exe出错了怎么修改

test_quota.c test_fs.c:
#define SQLITE_OS_WIN 0
#define SQLITE_OS_UNIX 1

函数没定义的,注释掉相关编译选项或直接在代码里屏蔽掉 zipfile.c有错,编译加-lz

SQLITE_ENABLE_DESERIALIZE全都注释掉,无论代码还是Makefile

大概修改方法如上,可能不同机器上有些差异,但思路都差不多,另外如果出现下面这样的错误

'_P_WAIT' undeclared (first use in this function); did you mean '__VALIST'?

   rval = _spawnv (_P_WAIT, lt_argv_zero, (const char * const *) newargz);

把bld文件夹下libtool文件中的build_libtool_libs=yes改为build_libtool_libs=no

猜你喜欢

转载自blog.csdn.net/pfysw/article/details/107735158