# 一、概要 SQLsmith是一个随机SQL查询生成器。它的典范是[Csmith](https://github.com/csmith-project/csmith)(它被证明对C编译器的质量保证很有价值)。 本文介绍使用SQLsmith对PostgreSQL数据库进行模糊测试方法。 # 二、环境 - OS:CentOS 8 - PostgreSQL版本:v18 - SQLsmith版本:v1.4 # 三、编译安装 ## 准备编译环境 要求: - cmake >= 3.14 - g++支持C++17 ## 安装PostgreSQL 请自行安装PostgreSQL,过程略。 ## 获取SQLsmith源码 ```bash # clone仓库 git clone https://github.com/anse1/sqlsmith.git cd sqlsmith # 切换到v1.4 tag git checkout v1.4 ``` ## 依赖 SQLsmith依赖`libpqxx`(libpq的C++版本),编译SQLsmith时可以指定已安装的libpqxx,也可以从上游[libpqxx](https://github.com/jtv/libpqxx)仓库现取代码并编译。参考`sqlsmith/CMakeLists.txt`代码段: ```cmake if (NOT USE_UPSTREAM_LIBPQXX) # If we use the system pqxx library, we have to check for libpq. # This check is done by the CMakeLists.txt of the libpqxx project otherwise find_package(PQXX REQUIRED) ... else (NOT USE_UPSTREAM_LIBPQXX) set(SKIP_BUILD_TEST TRUE) include(FetchContent) FetchContent_Declare( libpqxx GIT_REPOSITORY https://github.com/jtv/libpqxx.git GIT_TAG 7.6.0 ) ... endif (NOT USE_UPSTREAM_LIBPQXX) ``` **方法1:安装libpqxx** 使用yum安装libpqxx: ``` sudo yum install libpqxx libpqxx-devel ``` 请注意,如果使用本方法安装libpqxx,请修改`sqlsmith/CMakeLists.txt`: ``` set(CMAKE_CXX_STANDARD 17) ``` 修改为: ``` set(CMAKE_CXX_STANDARD 11) ``` 否则,后续编译报错: ``` /usr/include/pqxx/tuple.hxx:95:33: error: ISO C++17 does not allow dynamic exception specifications 95 | reference at(size_type) const throw (pqxx::range_error); //[t11] | ^~~~~ /usr/include/pqxx/tuple.hxx:96:27: error: ISO C++17 does not allow dynamic exception specifications 96 | reference at(int) const throw (pqxx::range_error); //[t11] | ^~~~~ ... /usr/include/pqxx/result.hxx:135:35: error: ISO C++17 does not allow dynamic exception specifications 135 | const tuple at(size_type) const throw (range_error); //[t10] ``` **方法2:取上游libpqxx** 通过指定cmake参数`USE_UPSTREAM_LIBPQXX=ON`,从上游`libpqxx`仓库现取代码并编译。 本文使用**方法2**。 ## 编译参数 使用`pg_config`取PostgreSQL配置参数(下一节中`cmake`命令使用): ```bash pg_config --includedir pg_config --libdir ``` ## 编译 ```bash cd sqlsmith mkdir build cd build cmake3 .. -DPostgreSQL_LIBRARY={path of libdir}/libpq.so -DPostgreSQL_INCLUDE_DIR={path of includedir} -DPostgreSQL_TYPE_INCLUDE_DIR={path of includedir} -DUSE_UPSTREAM_LIBPQXX=ON make ``` # 四、测试 ```bash cd sqlsmith/build/ ./sqlsmith --verbose --target="post=5432 dbname=test" ``` `--target`参数请修改为PostgreSQL实际值,其中,dbname对应的数据库需要预先创建准备好。 # 五、参考 1. [Finding and understanding bugs in C compilers](https://dl.acm.org/doi/10.1145/1993498.1993532) 2. [SQLsmith](https://github.com/anse1/sqlsmith) 3. [SQLSmith 开源项目教程](https://blog.csdn.net/gitblog_01122/article/details/141376347) 4. [如何利用随机化的 SQL 测试来帮助检测错误](https://juejin.cn/post/7261808673034813499)