SQL 改写测试

目标

面向逻辑库与逻辑表书写的SQL,并不能够直接在真实的数据库中执行,SQL改写用于将逻辑SQL改写为在真实数据库中可以正确执行的SQL。 它包括正确性改写和优化改写两部分,所以 SQL 改写的测试都是基于这些改写方向进行校验的。

测试

SQL 改写测试用例位于 sharding-core/sharding-core-rewrite 下的 test 中。SQL 改写的测试主要依赖如下几个部分:

  • 测试引擎
  • 环境配置
  • 验证数据

测试引擎是 SQL 改写测试的入口,跟其他引擎一样,通过 Junit 的 Parameterized 逐条读取 test\resources 目录中测试类型下对应的 xml 文件,然后按读取顺序一一进行验证。

环境配置存放在 test\resources\yaml 路径中测试类型下对应的 yaml 中。配置了dataSources,shardingRule,encryptRule 等信息,例子如下:

  1. dataSources:
  2. db: !!com.zaxxer.hikari.HikariDataSource
  3. driverClassName: org.h2.Driver
  4. jdbcUrl: jdbc:h2:mem:db;DB_CLOSE_DELAY=-1;DATABASE_TO_UPPER=false;MODE=MYSQL
  5. username: sa
  6. password:
  7. ## sharding 规则
  8. rules:
  9. - !SHARDING
  10. tables:
  11. t_account:
  12. actualDataNodes: db.t_account_${0..1}
  13. tableStrategy:
  14. standard:
  15. shardingColumn: account_id
  16. shardingAlgorithmName: account_table_inline
  17. keyGenerateStrategy:
  18. column: account_id
  19. keyGeneratorName: snowflake
  20. t_account_detail:
  21. actualDataNodes: db.t_account_detail_${0..1}
  22. tableStrategy:
  23. standard:
  24. shardingColumn: order_id
  25. shardingAlgorithmName: account_detail_table_inline
  26. bindingTables:
  27. - t_account, t_account_detail
  28. shardingAlgorithms:
  29. account_table_inline:
  30. type: INLINE
  31. props:
  32. algorithm-expression: t_account_${account_id % 2}
  33. account_detail_table_inline:
  34. type: INLINE
  35. props:
  36. algorithm-expression: t_account_detail_${account_id % 2}
  37. keyGenerators:
  38. snowflake:
  39. type: SNOWFLAKE
  40. props:
  41. worker-id: 123

验证数据存放在 test\resources 路径中测试类型下对应的 xml 文件中。验证数据中, yaml-rule 指定了环境以及 rule 的配置文件,input 指定了待测试的 SQL 以及参数,output 指定了期待的 SQL 以及参数。 其中 db-type 决定了 SQL 解析的类型,默认为 SQL92, 例如:

  1. <rewrite-assertions yaml-rule="yaml/sharding/sharding-rule.yaml">
  2. <!-- 替换数据库类型需要在这里更改 db-type -->
  3. <rewrite-assertion id="create_index_for_mysql" db-type="MySQL">
  4. <input sql="CREATE INDEX index_name ON t_account ('status')" />
  5. <output sql="CREATE INDEX index_name ON t_account_0 ('status')" />
  6. <output sql="CREATE INDEX index_name ON t_account_1 ('status')" />
  7. </rewrite-assertion>
  8. </rewrite-assertions>

只需在 xml 文件中编写测试数据,配置好相应的 yaml 配置文件,就可以在不更改任何 Java 代码的情况下校验对应的 SQL 了。