#list #postgresql #query-parser #sql-parser #sql-query #wrapper #safe-wrapper

postgres-parser

PostgreSQL查询解析器的基于LLVM的安全包装器。目前基于v13

10个版本

0.2.3 2021年2月20日
0.2.1 2021年2月9日
0.2.0 2021年1月4日
0.1.9 2021年1月4日
0.0.4 2020年6月7日

#26 in #query-parser

每月 29 次下载
2 个crate中使用 (通过 inline-postgres-macros)

PostgreSQL

1MB
34K SLoC

Actions Status crates.io badge docs.rs badge Twitter Follow

postgres-parser

本项目是使用Postgres v13.0的SQL解析器(实际上是 gram.yList *raw_parser(const char *str) 函数)的起点。

此方法是通过下载Postgres源代码,修补一些Makefile(见 patches/makefiles-13.0.patch),编译成LLVM IR,优化/汇编成LLVM位码,进行链接时间优化(LTO),生成仅包含正确使用Postgres的 raw_parser() 函数所需的符号/代码的静态库,最后,使用Rust链接该库。

这是通过一个自定义的 build.rs 脚本实现的,它调用 build.sh 来执行所有艰苦的工作。

过程结束时,我们得到一个 libpostgres_parser.a 归档,该归档由 build.rs 指示 cargo 链接。

使用此crate

使用此crate与使用任何其他crate一样。将其添加到您的 Cargo.toml 依赖中

[dependencies]
postgres-parser = "0.2.2"

此外,请参阅下面的 系统要求 部分。

以下是一个简单的示例,它以JSON格式输出SQL解析树。

use postgres_parser::*;

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let query_string = args.get(1).expect("no arguments");
    let parse_list = match parse_query(query_string) {
        Ok(query) => query,
        Err(e) => {
            eprintln!("{:?}", e);
            std::process::exit(1);
        }
    };

    let as_json = serde_json::to_string_pretty(&parse_list).expect("failed to convert to json");
    println!("{}", as_json);
}

系统要求

对于基于Ubuntu的Linux系统,您需要

$ sudo apt-get install clang llvm make curl
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

对于MacOS,您需要

$ brew install wget
$ brew install llvm
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

就Linux系统而言,目前已在Ubuntu 18.04(使用LLVM 6.0.0)和Ubuntu 20.04(使用LLVM 10.0.0)上进行了测试。

请确保LLVM和clang工具已添加到您的$PATH环境变量中。特别是clangoptllvm-ar工具。

构建

就像构建任何其他Rust二进制crate一样构建它

$ cargo build [--release]

这个过程会花费一些时间,因为构建过程

  • 下载Postgres源代码
  • 配置Postgres
  • 编译Postgres(并行编译,最多达到您CPU的核心数)
  • 将生成的LLVM ir优化成LLVM位码

在我的较新的MacBook Pro 16"上,这个过程第一次需要大约2.5分钟。

在我的非常旧的Mac Mini上,运行Ubuntu 16.04(天哪!),这个过程需要大约25分钟。所以如果您使用的是旧电脑,请耐心等待。

后续构建(假设没有执行cargo clean)可以省略所有上述步骤,因为最终的libpostgres_parser.a存档工件已缓存在target/目录中。

已知问题

  • 虽然postgres解析器支持UTF8输入,但启用此功能似乎会导致生成的编译二进制文件膨胀到近10兆字节。看起来,包含Postgres的SetDatabaseEncoding函数会导致LLVM的opt无法正确执行全局死代码消除。目前正在调查此问题。因此,输入必须匹配Postgres的SQL_ASCII编码。

  • 使用XCode >=11.4.0在MacOS上构建不起作用。这似乎是这些版本的XCode的问题。这是bug:[https://openradar.appspot.com/FB7647406](https://openradar.appspot.com/FB7647406)。在构建Postgres时会发生这种情况。如果您有任何解决方案的建议,将非常感谢。

  • 单线程查询解析... Postgres不是线程安全的,因此在解析查询时我们需要锁定Mutex。这意味着一次只能处理一个。未来可能会有一些事情可以做以改善这种情况。根本的困境在于Postgres如何分配内存,而将Postgres解析器嵌入到系统中需要使用这种系统

请帮助!

我们真诚地感谢您花时间克隆此存储库并至少尝试执行cargo test --all。如果它不起作用,或者如果这些说明有误,我们肯定想知道。我们希望这对每个人来说都尽可能简单。

此外,这是v0.0.1。请随时提交错误报告、功能请求,特别是Pull Requests。

谢谢

感谢您查看这个项目。[GitHub赞助链接](https://github.com/sponsors/eeeebbbbrrrr)。

如果您喜欢我们正在做的事情以及它的方向,您的赞助将使我们保持动力。

依赖项

~0.4–2.8MB
~58K SLoC