SQLIte在使用时,前端的主要API是sqlite3_prepare函数,该函数的主要功能是把sql编译成sqlite虚拟机代码。
1-语法分析
sqlite的语法分析阶段把sql转换成内部的抽象语法树AST结构,这部分工作采用lemon工具进行完成。
《Sqlite3源码---Parser(1)》介绍了lemon工具;
《Sqlite3源码---Parser(2)》介绍了insert、update、delete等语句的lemon语法规则。
《Sqlite3源码---Parser(3)》介绍了sql表达式的语法规则;
《Sqlite3源码---Parser(4)》介绍了select语句的语法规则;
《Sqlite3源码---Parser(5)》对语法规则进行了总结。
select的语法规则如下
2-sqlite虚拟机
接着AST需要被转换成内部sqlite的虚拟机代码。我们简单介绍了几类典型SQL语句的虚拟机代码。
《Sqlite3源码---虚拟机(1)》介绍了“select * from tbl”的字节码
《Sqlite3源码---虚拟机(2)》介绍了虚拟机字节码的内部数据结构
《Sqlite3源码---虚拟机(3)》介绍了where语句的字节码
《Sqlite3源码---虚拟机(4)》介绍了join语句的字节码
《sqlite3源码---虚拟机(5)》介绍了group by语句的字节码
3-优化器&生成器
接着,《Sqlite3源码之代码生成》介绍了如何从AST到虚拟机代码的过程。生成虚拟代码的重点工作是优化器的任务。优化器主要需要判定的是单表扫描操作和多表join操作的执行策略选择,分别在《SQLite源代码之扫描与索引》和《Sqlite3源码之JOIN顺序》中介绍,此外,我们转载了一篇官网优化器的中文翻译《SQLite查询计划器和优化(翻译)》。
虚拟机代码生成器涉及到的函数调用关系如下:
sqlite3Select()是虚拟机代码生成器的入口,生成器的很重要一个工作是基于AST生成最优的执行方案,这部分工作是优化器来完成的。
优化器的入口函数是sqlite3WhereBegin(),该函数会调用wherePathSolver()完成join顺序,扫描方法等的选取。
扫描操作:主要是能不能有索引可用。
join顺序:主要是选取代价最优的join顺序,目前采用kNN算法。