为了让大家对 DistSQL 有更深入的了解,同时能根据需要定制自己的 DistSQL 语法,本篇将为大家解析 DistSQL 的设计开发流程,同时通过实际的场景案例,带领大家实现一个全新的 DistSQL 语法,完成从需求到设计、开发和测试的完整过程。
兰城翔
SphereEx 中间件研发工程师,Apache ShardingSphere contributor,目前专注于 DistSQL 的设计和研发。
何为 DistSQL
DistSQL 的意义
DistSQL 设计的目的是 打破中间件和数据库之间的界限,让开发者像使用数据库一样使用 Apache ShardingSphere。 因此 DistSQL 的设计会尽可能契合已有的数据库语法,进而降低学习成本;此外 DistSQL 的作用是对资源和规则进行 SQL 级别的管理,完全替代配置文件也是其优点之一。
开发 DistSQL
准备
b. 在 ANTLR preview 中输入需要校验的语句
在了解语法和插件的基础之上,还需要对 DistSQL 执行流程有一定认识。但 DistSQL 完整的执行流程较为繁琐,而 ShardingSphere 的良好的架构使得开发者不用关注整个流程也能完成 DistSQL 功能的开发。
开发 DistSQL 需要关注的核心流程如下,此处以分片功能为例,不同的功能对应的 Visitor 不同:
实战
在了解 DistSQL 执行流程之后,接下来将实战演示如何开发一条自己的 DistSQL。
现在,让我们提出一个新的需求:通过 DistSQL 快速查询各个分片表的分片数量。设计语法如下:
show sharding tables count [from schema] ;
在 src/main/antlr4/imports/sharding/RQLStatement.g4 文件中添加如下的语法定义,添加完成后可以使用 ANTLR v4 对语法定义进行测试。
在添加语法定义时需要考虑该语法中的关键字是否已经定义,此处的 COUNT 为未定义的关键字,需要在 src/main/antlr4/imports/sharding/Keyword.g4 中定义。 在语法定义之后还需将其添加到 ShardingDistSQLStatement.g4 文件中,该文件可以理解为解析的路由。
在完成以上步骤之后,对 shardingsphere-sharding-distsql-parser 进行编译生成语法对应的上下文对象。
在处理语法之前还需要在 shardingsphere-distsql-statement 添加一个与该语法定义对应的 DistSQLStatement 对象用于保存语句中的变量属性,例如当前语法定义中的 schemaName 需要保存至 DistSQLStatement 对象中。
在 ShardingSphere 中使用的是 ANTLR 的 Visitor 模式,因此对语法定义的处理需要在 ShardingDistSQLStatementVisitor 中重写 visitShowShardingTableCount 方法,该方法的目的为创建 ShowShardingTablesCountStatement 对象,并将语法中的变量属性保存到 DistSQLStatement 对象中。
shardingsphere-distsql-statement 存在 shardingsphere-sharding-distsql-parser 依赖关系,因此需要对 shardingsphere-distsql-statement 进行编译。
数据的处理主要由 Handler 或者 Executor 中的 execute 方法处理,结果主要由 getRowData 方法返回,但是对应不同类型的语法定义在侧重点上可能有所差异。其中结果返回的语法定义使用 DistSQLResultSet 作为结果存储的对象,会在 execute 方法中对结果数据进行组装。
本示例便是这种处理方式,以下为该示例对应的 DistSQLResultSet 。
在 ShardingTablesCountResultSet 中 init 方法负责数据的获取与组装, getRowData 方法负责对行数据的返回。此外不难发现该类中还有 getType 方法,该方法属于 TypedSPI 接口,所以 ShardingTablesCountResultSet 还需要在当前模块的 src/main/resources/META-INF/services 目录下增加 org.apache.shardingsphere.infra.distsql.query.DistSQLResultSet 文件来完成 SPI 的注入才能使用,路径与内容如下:
在完成基本的功能开发之后为了保证其持续的可用性需要对新增的类或者方法添加测试用例,对新增的语法添加解析测试,以下为 ShardingTablesCountResultSet 的单元测试。
除了单元测试以外还需要在 shardingsphere-parser-test 中添加对语法定义的解析测试,将输入的 DistSQL 解析成 DistSQLStatement 然后与预期的 TestCase 对象进行比较, 步骤如下。
a. 在 src/main/resources/sql/supported/rql/show.xml 中添加测试的 SQL;
b. 在 src/main/resources/case/rql/show.xml 添加测试的 case;
c. 添加 TestCase 对象用于保存 case 中定义的预期结果;
d. 使用 SQLParserTestCases 类将 TestCase 进行加载;
e. 添加对应的 Assert 对象 ,并将其加入到 ShowRulesStatementAssert 判断中;
f. 执行 DistSQLParserParameterizedTest 中的测试方法,至此测试告一段落。 最后可以在命令行工具中去执行开发完成的 DistSQL 检验功能。
结语
DistSQL 作为 5.0.0 版本发布的新特性之一,将会在此版本基础上持续发力,也希望更多的社区伙伴加入,构造更加完善的语法体系,提供更强大的功能,真正打破中间件与数据库之间的界限。
最后,DistSQL SIG 近日已成立,致力于 DistSQL 特性持续优化,拓展新的使用场景以及宣传答疑,欢迎大家点击 这里链接 关注,了解 DistSQL 以及 ShardingSphere 项目最新进展。
欢迎添加社区经理微信( ss_assistant_1 )进入交流群,与众多 ShardingSphere 爱好者一同交流进步