79 个版本

0.7.4 2023 年 3 月 14 日
0.7.2 2023 年 2 月 23 日
0.6.1 2022 年 12 月 6 日
0.6.0-alpha.22022 年 11 月 18 日
0.0.8 2020 年 7 月 28 日

#319 in 数据库接口

Download history 51/week @ 2024-04-08 59/week @ 2024-04-15 44/week @ 2024-04-22 32/week @ 2024-04-29 30/week @ 2024-05-06 29/week @ 2024-05-13 105/week @ 2024-05-20 32/week @ 2024-05-27 46/week @ 2024-06-03 74/week @ 2024-06-10 23/week @ 2024-06-17 50/week @ 2024-06-24 18/week @ 2024-07-01 63/week @ 2024-07-08 13/week @ 2024-07-15 58/week @ 2024-07-22

163 每月下载量
用于 pg_jq

MIT 许可证

625KB
12K SLoC

cargo-pgx

cargo-pgx 是一个用于管理基于 pgx 的 Postgres 扩展的 Cargo 子命令。

在您的扩展开发过程中,您将希望使用 cargo pgx。它自动执行创建新的 Rust crate 项目、自动生成您的扩展的 SQL 架构、在本地安装您的扩展以与 Postgres 进行测试,以及针对一个或多个 Postgres 版本运行测试套件的过程。

您可以在以下链接中找到其功能的视频演示: https://www.twitch.tv/videos/684087991

安装

通过 crates.io 安装

$ cargo install --locked cargo-pgx

随着 pgx 的新版本发布,您需要确保再次运行此命令以更新它。当您更新 rustc 时,也应重新安装 cargo-pgx,以确保使用相同的编译器来构建 cargo-pgx 和您的 Postgres 扩展。您可以通过传递 --force 来强制 cargo 重新安装现有的 crate。

用法

$ cargo pgx --help
cargo-pgx 0.5.0
ZomboDB, LLC <[email protected]>
Cargo subcommand for 'pgx' to make Postgres extension development easy

USAGE:
    cargo pgx [OPTIONS] <SUBCOMMAND>

OPTIONS:
    -h, --help       Print help information
    -v, --verbose    Enable info logs, -vv for debug, -vvv for trace
    -V, --version    Print version information

SUBCOMMANDS:
    connect    Connect, via psql, to a Postgres instance
    get        Get a property from the extension control file
    help       Print this message or the help of the given subcommand(s)
    init       Initialize pgx development environment for the first time
    install    Install the extension from the current crate to the Postgres specified by
                   whatever `pg_config` is currently on your $PATH
    new        Create a new extension crate
    package    Create an installation package directory
    run        Compile/install extension to a pgx-managed Postgres instance and start psql
    schema     Generate extension schema files
    start      Start a pgx-managed Postgres instance
    status     Is a pgx-managed Postgres instance running?
    stop       Stop a pgx-managed Postgres instance
    test       Run the test suite for this crate

环境变量

  • PGX_HOME - 如果设置,将覆盖 pgx 的默认目录 ~/.pgx/
  • PGX_BUILD_FLAGS - 如果在 cargo pgx run/test/install 期间设置,这些附加标志将在构建扩展时传递给 cargo build
  • PGX_BUILD_VERBOSE - 设置为 true 以启用详细的 "build.rs" 输出 -- 对于调试构建问题很有用
  • HTTPS_PROXY - 如果在 cargo pgx init 期间设置,它将使用这些代理设置下载 Postgres 源代码。更多详细信息请参阅 env_proxy crate 文档
  • PGX_IGNORE_RUST_VERSIONS - 设置为 true 以禁用执行模式生成时的 rustc 版本检查(模式生成需要与构建 cargo-pgx 的 crate 相同的 rustc 版本)

首次初始化

$ cargo pgx init
  Discovered Postgres v15.0, v14.5, v13.8, v12.12, v11.17
  Downloading Postgres v15.0 from https://ftp.postgresql.org/pub/source/v15.0/postgresql-15.0.tar.bz2
  Downloading Postgres v11.17 from https://ftp.postgresql.org/pub/source/v11.17/postgresql-11.17.tar.bz2
  Downloading Postgres v12.12 from https://ftp.postgresql.org/pub/source/v12.12/postgresql-12.12.tar.bz2
  Downloading Postgres v13.8 from https://ftp.postgresql.org/pub/source/v13.8/postgresql-13.8.tar.bz2
  Downloading Postgres v14.5 from https://ftp.postgresql.org/pub/source/v14.5/postgresql-14.5.tar.bz2
     Removing /home/yourself/.pgx/11.17
    Untarring Postgres v11.17 to /home/yourself/.pgx/11.17
     Removing /home/yourself/.pgx/14.5
     Removing /home/yourself/.pgx/12.12
    Untarring Postgres v14.5 to /home/yourself/.pgx/14.5
    Untarring Postgres v12.12 to /home/yourself/.pgx/12.12
     Removing /home/yourself/.pgx/15.0
     Removing /home/yourself/.pgx/13.8
    Untarring Postgres v15.0 to /home/yourself/.pgx/15.0
    Untarring Postgres v13.8 to /home/yourself/.pgx/13.8
  Configuring Postgres v11.17
  Configuring Postgres v12.12
  Configuring Postgres v14.5
  Configuring Postgres v13.8
  Configuring Postgres v15.0
    Compiling Postgres v11.17
    Compiling Postgres v12.12
    Compiling Postgres v13.8
    Compiling Postgres v14.5
    Compiling Postgres v15.0
   Installing Postgres v11.17 to /home/yourself/.pgx/11.17/pgx-install
   Installing Postgres v12.12 to /home/yourself/.pgx/12.12/pgx-install
   Installing Postgres v13.8 to /home/yourself/.pgx/13.8/pgx-install
   Installing Postgres v14.5 to /home/yourself/.pgx/14.5/pgx-install
   Installing Postgres v15.0 to /home/yourself/.pgx/15.0/pgx-install
   Validating /home/yourself/.pgx/11.17/pgx-install/bin/pg_config
   Validating /home/yourself/.pgx/12.12/pgx-install/bin/pg_config
   Validating /home/yourself/.pgx/13.8/pgx-install/bin/pg_config
   Validating /home/yourself/.pgx/14.5/pgx-install/bin/pg_config
   Validating /home/yourself/.pgx/15.0/pgx-install/bin/pg_config

cargo pgx init 需要运行一次以正确配置 pgx 开发环境。

如上图所示,它下载了 Postgres v11、v12、v13、v14、v15 的最新版本,配置它们,编译它们,并将它们安装到 ~/.pgx/,包括 Postgres 包含的所有 contrib 扩展和工具。其他 pgx 命令如 runtest 将完全管理和使用这些 Postgres 安装。

pgx 被设计成以支持多种 Postgres 版本,在开发过程中,您会知道是否正在尝试使用一个在所有版本中不常见的 Postgres API。它还被设计成易于测试您的扩展与这些版本。这就是为什么它要求您在开发期间拥有所有完全编译并安装的 Postgres 版本。

当 pgx 使用的默认端口用于在内部运行 PostgreSQL 不可用的情况下,可以在初始化期间使用 --base-port--base-testing-port 选项指定自定义值。这种用法之一是在开发多个扩展的同时使用多个 pgx 安装(使用 $PGX_HOME 变量)。这些值可以在后续的 $PGX_HOME/config.toml 中更改。

如果您想使用操作系统的软件包管理器安装 Postgres,cargo pgx init 有可选参数,允许您指定它们安装的位置(见下文)。

您告诉 cargo pgx init 是每个版本 pg_config 的完整路径。

对于您指定的任何版本,cargo pgx init 将跳过下载/编译/安装它。然后 pgx 将像使用它自己下载/编译/安装的任何版本一样使用本地安装的版本。

但是,如果 "pg_config 路径" 是字面字符串 download,那么 pgx 将为您下载并编译该版本的 Postgres。

当指定了各种 --pgXX 选项时,这些是 pgx 将为您管理的唯一的 Postgres 版本。

您还需要确保为每个您想要自行管理的版本安装了 "postgresql-server-dev" 软件包。

完成后,cargo pgx init 还会创建一个配置文件(~/.pgx/config.toml),用于描述每个版本的 pg_config 工具的位置。

如果将来发布了新的 Postgres 小版本,您可以简单地再次运行 cargo pgx init [args],您的本地版本将被更新,同时保留所有现有数据库和配置。

cargo-pgx-init 0.5.0
ZomboDB, LLC <[email protected]>
Initialize pgx development environment for the first time

USAGE:
    cargo pgx init [OPTIONS]

OPTIONS:
        --base-port <BASE_PORT>
            Base port number

        --base-testing-port <BASE_TESTING_PORT>
            Base testing port number

    -h, --help           Print help information
        --pg11 <PG11>    If installed locally, the path to PG11's `pgconfig` tool, or `download` to
                         have pgx download/compile/install it [env: PG11_PG_CONFIG=]
        --pg12 <PG12>    If installed locally, the path to PG12's `pgconfig` tool, or `download` to
                         have pgx download/compile/install it [env: PG12_PG_CONFIG=]
        --pg13 <PG13>    If installed locally, the path to PG13's `pgconfig` tool, or `download` to
                         have pgx download/compile/install it [env: PG13_PG_CONFIG=]
        --pg14 <PG14>    If installed locally, the path to PG14's `pgconfig` tool, or `download` to
                         have pgx download/compile/install it [env: PG14_PG_CONFIG=]
        --pg15 <PG15>    If installed locally, the path to PG15's `pgconfig` tool, or `download` to
                         have pgx download/compile/install it [env: PG15_PG_CONFIG=]
    -v, --verbose        Enable info logs, -vv for debug, -vvv for trace
    -V, --version        Print version information

创建新扩展

$ cargo pgx new example
$ ls example/
Cargo.toml  example.control  sql  src

cargo pgx new <extname> 是开始创建新扩展的简单方法。它类似于 cargo new <name>,但还做了支持构建 Rust Postgres 扩展所需的其他事情。

如果您想要创建一个 "后台工作进程",请指定 --bgworker 参数。

cargo pgx new 不会将目录初始化为 git 仓库,但会创建一个 .gitignore 文件,以防您决定这样做。

工作空间用户: cargo pgx new $NAME 将创建一个 $NAME/.cargo/config,您应该将其移动到工作空间根目录下的 .cargo./config 中。

如果不这样做,您可能会在使用 Rust-Analyzer 等工具时遇到不必要的重建,因为它将使用错误的 rustflags 选项。

$ cargo pgx new --help
cargo-pgx-new 0.5.0
ZomboDB, LLC <[email protected]>
Create a new extension crate

USAGE:
    cargo pgx new [OPTIONS] <NAME>

ARGS:
    <NAME>    The name of the extension

OPTIONS:
    -b, --bgworker    Create a background worker template
    -h, --help        Print help information
    -v, --verbose     Enable info logs, -vv for debug, -vvv for trace
    -V, --version     Print version information

管理您的 Postgres 安装

$ cargo pgx status all
Postgres v11 is stopped
Postgres v12 is stopped
Postgres v13 is stopped
Postgres v14 is stopped
Postgres v15 is stopped

$ cargo pgx start all
    Starting Postgres v11 on port 28811
    Starting Postgres v12 on port 28812
    Starting Postgres v13 on port 28813
    Starting Postgres v14 on port 28814
    Starting Postgres v15 on port 28815

$ cargo pgx status all
Postgres v11 is running
Postgres v12 is running
Postgres v13 is running
Postgres v14 is running
Postgres v15 is running

$ cargo pgx stop all
    Stopping Postgres v11
    Stopping Postgres v12
    Stopping Postgres v13
    Stopping Postgres v14
    Stopping Postgres v15

cargo pgx 有三个命令用于管理每个 Postgres 安装:startstopstatus。此外,cargo pgx run(见下文)将在目标 Postgres 实例尚未运行的情况下自动启动它。

启动Postgres实例时,pgx会在端口28800 + PG_MAJOR_VERSION上启动,所以Postgres 11运行在端口28811,12运行在端口28812,依此类推。此外,第一次启动这些实例中的任何一个时,它会自动在~/.pgx/data-[11 | 12 | 13 | 14 | 15]目录中初始化一个PGDATA目录。这样做允许pgx管理它安装的Postgres版本或计算机上已有的版本,并确保在后者的情况下,pgx管理的版本不会与已运行的版本冲突。实例的区域设置为C.UTF-8(或等价地,在macOS上具有ctypeUTF8C区域),或者如果不可用,则使用C区域。

pgx不会拆除这些实例。虽然它们存储在您主目录中的一个隐藏目录中,但pgx认为这些是重要的永久性数据库安装。

启动后,您可以使用psql(如果您已在您的$PATH上安装了它)来连接到它们,如下所示:psql -p 28812。然而,您可能只想使用cargo pgx run命令。

编译和运行您的扩展

$ cargo pgx run pg13
building extension with features ``
"cargo" "build" "--message-format=json-render-diagnostics"
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s

installing extension
     Copying control file to /home/ana/.pgx/13.5/pgx-install/share/postgresql/extension/strings.control
     Copying shared library to /home/ana/.pgx/13.5/pgx-install/lib/postgresql/strings.so
    Building for SQL generation with features ``
    Finished dev [unoptimized + debuginfo] target(s) in 0.07s
 Discovering SQL entities
  Discovered 6 SQL entities: 0 schemas (0 unique), 6 functions, 0 types, 0 enums, 0 sqls, 0 ords, 0 hashes, 0 aggregates
     Writing SQL entities to /home/ana/.pgx/13.5/pgx-install/share/postgresql/extension/strings--0.1.0.sql
    Finished installing strings
    Starting Postgres v13 on port 28813
    Re-using existing database strings
psql (13.5)
Type "help" for help.

strings=# DROP EXTENSION strings;
ERROR:  extension "strings" does not exist
strings=# CREATE EXTENSION strings;
CREATE EXTENSION
strings=# \df strings.*
                                      List of functions
 Schema  |     Name      | Result data type |           Argument data types            | Type
---------+---------------+------------------+------------------------------------------+------
 strings | append        | text             | input text, extra text                   | func
 strings | return_static | text             |                                          | func
 strings | split         | text[]           | input text, pattern text                 | func
 strings | split_set     | SETOF text       | input text, pattern text                 | func
 strings | substring     | text             | input text, start integer, "end" integer | func
 strings | to_lowercase  | text             | input text                               | func
(6 rows)

strings=# select strings.to_lowercase('PGX');
 to_lowercase
--------------
 pgx
(1 row)

cargo pgx run <pg11 | pg12 | pg13 | pg14 | pg15>是编译和开发期间交互式测试/使用您的扩展的主要接口。

您第一次执行cargo pgx run pgXX时,需要编译的不仅仅是您的扩展,还有pgx本身及其所有依赖项。根据您的计算机,这可能需要一点时间(pgx在计算为Postgres生成的绑定时几乎有20k行Rust代码)。然而,之后(如上图所示),它会相当快。

cargo pgx run 编译您的扩展,将其安装到指定的 Postgres 安装程序中,正如其 pg_config 工具所描述的那样,使用与 cargo pgx start pgXX 相同的过程启动该 Postgres 实例,并自动将您放入连接到数据库的 psql 命令行界面,默认情况下,名称与您的扩展相同。从那里开始,创建和使用您的扩展就由您来决定了。

这也是 pgx 通过 sql-generator 二进制文件自动为您生成扩展 SQL 架构的阶段。

当您退出 psql 时,Postgres 实例将继续在后台运行。

对于已安装在您计算机上的 Postgres 安装,cargo pgx run 需要写入权限到由 pg_config --pkglibdirpg_config --sharedir 描述的目录。您需要决定如何实现这一点。虽然单个 Postgres 安装可以在不同的端口和不同的数据目录中多次启动,但它不支持多个“扩展库目录”。

$ cargo pgx run --help
cargo-pgx-run 0.5.0
ZomboDB, LLC <[email protected]>
Compile/install extension to a pgx-managed Postgres instance and start psql

USAGE:
    cargo pgx run [OPTIONS] [ARGS]

ARGS:
    <PG_VERSION>    Do you want to run against Postgres `pg11`, `pg12`, `pg13`, `pg14`,
                    `pg15`? [env: PG_VERSION=]
    <DBNAME>        The database to connect to (and create if the first time).  Defaults to a
                    database with the same name as the current extension name

OPTIONS:
        --all-features
            Activate all available features

        --features <FEATURES>
            Space-separated list of features to activate

    -h, --help
            Print help information

        --manifest-path <MANIFEST_PATH>
            Path to Cargo.toml

        --no-default-features
            Do not activate the `default` feature

    -p, --package <PACKAGE>
            Package to build (see `cargo help pkgid`)

        --pgcli
            Use an existing `pgcli` on the $PATH [env: PGX_PGCLI=]

        --profile <PROFILE>
            Specific profile to use (conflicts with `--release`)

    -r, --release
            Compile for release mode (default is debug)

    -v, --verbose
            Enable info logs, -vv for debug, -vvv for trace

    -V, --version
            Print version information

连接到数据库

$ cargo pgx connect
    Re-using existing database strings
psql (13.5)
Type "help" for help.

strings=# select strings.to_lowercase('PGX');
 to_lowercase
--------------
 pgx
(1 row)

strings=#

如果您只想连接到一个无需重新编译和安装扩展的托管版本,请使用 cargo pgx connect <pg11 | pg12 | pg13 | pg14 | pg15>

此命令将使用默认的数据库,数据库名称与您的扩展相同,或者您可以在最后一个参数中指定另一个数据库名称。

如果指定的数据库不存在,cargo pgx connect 将创建它。同样,如果指定的 Postgres 版本没有运行,它将自动启动。

cargo-pgx-connect 0.5.
ZomboDB, LLC <[email protected]>
Connect, via psql, to a Postgres instance

USAGE:
    cargo pgx connect [OPTIONS] [ARGS]

ARGS:
    <PG_VERSION>    Do you want to run against Postgres `pg11`, `pg12`, `pg13`, `pg14`,
                    `pg15`? [env: PG_VERSION=]
    <DBNAME>        The database to connect to (and create if the first time).  Defaults to a
                    database with the same name as the current extension name [env: DBNAME=]

OPTIONS:
    -h, --help
            Print help information

        --manifest-path <MANIFEST_PATH>
            Path to Cargo.toml

    -p, --package <PACKAGE>
            Package to determine default `pg_version` with (see `cargo help pkgid`)

        --pgcli
            Use an existing `pgcli` on the $PATH [env: PGX_PGCLI=]

    -v, --verbose
            Enable info logs, -vv for debug, -vvv for trace

    -V, --version
            Print version information

在本地安装您的扩展

$ cargo pgx install
building extension with features ``
"cargo" "build" "--message-format=json-render-diagnostics"
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s

installing extension
     Copying control file to /usr/share/postgresql/13/extension/strings.control
     Copying shared library to /usr/lib/postgresql/13/lib/strings.so
    Building for SQL generation with features ``
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s
 Discovering SQL entities
  Discovered 6 SQL entities: 0 schemas (0 unique), 6 functions, 0 types, 0 enums, 0 sqls, 0 ords, 0 hashes, 0 aggregates
     Writing SQL entities to /usr/share/postgresql/13/extension/strings--0.1.0.sql
    Finished installing strings

如果出于某种原因,您不喜欢使用 cargo pgx run <PG_VERSION>,则可以使用 cargo pgx install 将您的扩展安装到当前在您的 $PATH 上的 pg_config 工具所描述的 Postgres 安装程序。

您需要写入权限到由 pg_config --pkglibdirpg_config --sharedir 描述的目录。

默认情况下,cargo pgx install 以调试模式构建您的扩展。指定 --release 将改变这一点。

$ cargo pgx install --help
cargo-pgx-install 0.5.0
ZomboDB, LLC <[email protected]>
Install the extension from the current crate to the Postgres specified by whatever `pg_config` is
currently on your $PATH

USAGE:
    cargo pgx install [OPTIONS]

OPTIONS:
        --all-features
            Activate all available features

    -c, --pg-config <PG_CONFIG>
            The `pg_config` path (default is first in $PATH)

        --features <FEATURES>
            Space-separated list of features to activate

    -h, --help
            Print help information

        --manifest-path <MANIFEST_PATH>
            Path to Cargo.toml

        --no-default-features
            Do not activate the `default` feature

    -p, --package <PACKAGE>
            Package to build (see `cargo help pkgid`)

        --profile <PROFILE>
            Specific profile to use (conflicts with `--release`)

    -r, --release
            Compile for release mode (default is debug)

        --test
            Build in test mode (for `cargo pgx test`)

    -v, --verbose
            Enable info logs, -vv for debug, -vvv for trace

    -V, --version
            Print version information

测试您的扩展

$ cargo pgx test
"cargo" "test" "--features" " pg_test"
    Finished test [unoptimized + debuginfo] target(s) in 0.07s
     Running unittests (target/debug/deps/spi-312296af509607bc)

running 2 tests
building extension with features ` pg_test`
"cargo" "build" "--features" " pg_test" "--message-format=json-render-diagnostics"
    Finished dev [unoptimized + debuginfo] target(s) in 0.06s

installing extension
     Copying control file to /home/ana/.pgx/13.5/pgx-install/share/postgresql/extension/spi.control
     Copying shared library to /home/ana/.pgx/13.5/pgx-install/lib/postgresql/spi.so
    Building for SQL generation with features ` pg_test`
    Finished test [unoptimized + debuginfo] target(s) in 0.07s
 Discovering SQL entities
  Discovered 11 SQL entities: 1 schemas (1 unique), 8 functions, 0 types, 0 enums, 2 sqls, 0 ords, 0 hashes, 0 aggregates
     Writing SQL entities to /home/ana/.pgx/13.5/pgx-install/share/postgresql/extension/spi--0.0.0.sql
    Finished installing spi
test tests::pg_test_spi_query_by_id_direct ... ok
test tests::pg_test_spi_query_by_id_via_spi ... ok

test result: ok. 2 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 1.61s

Stopping Postgres

cargo pgx test [pg11 | pg12 | pg13 | pg14 | pg15] 运行您的 #[test]#[pg_test] 标注的函数,使用 cargo 的测试系统。

在测试过程中,pgx./target/pgx-test-data-PGVER/ 目录启动一个临时的 Postgres 实例,其 PGDATA 目录。这个 Postgres 实例在测试框架完成后停止。临时实例的区域设置为 C.UTF-8(或在 macOS 上等效于具有 ctypeUTF8C 区域),如果 C.UTF-8 区域不可用,则设置为 C

输出是标准的 "cargo test" 输出和一些 Postgres 日志输出。如果测试失败,失败报告将包括由特定测试生成的任何 Postgres 日志消息。

Rust 的 #[test] 函数表现正常,而 #[pg_test] 函数在 Postgres 实例中运行,并具有对 Postgres 内部结构的完全访问权限。所有测试都并行运行,无论其类型如何。

此外,一个 #[pg_test] 函数在一个事务中运行,当测试完成后事务会被中止。因此,它对数据库所做的任何更改都不会被保留。

cargo-pgx-test 0.5.0
ZomboDB, LLC <[email protected]>
Run the test suite for this crate

USAGE:
    cargo pgx test [OPTIONS] [ARGS]

ARGS:
    <PG_VERSION>    Do you want to run against Postgres `pg11`, `pg12`, `pg13`, `pg14`,
                    `pg15`, or `all`? [env: PG_VERSION=]
    <TESTNAME>      If specified, only run tests containing this string in their names

OPTIONS:
        --all-features
            Activate all available features

        --features <FEATURES>
            Space-separated list of features to activate

    -h, --help
            Print help information

        --manifest-path <MANIFEST_PATH>
            Path to Cargo.toml

    -n, --no-schema
            Don't regenerate the schema

        --no-default-features
            Do not activate the `default` feature

    -p, --package <PACKAGE>
            Package to build (see `cargo help pkgid`)

        --profile <PROFILE>
            Specific profile to use (conflicts with `--release`)

    -r, --release
            compile for release mode (default is debug)

    -v, --verbose
            Enable info logs, -vv for debug, -vvv for trace

    -V, --version
            Print version information

构建安装包

$ cargo pgx package
building extension with features ``
"cargo" "build" "--release" "--message-format=json-render-diagnostics"
    Finished release [optimized] target(s) in 0.07s

installing extension
     Copying control file to target/release/spi-pg13/usr/share/postgresql/13/extension/spi.control
     Copying shared library to target/release/spi-pg13/usr/lib/postgresql/13/lib/spi.so
    Building for SQL generation with features ``
    Finished release [optimized] target(s) in 0.07s
 Discovering SQL entities
  Discovered 8 SQL entities: 0 schemas (0 unique), 6 functions, 0 types, 0 enums, 2 sqls, 0 ords, 0 hashes, 0 aggregates
     Writing SQL entities to target/release/spi-pg13/usr/share/postgresql/13/extension/spi--0.0.0.sql
    Finished installing spi

cargo pgx package [--debug]--release 模式下构建您的扩展,到一个由 pg_config 工具从您的 $PATH 上的 Postgres 安装路径信息创建的目录结构 ./target/[debug | release]/extension_name-PGVER

目标是切换到该目录并构建一个 tarball 或 .deb 或 .rpm 包。

cargo pgx package 创建的目录结构从文件系统的根目录开始,因为已安装的包管理器可能将 pg_config --pkglibdirpg_config --sharedir 分割到不同的基本路径。

(如上图示例截图所示,使用 cargo pgx package 构建目录结构,该结构使用我手动安装的 Postgres 12 版本。)

此命令在 Dockerfile 中很有用,例如,可以自动化构建各种 Linux 发行版或 MacOS Postgres 安装程序的安装包。

$ cargo pgx package --help
cargo-pgx-package 0.5.0
ZomboDB, LLC <[email protected]>
Create an installation package directory

USAGE:
    cargo pgx package [OPTIONS]

OPTIONS:
        --all-features
            Activate all available features

    -c, --pg-config <PG_CONFIG>
            The `pg_config` path (default is first in $PATH)

    -d, --debug
            Compile for debug mode (default is release)

        --features <FEATURES>
            Space-separated list of features to activate

    -h, --help
            Print help information

        --manifest-path <MANIFEST_PATH>
            Path to Cargo.toml

        --no-default-features
            Do not activate the `default` feature

        --out-dir <OUT_DIR>
            The directory to output the package (default is
            `./target/[debug|release]/extname-pgXX/`)

    -p, --package <PACKAGE>
            Package to build (see `cargo help pkgid`)

        --profile <PROFILE>
            Specific profile to use (conflicts with `--debug`)

        --test
            Build in test mode (for `cargo pgx test`)

    -v, --verbose
            Enable info logs, -vv for debug, -vvv for trace

    -V, --version
            Print version information

检查您的扩展模式

如果您只想查看 pgx 将生成的完整扩展模式,请使用 cargo pgx schema

$ cargo pgx schema --help
cargo-pgx-schema 0.5.0
ZomboDB, LLC <[email protected]>
Generate extension schema files

USAGE:
    cargo pgx schema [OPTIONS] [PG_VERSION]

ARGS:
    <PG_VERSION>    Do you want to run against Postgres `pg11`, `pg12`, `pg13`, `pg14`,
                    `pg15`?

OPTIONS:
        --all-features
            Activate all available features

    -c, --pg-config <PG_CONFIG>
            The `pg_config` path (default is first in $PATH)

    -d, --dot <DOT>
            A path to output a produced GraphViz DOT file

        --features <FEATURES>
            Space-separated list of features to activate

    -h, --help
            Print help information

        --manifest-path <MANIFEST_PATH>
            Path to Cargo.toml

        --no-default-features
            Do not activate the `default` feature

    -o, --out <OUT>
            A path to output a produced SQL file (default is `stdout`)

    -p, --package <PACKAGE>
            Package to build (see `cargo help pkgid`)

        --profile <PROFILE>
            Specific profile to use (conflicts with `--release`)

    -r, --release
            Compile for release mode (default is debug)

        --skip-build
            Skip building a fresh extension shared object

        --test
            Build in test mode (for `cargo pgx test`)

    -v, --verbose
            Enable info logs, -vv for debug, -vvv for trace

    -V, --version
            Print version information

实验性:版本化共享对象支持

pgx 实验性支持生成版本化共享库的选项。这允许安装扩展的不同版本可以并行安装,并且可以启用在扩展版本之间弃用(和删除)函数。使用此功能时必须注意一些限制。因此,目前该功能是实验性的。

激活

通过从扩展的 .control 文件中移除 module_pathname 配置值来启用版本化共享对象支持。

概念

Postgres 对 C 扩展在版本之间保持 ABI 兼容性有隐式要求。此功能背后的想法是在新版本与旧版本不兼容时,允许两个版本的扩展之间进行互操作。

操作机制是版本化共享库文件的名称,并硬编码函数定义以指向版本化的共享库文件。没有版本化共享对象支持,C 函数的 SQL 定义如下所示

CREATE OR REPLACE FUNCTION "hello_extension"() RETURNS text /* &str */
STRICT
LANGUAGE c /* Rust */
AS 'MODULE_PATHNAME', 'hello_extension_wrapper';

MODULE_PATHNAME 由 Postgres 替换为 .control 文件中的配置值。对于基于 pgx 的扩展,这通常设置为 $libdir/<extension-0.0.0.so

使用版本化共享对象支持时,相同的 SQL 将如下所示

CREATE OR REPLACE FUNCTION "hello_extension"() RETURNS text /* &str */
STRICT
LANGUAGE c /* Rust */
AS '$libdir/extension-0.0.0', 'hello_extension_wrapper';

请注意,版本化共享库在函数定义中是硬编码的。这对应于 pgx 生成的 extension-0.0.0.so 文件。

重要的是要注意,输出的 SQL 是版本相关的。这意味着在版本升级脚本中必须重新定义所有先前定义的 C 函数,以便指向当前版本化的 so。例如,当将扩展版本更新到 0.1.0 时,共享对象将被命名为 <extension-0.1.0.so,而 cargo pgx schema 将为上述函数生成以下 SQL

CREATE OR REPLACE FUNCTION "hello_extension"() RETURNS text /* &str */
STRICT
LANGUAGE c /* Rust */
AS '$libdir/extension-0.1.0', 'hello_extension_wrapper';

此 SQL 必须用于从 0.0.00.1.0 的升级脚本中,以便将 hello_extension 函数指向新的共享对象。 pgx 不会 做任何魔法来确定函数是在哪个版本中引入或修改的,而只是将其放置在相应的版本化 so 文件中。由此扩展,您可以始终期望共享库将包含在扩展源代码中定义的所有函数。

此功能不是为了帮助数据类型的向后兼容而设计的。

@MODULE_PATHNAME@ 模板化

如果您已经为Rust函数提供了自定义SQL定义,您可以在自定义SQL中使用 @MODULE_PATHNAME@ 模板。此值将被替换为实际共享对象的路径。

以下示例说明了它是如何工作的

#[pg_extern(sql = r#"
    CREATE OR REPLACE FUNCTION tests."overridden_sql_with_fn_name"() RETURNS void
    STRICT
    LANGUAGE c /* Rust */
    AS '@MODULE_PATHNAME@', '@FUNCTION_NAME@';
"#)]
fn overridden_sql_with_fn_name() -> bool {
    true
}

注意事项

有些场景与该功能完全不兼容,因为它们依赖于Postgres的一些全局状态,因此加载两个版本的共享库将导致问题。

这些场景包括

  • 使用共享内存时
  • 使用查询计划钩子时

编译器版本依赖性

构建 cargo-pgx 所使用的Rust编译器和工具链的版本必须与构建您的扩展所使用的版本相同。

一些子命令(包括 cargo pgx schemacargo pgx testcargo pgx install 等)如果不匹配,将产生错误消息。

尽管将来可能会放宽这一点,但目前模式生成涉及 dlopen 扩展并调用 extern "Rust" 函数在 #[repr(Rust)] 类型上。通常,修复此问题的正确方法是重新安装 cargo-pgx,使用以下命令

$ cargo install --force --locked cargo-pgx

可能需要显式指定 --version

如果您确定在这种情况下没有问题,您可以在环境中设置 PGX_IGNORE_RUST_VERSIONS(除 "0" 之外的任何值),检查将被绕过。但是,请注意,尽管检查不是万无一失的,但它试图在允许的内容上保持相当宽松。

有关更多信息,请参阅 https://github.com/tcdi/pgx/issues/774https://github.com/tcdi/pgx/pull/873

依赖项

~21–33MB
~532K SLoC