Coder Social home page Coder Social logo

pgrx's Introduction

Logo

pgrx

Build Postgres Extensions with Rust!

GitHub Actions badge crates.io badge docs.rs badge Twitter Follow Discord Chat

pgrx is a framework for developing PostgreSQL extensions in Rust and strives to be as idiomatic and safe as possible.

pgrx supports Postgres 12 through Postgres 16.

Feel free to join our Discord Server.

Key Features

  • A fully managed development environment with cargo-pgrx
    • cargo pgrx new: Create new extensions quickly
    • cargo pgrx init: Install new (or register existing) PostgreSQL installs
    • cargo pgrx run: Run your extension and interactively test it in psql (or pgcli)
    • cargo pgrx test: Unit-test your extension across multiple PostgreSQL versions
    • cargo pgrx package: Create installation packages for your extension
    • More in the README.md!
  • Target Multiple Postgres Versions
    • Support from Postgres 12 to Postgres 16 from the same codebase
    • Use Rust feature gating to use version-specific APIs
    • Seamlessly test against all versions
  • Automatic Schema Generation
  • Safety First
    • Translates Rust panic!s into Postgres ERRORs that abort the transaction, not the process
    • Memory Management follows Rust's drop semantics, even in the face of panic! and elog(ERROR)
    • #[pg_guard] procedural macro to ensure the above
    • Postgres Datums are Option<T> where T: FromDatum
      • NULL Datums are safely represented as Option::<T>::None
  • First-class UDF support
    • Annotate functions with #[pg_extern] to expose them to Postgres
    • Return pgrx::iter::SetOfIterator<'a, T> for RETURNS SETOF
    • Return pgrx::iter::TableIterator<'a, T> for RETURNS TABLE (...)
    • Create trigger functions with #[pg_trigger]
  • Easy Custom Types
    • #[derive(PostgresType)] to use a Rust struct as a Postgres type
      • By default, represented as a CBOR-encoded object in-memory/on-disk, and JSON as human-readable
      • Provide custom in-memory/on-disk/human-readable representations
    • #[derive(PostgresEnum)] to use a Rust enum as a Postgres enum
    • Composite types supported with the pgrx::composite_type!("Sample") macro
  • Server Programming Interface (SPI)
    • Safe access into SPI
    • Transparently return owned Datums from an SPI context
  • Advanced Features
    • Safe access to Postgres' MemoryContext system via pgrx::PgMemoryContexts
    • Executor/planner/transaction/subtransaction hooks
    • Safely use Postgres-provided pointers with pgrx::PgBox<T> (akin to alloc::boxed::Box<T>)
    • #[pg_guard] proc-macro for guarding extern "C" Rust functions that need to be passed into Postgres
    • Access Postgres' logging system through eprintln!-like macros
    • Direct unsafe access to large parts of Postgres internals via the pgrx::pg_sys module
    • New features added regularly!

System Requirements

PGRX has been tested to work on x86_64⹋ and aarch64⹋ Linux and aarch64 macOS targets. It is currently expected to work on other "Unix" OS with possible small changes, but those remain untested. So far, some of PGRX's build tooling works on Windows, but not all.

  • A Rust toolchain: rustc, cargo, and rustfmt. The recommended way to get these is from https://rustup.rs
  • git
  • libclang 5.0 or greater (required by bindgen)
    • Ubuntu: apt install libclang-dev or apt install clang
    • RHEL: yum install clang
  • GCC 7 or newer
  • PostgreSQL's build dependencies
    • Debian-likes: sudo apt-get install build-essential libreadline-dev zlib1g-dev flex bison libxml2-dev libxslt-dev libssl-dev libxml2-utils xsltproc ccache pkg-config
    • RHEL-likes: sudo yum install -y bison-devel readline-devel zlib-devel openssl-devel wget ccache && sudo yum groupinstall -y 'Development Tools'

† PGRX has no MSRV policy, thus may require the latest stable version of Rust, available via Rustup

‡ A local PostgreSQL server installation is not required. cargo pgrx can download and compile PostgreSQL versions on its own.

⹋ PGRX has not been tested to work on 32-bit: the library assumes an 8-byte pg_sys::Datum which may result in unexpected behavior on 32-bit, like dropping 4 bytes of data from int8 and double. This may not be "unsound" in itself, as it is "merely" illogical, but it may undermine otherwise-reasonable safety assumptions of PGRX extensions. We do not plan to add support without considerable ongoing technical and financial contributions.

How to: GCC 7 on CentOS 7

It is not recommended to use CentOS 7 for PGRX development, even if it works.

Recommended Linux distributions include recent Debian, Fedora, and Ubuntu.

In order to use GCC 7, install scl and enter the GCC 7 development environment:

yum install centos-release-scl
yum install devtoolset-7
scl enable devtoolset-7 bash
How to: Homebrew on macOS

As macOS provides no package manager, it is recommended to use https://brew.sh for C dependencies.

In particular, you will probably need these if you don't have them already:

brew install git icu4c pkg-config

Getting Started

Before anything else, install the system dependencies.

Now install the cargo-pgrx sub-command.

cargo install --locked cargo-pgrx

Once cargo-pgrx is ready you can initialize the "PGRX Home" directory:

cargo pgrx init

The init command downloads all currently supported PostgreSQL versions, compiles them to ${PGRX_HOME}, and runs initdb.

It's also possible to use an existing (user-writable) PostgreSQL install, or install a subset of versions, see the README.md of cargo-pgrx for details.

Now you can begin work on a specific pgrx extension:

cargo pgrx new my_extension
cd my_extension

This will create a new directory for the extension crate.

$ tree 
.
├── Cargo.toml
├── my_extension.control
├── sql
└── src
    └── lib.rs

2 directories, 3 files

The new extension includes an example, so you can go ahead and run it right away.

cargo pgrx run

This compiles the extension to a shared library, copies it to the specified Postgres installation, starts that Postgres instance and connects you to a database named the same as the extension.

Once cargo-pgrx drops us into psql we can load the extension and do a SELECT on the example function.

my_extension=# CREATE EXTENSION my_extension;
CREATE EXTENSION

my_extension=# SELECT hello_my_extension();
 hello_my_extension
---------------------
 Hello, my_extension
(1 row)

For more details on how to manage pgrx extensions see Managing pgrx extensions.

Upgrading

As new Postgres versions are supported by pgrx, you can re-run the pgrx init process to download and compile them:

cargo pgrx init

Mapping of Postgres types to Rust

Postgres Type Rust Type (as Option<T>)
bytea Vec<u8> or &[u8] (zero-copy)
text String or &str (zero-copy)
varchar String or &str (zero-copy) or char
"char" i8
smallint i16
integer i32
bigint i64
oid u32
real f32
double precision f64
bool bool
json pgrx::Json(serde_json::Value)
jsonb pgrx::JsonB(serde_json::Value)
date pgrx::Date
time pgrx::Time
timestamp pgrx::Timestamp
time with time zone pgrx::TimeWithTimeZone
timestamp with time zone pgrx::TimestampWithTimeZone
anyarray pgrx::AnyArray
anyelement pgrx::AnyElement
box pgrx::pg_sys::BOX
point pgrx::pg_sys::Point
tid pgrx::pg_sys::ItemPointerData
cstring &core::ffi::CStr
inet pgrx::Inet(String) -- TODO: needs better support
numeric pgrx::Numeric<P, S> or pgrx::AnyNumeric
void ()
ARRAY[]::<type> Vec<Option<T>> or pgrx::Array<T> (zero-copy)
int4range pgrx::Range<i32>
int8range pgrx::Range<i64>
numrange pgrx::Range<Numeric<P, S>> or pgrx::Range<AnyRange>
daterange pgrx::Range<pgrx::Date>
tsrange pgrx::Range<pgrx::Timestamp>
tstzrange pgrx::Range<pgrx::TimestampWithTimeZone>
NULL Option::None
internal pgrx::PgBox<T> where T is any Rust/Postgres struct
uuid pgrx::Uuid([u8; 16])

There are also IntoDatum and FromDatum traits for implementing additional type conversions, along with #[derive(PostgresType)] and #[derive(PostgresEnum)] for automatic conversion of custom types.

Note that text and varchar are converted to &str or String, so PGRX assumes any Postgres database you use it with has UTF-8-compatible encoding. Currently, PGRX will panic if it detects this is incorrect, to inform you, the programmer, that you were wrong. However, it is best to not rely on this behavior, as UTF-8 validation can be a performance hazard. This problem was previously assumed to simply not happen, and PGRX may decide to change the details of how it does UTF-8 validation checks in the future in order to mitigate performance hazards.

The default Postgres server encoding is SQL_ASCII, and it guarantees neither ASCII nor UTF-8 (as Postgres will then accept but ignore non-ASCII bytes). For best results, always use PGRX with UTF-8, and set database encodings explicitly upon database creation.

Digging Deeper

Caveats & Known Issues

There's probably more than are listed here, but a primary things of note are:

  • Threading is not really supported. Postgres is strictly single-threaded. As such, if you do venture into using threads, those threads MUST NOT call any internal Postgres function, or otherwise use any Postgres-provided pointer. There's also a potential problem with Postgres' use of sigprocmask. This was being discussed on the -hackers list, even with a patch provided, but the conversation seems to have stalled (https://www.postgresql.org/message-id/flat/5EF20168.2040508%40anastigmatix.net#4533edb74194d30adfa04a6a2ce635ba).
  • How to correctly interact with Postgres in an async context remains unexplored.
  • pgrx wraps a lot of unsafe code, some of which has poorly-defined safety conditions. It may be easy to induce illogical and undesirable behaviors even from safe code with pgrx, and some of these wrappers may be fundamentally unsound. Please report any issues that may arise.
  • Not all of Postgres' internals are included or even wrapped. This isn't due to it not being possible, it's simply due to it being an incredibly large task. If you identify internal Postgres APIs you need, open an issue and we'll get them exposed, at least through the pgrx::pg_sys module.
  • Windows is not supported. It could be, but will require a bit of work with cargo-pgrx and figuring out how to compile pgrx's "cshim" static library.
  • Sessions started before ALTER EXTENSION my_extension UPDATE; will continue to see the old version of my_extension. New sessions will see the updated version of the extension.
  • pgrx is used by many "in production", but it is not "1.0.0" or above, despite that being recommended by SemVer for production-quality software. This is because there are many unresolved soundness and ergonomics questions that will likely require breaking changes to resolve, in some cases requiring cutting-edge Rust features to be able to expose sound interfaces. While a 1.0.0 release is intended at some point, it seems prudent to wait until it seems like a 2.0.0 release would not be needed the next week and the remaining questions can be deferred.

TODO

There's a few things on our immediate TODO list

  • Automatic extension schema upgrade scripts
  • Improved unit testing framework
  • Better/Safer API for Datum management
  • Improved generated bindings organization
  • Safely wrap more Postgres internal APIs
  • More examples -- especially around memory management and the various derive macros #[derive(PostgresType/Enum)]

Feature Flags

PGRX has optional feature flags for Rust code that do not involve configuring the version of Postgres used, but rather extend additional support for other kinds of Rust code. These are not included by default.

"unsafe-postgres": Allow compilation for Postgres forks that have a different ABI

As of Postgres 15, forks are allowed to specify they use a different ABI than canonical Postgres. Since pgrx makes countless assumptions about Postgres' internal ABI it is not possible for it to guarantee that a compiled pgrx extension will probably execute within such a Postgres fork. You, dear compiler runner, can make this guarantee for yourself by specifying the unsafe-postgres feature flag. Otherwise, a pgrx extension will fail to compile with an error similar to:

error[E0080]: evaluation of constant value failed
   --> pgrx/src/lib.rs:151:5
    |
151 | /     assert!(
152 | |         same_slice(pg_sys::FMGR_ABI_EXTRA, b"xPostgreSQL\0"),
153 | |         "Unsupported Postgres ABI. Perhaps you need `--features unsafe-postgres`?",
154 | |     );
    | |_____^ the evaluated program panicked at 'Unsupported Postgres ABI. Perhaps you need `--features unsafe-postgres`?', pgrx/src/lib.rs:151:5
    |

Contributing

We are most definitely open to contributions of any kind. Bug Reports, Feature Requests, Documentation, and even sponsorships.

If you'd like to contribute code via a Pull Request, please make it against our develop branch. The master branch is no longer used.

Providing wrappers for Postgres' internals is not a straightforward task, and completely wrapping it is going to take quite a bit of time. pgrx is generally ready for use now, and it will continue to be developed as time goes on. Your feedback about what you'd like to be able to do with pgrx is greatly appreciated.

Hacking

If you're hacking on pgrx and want to ensure your test will run correctly, you need to have the current implementation of cargo-pgrx (from the revision you're working on) in your PATH.

An easy way would be to install cargo-local-install:

cargo install cargo-local-install

and then run cargo local-install to install cargo-pgrx as specified in top-level's Cargo.toml.

Don't forget to prepend /path/to/pgrx/bin to your PATH!

This approach can also be used in extensions to ensure a matching version of cargo-pgrx is used.

License

Portions Copyright 2019-2021 ZomboDB, LLC.  
Portions Copyright 2021-2023 Technology Concepts & Design, Inc.
Portions Copyright 2023 PgCentral Foundation, Inc.

All rights reserved.
Use of this source code is governed by the MIT license that can be found in the LICENSE file.

pgrx's People

Contributors

bbigras avatar bradybonnette avatar daamien avatar edmcbane avatar eeeebbbbrrrr avatar einarmo avatar ethanpailes avatar ewencp avatar feikesteenbergen avatar hoverbear avatar jamesguthrie avatar jamessewell avatar jeltef avatar jlockerman avatar mhov avatar nikkhils avatar notgyro avatar nyurik avatar passcod avatar rebasedming avatar rustprooflabs avatar saltydavidselph avatar skyzh avatar syvb avatar thomcc avatar usamoi avatar willmurnane avatar workingjubilee avatar yrashk avatar zombodb avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pgrx's Issues

I am having trouble compiling the hello example

I am using 20.04 ubuntu with stock rustc. I have set my path for cargo and have pg_config in path.

[12.3] [stdout] make[4]: Leaving directory '/home/pbrumm/pg_bitquery/target/postgresql-12.3/src/common'
[12.3] [stdout] make[3]: Leaving directory '/home/pbrumm/pg_bitquery/target/postgresql-12.3/src/interfaces/libpq'
[12.3] [stdout] make[2]: Leaving directory '/home/pbrumm/pg_bitquery/target/postgresql-12.3/src/test/isolation'
[12.3] [stdout] make[1]: Leaving directory '/home/pbrumm/pg_bitquery/target/postgresql-12.3/src'
[12.3] [stderr] + cd /home/pbrumm/pg_bitquery/target/postgresql-12.3
[12.3] [stderr] + '[' '!' -f config.status ']'
[12.3] [stderr] + ./configure --prefix=/home/pbrumm/pg_bitquery/target/postgresql-12.3/pgx-install --without-readline --without-zlib -with-pgport=8812
[12.3] [stderr] + '[' '!' -f /home/pbrumm/pg_bitquery/target/postgresql-12.3/pgx-install/bin/postgres ']'
[12.3] [stderr] + make -j 5
[12.3] [stderr] gcc: fatal error: cannot read spec file ‘./specs’: Is a directory
[12.3] [stderr] compilation terminated.
[12.3] [stderr] make[2]: *** [<builtin>: specparse.o] Error 1
[12.3] [stderr] make[2]: *** Waiting for unfinished jobs....
[12.3] [stderr] gcc: fatal error: cannot read spec file ‘./specs’: Is a directory
[12.3] [stderr] compilation terminated.
[12.3] [stderr] make[2]: *** [<builtin>: isolationtester.o] Error 1
[12.3] [stderr] gcc: fatal error: cannot read spec file ‘./specs’: Is a directory
[12.3] [stderr] compilation terminated.
[12.3] [stderr] make[2]: *** [<builtin>: isolation_main.o] Error 1
[12.3] [stderr] make[1]: *** [Makefile:42: all-test/isolation-recurse] Error 2
[12.3] [stderr] make: *** [GNUmakefile:11: all-src-recurse] Error 2
[12.3] [stderr] + exit 1
[12.3] /----------------------------------------

thread '<unnamed>' panicked at 'failed to compile Postgres v12.3', /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.0.4/build.rs:287:14
stack backtrace:
   0:     0x55f78a846b73 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h4ef1f84901fa8edc
   1:     0x55f78a8640dd - core::fmt::write::h026b5c0fa015f11c
   2:     0x55f78a845cb5 - std::io::Write::write_fmt::hc77e135d55d2160d
   3:     0x55f78a849e1e - std::panicking::default_hook::{{closure}}::h7a1ebe73b27c35f6
   4:     0x55f78a849b30 - std::panicking::default_hook::hc9a55f38c57244a0
   5:     0x55f78a84a4fb - std::panicking::rust_panic_with_hook::hd3ad4a665e641fa7
   6:     0x55f78a84a0ae - rust_begin_unwind
   7:     0x55f78a849ff0 - std::panicking::begin_panic_fmt::h1e4a1c904d7eb2f7
   8:     0x55f78a017493 - build_script_build::compile_postgres::h1f97e74dfceb7e2e
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.0.4/build.rs:287
   9:     0x55f78a01490f - build_script_build::main::{{closure}}::he465a0cd0e1a51f9
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.0.4/build.rs:113
  10:     0x55f78a012313 - core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut::h26278ceea995277f
                               at /usr/src/rustc-1.41.0/src/libcore/ops/function.rs:252
  11:     0x55f78a02b8ed - core::iter::traits::iterator::Iterator::for_each::call::{{closure}}::h40e7d576a6bc1bf1
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:629
  12:     0x55f78a02add8 - core::iter::traits::iterator::Iterator::fold::ok::{{closure}}::h719d08f59d55fcf9
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:1829
  13:     0x55f78a00f107 - core::iter::traits::iterator::Iterator::try_fold::hc8816c4cac676472
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:1710
  14:     0x55f78a00b86e - core::iter::traits::iterator::Iterator::fold::h35c4f86164ba1d00
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:1832
  15:     0x55f78a00cc0c - core::iter::traits::iterator::Iterator::for_each::h8a8376ab0220bbea
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:632
  16:     0x55f789fee94e - <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter::hb6eebacc52f79cb4
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/for_each.rs:55
  17:     0x55f789ffe2be - rayon::iter::plumbing::Producer::fold_with::h81cbb8a60d7242c3
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/plumbing/mod.rs:110
  18:     0x55f78a02e02f - rayon::iter::plumbing::bridge_producer_consumer::helper::h75a6fdd60f34eccf
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/plumbing/mod.rs:438
  19:     0x55f78a02e2da - rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}::he6593c93a132dea9
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/plumbing/mod.rs:427
  20:     0x55f78a01a42f - rayon_core::join::join_context::call_b::{{closure}}::h6a55407af6384f2d
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/join/mod.rs:130
  21:     0x55f789fe2512 - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::call::{{closure}}::h0e2cf0656bfd05e7
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/job.rs:113
  22:     0x55f78a019670 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h808679ff31855677
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:318
  23:     0x55f78a01b02e - std::panicking::try::do_call::hc883de5c948bd719
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:292
  24:     0x55f78a84e48a - __rust_maybe_catch_panic
  25:     0x55f78a01ad2e - std::panicking::try::h650df14c946883d1
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:270
  26:     0x55f78a01a792 - std::panic::catch_unwind::h85d1a16d067113e1
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:394
  27:     0x55f789feea6f - rayon_core::unwind::halt_unwinding::h80be1878277c04e9
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/unwind.rs:17
  28:     0x55f789fe21ab - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::hce1d24a18d402950
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/job.rs:119
  29:     0x55f78a1d1f66 - rayon_core::job::JobRef::execute::h5ba2780576e5d2ec
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/job.rs:59
  30:     0x55f78a1cbb2d - rayon_core::registry::WorkerThread::execute::hd016764618062486
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:685
  31:     0x55f78a1cb836 - rayon_core::registry::WorkerThread::wait_until_cold::hd9e954d412c2fa04
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:669
  32:     0x55f78a1cb156 - rayon_core::registry::WorkerThread::wait_until::h440fd0891a627775
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:643
  33:     0x55f78a1cc366 - rayon_core::registry::main_loop::h69a5991763cd151a
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:763
  34:     0x55f78a1c9060 - rayon_core::registry::ThreadBuilder::run::hcae4539176983f8c
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:56
  35:     0x55f78a1c96a1 - <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}::h609d2e53f7cf2984
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:101
  36:     0x55f78a1df060 - std::sys_common::backtrace::__rust_begin_short_backtrace::h702555aa88d17f61
                               at /usr/src/rustc-1.41.0/src/libstd/sys_common/backtrace.rs:136
  37:     0x55f78a1e6111 - std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}}::h57f8e203e05eec92
                               at /usr/src/rustc-1.41.0/src/libstd/thread/mod.rs:469
  38:     0x55f78a1e4c23 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h49e6b785dc47c84f
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:318
  39:     0x55f78a1ef653 - std::panicking::try::do_call::h13479e341e364396
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:292
  40:     0x55f78a84e48a - __rust_maybe_catch_panic
  41:     0x55f78a1ef548 - std::panicking::try::hec248c78942e54c1
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:270
  42:     0x55f78a1e5323 - std::panic::catch_unwind::he93cda27e90d61c4
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:394
  43:     0x55f78a1e5ef6 - std::thread::Builder::spawn_unchecked::{{closure}}::haea9673371700eec
                               at /usr/src/rustc-1.41.0/src/libstd/thread/mod.rs:468
  44:     0x55f78a1d8934 - core::ops::function::FnOnce::call_once{{vtable.shim}}::hc7dd0c4f9b1ef688
                               at /usr/src/rustc-1.41.0/src/libcore/ops/function.rs:232
  45:     0x55f78a83ebcf - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h2f9577dd894cb305
  46:     0x55f78a845e10 - std::sys_common::thread::start_thread::h05cb3555d2d68d0a
  47:     0x55f78a83cae6 - std::sys::unix::thread::Thread::new::thread_start::ha2762cba1ba415cc
  48:     0x7efe0d1c9609 - start_thread
  49:     0x7efe0d0d5103 - __clone
  50:                0x0 - <unknown>

Error: Os { code: 101, kind: Other, message: "Network is unreachable" }

the same thing happens for 10 and 11

[10.13] [stderr] + cd /home/pbrumm/pg_bitquery/target/postgresql-10.13
[10.13] [stderr] + '[' '!' -f config.status ']'
[10.13] [stderr] + ./configure --prefix=/home/pbrumm/pg_bitquery/target/postgresql-10.13/pgx-install --without-readline --without-zlib -with-pgport=8810
[10.13] [stderr] + '[' '!' -f /home/pbrumm/pg_bitquery/target/postgresql-10.13/pgx-install/bin/postgres ']'
[10.13] [stderr] + make -j 5
[10.13] [stderr] gcc: fatal error: cannot read spec file ‘./specs’: Is a directory
[10.13] [stderr] compilation terminated.
[10.13] [stderr] make[2]: *** [<builtin>: specparse.o] Error 1
[10.13] [stderr] make[2]: *** Waiting for unfinished jobs....
[10.13] [stderr] gcc: fatal error: cannot read spec file ‘./specs’: Is a directory
[10.13] [stderr] compilation terminated.
[10.13] [stderr] make[2]: *** [<builtin>: isolationtester.o] Error 1
[10.13] [stderr] gcc: fatal error: cannot read spec file ‘./specs’: Is a directory
[10.13] [stderr] compilation terminated.
[10.13] [stderr] make[2]: *** [<builtin>: isolation_main.o] Error 1
[10.13] [stderr] make[1]: *** [Makefile:38: all-test/isolation-recurse] Error 2
[10.13] [stderr] make: *** [GNUmakefile:11: all-src-recurse] Error 2
[10.13] [stderr] + exit 1
[10.13] /----------------------------------------

thread '<unnamed>' panicked at 'failed to compile Postgres v10.13', /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.0.4/build.rs:287:14
stack backtrace:
   0:     0x55f78a846b73 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::h4ef1f84901fa8edc
   1:     0x55f78a8640dd - core::fmt::write::h026b5c0fa015f11c
   2:     0x55f78a845cb5 - std::io::Write::write_fmt::hc77e135d55d2160d
   3:     0x55f78a849e1e - std::panicking::default_hook::{{closure}}::h7a1ebe73b27c35f6
   4:     0x55f78a849b30 - std::panicking::default_hook::hc9a55f38c57244a0
   5:     0x55f78a84a4fb - std::panicking::rust_panic_with_hook::hd3ad4a665e641fa7
   6:     0x55f78a84a0ae - rust_begin_unwind
   7:     0x55f78a849ff0 - std::panicking::begin_panic_fmt::h1e4a1c904d7eb2f7
   8:     0x55f78a017493 - build_script_build::compile_postgres::h1f97e74dfceb7e2e
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.0.4/build.rs:287
   9:     0x55f78a01490f - build_script_build::main::{{closure}}::he465a0cd0e1a51f9
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.0.4/build.rs:113
  10:     0x55f78a012313 - core::ops::function::impls::<impl core::ops::function::FnMut<A> for &F>::call_mut::h26278ceea995277f
                               at /usr/src/rustc-1.41.0/src/libcore/ops/function.rs:252
  11:     0x55f78a02b8ed - core::iter::traits::iterator::Iterator::for_each::call::{{closure}}::h40e7d576a6bc1bf1
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:629
  12:     0x55f78a02add8 - core::iter::traits::iterator::Iterator::fold::ok::{{closure}}::h719d08f59d55fcf9
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:1829
  13:     0x55f78a00f107 - core::iter::traits::iterator::Iterator::try_fold::hc8816c4cac676472
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:1710
  14:     0x55f78a00b86e - core::iter::traits::iterator::Iterator::fold::h35c4f86164ba1d00
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:1832
  15:     0x55f78a00cc0c - core::iter::traits::iterator::Iterator::for_each::h8a8376ab0220bbea
                               at /usr/src/rustc-1.41.0/src/libcore/iter/traits/iterator.rs:632
  16:     0x55f789fee94e - <rayon::iter::for_each::ForEachConsumer<F> as rayon::iter::plumbing::Folder<T>>::consume_iter::hb6eebacc52f79cb4
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/for_each.rs:55
  17:     0x55f789ffe2be - rayon::iter::plumbing::Producer::fold_with::h81cbb8a60d7242c3
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/plumbing/mod.rs:110
  18:     0x55f78a02e02f - rayon::iter::plumbing::bridge_producer_consumer::helper::h75a6fdd60f34eccf
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/plumbing/mod.rs:438
  19:     0x55f78a02e1fa - rayon::iter::plumbing::bridge_producer_consumer::helper::{{closure}}::h3ce23f8d37b0e4a5
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-1.3.1/src/iter/plumbing/mod.rs:418
  20:     0x55f78a01a375 - rayon_core::join::join_context::call_a::{{closure}}::hb91a4ef0b0f9bf9d
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/join/mod.rs:125
  21:     0x55f78a0196b0 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::hd1a1d085437d6e4f
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:318
  22:     0x55f78a01afbe - std::panicking::try::do_call::h77f9652e57fc9b39
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:292
  23:     0x55f78a84e48a - __rust_maybe_catch_panic
  24:     0x55f78a01abae - std::panicking::try::h3898e88ac07e3391
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:270
  25:     0x55f78a01a7e2 - std::panic::catch_unwind::h8882b725d6414bec
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:394
  26:     0x55f789feeaef - rayon_core::unwind::halt_unwinding::h8b3384713762fba9
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/unwind.rs:17
  27:     0x55f78a019ad3 - rayon_core::join::join_context::{{closure}}::h165048404ccfcd5f
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/join/mod.rs:146
  28:     0x55f789fdd986 - rayon_core::registry::Registry::in_worker_cold::{{closure}}::{{closure}}::hfccec1de986c74d6
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:447
  29:     0x55f789fe2564 - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::call::{{closure}}::h42b2840058076055
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/job.rs:113
  30:     0x55f78a0196f2 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::heb7c37d19b9d872e
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:318
  31:     0x55f78a01b0a1 - std::panicking::try::do_call::he11e4e307c5567e8
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:292
  32:     0x55f78a84e48a - __rust_maybe_catch_panic
  33:     0x55f78a01aeae - std::panicking::try::hfd371ad52def9ad1
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:270
  34:     0x55f78a01a742 - std::panic::catch_unwind::h70f35ea9fbf395fd
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:394
  35:     0x55f789feeb72 - rayon_core::unwind::halt_unwinding::hf49ebaba9a21e4f7
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/unwind.rs:17
  36:     0x55f789fe1e05 - <rayon_core::job::StackJob<L,F,R> as rayon_core::job::Job>::execute::ha2bfc31e6e3e9730
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/job.rs:119
  37:     0x55f78a1d1f66 - rayon_core::job::JobRef::execute::h5ba2780576e5d2ec
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/job.rs:59
  38:     0x55f78a1cbb2d - rayon_core::registry::WorkerThread::execute::hd016764618062486
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:685
  39:     0x55f78a1cb836 - rayon_core::registry::WorkerThread::wait_until_cold::hd9e954d412c2fa04
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:669
  40:     0x55f78a1cb156 - rayon_core::registry::WorkerThread::wait_until::h440fd0891a627775
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:643
  41:     0x55f78a1cc366 - rayon_core::registry::main_loop::h69a5991763cd151a
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:763
  42:     0x55f78a1c9060 - rayon_core::registry::ThreadBuilder::run::hcae4539176983f8c
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:56
  43:     0x55f78a1c96a1 - <rayon_core::registry::DefaultSpawn as rayon_core::registry::ThreadSpawn>::spawn::{{closure}}::h609d2e53f7cf2984
                               at /home/pbrumm/.cargo/registry/src/github.com-1ecc6299db9ec823/rayon-core-1.7.1/src/registry.rs:101
  44:     0x55f78a1df060 - std::sys_common::backtrace::__rust_begin_short_backtrace::h702555aa88d17f61
                               at /usr/src/rustc-1.41.0/src/libstd/sys_common/backtrace.rs:136
  45:     0x55f78a1e6111 - std::thread::Builder::spawn_unchecked::{{closure}}::{{closure}}::h57f8e203e05eec92
                               at /usr/src/rustc-1.41.0/src/libstd/thread/mod.rs:469
  46:     0x55f78a1e4c23 - <std::panic::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once::h49e6b785dc47c84f
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:318
  47:     0x55f78a1ef653 - std::panicking::try::do_call::h13479e341e364396
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:292
  48:     0x55f78a84e48a - __rust_maybe_catch_panic
  49:     0x55f78a1ef548 - std::panicking::try::hec248c78942e54c1
                               at /usr/src/rustc-1.41.0/src/libstd/panicking.rs:270
  50:     0x55f78a1e5323 - std::panic::catch_unwind::he93cda27e90d61c4
                               at /usr/src/rustc-1.41.0/src/libstd/panic.rs:394
  51:     0x55f78a1e5ef6 - std::thread::Builder::spawn_unchecked::{{closure}}::haea9673371700eec
                               at /usr/src/rustc-1.41.0/src/libstd/thread/mod.rs:468
  52:     0x55f78a1d8934 - core::ops::function::FnOnce::call_once{{vtable.shim}}::hc7dd0c4f9b1ef688
                               at /usr/src/rustc-1.41.0/src/libcore/ops/function.rs:232
  53:     0x55f78a83ebcf - <alloc::boxed::Box<F> as core::ops::function::FnOnce<A>>::call_once::h2f9577dd894cb305
  54:     0x55f78a845e10 - std::sys_common::thread::start_thread::h05cb3555d2d68d0a
  55:     0x55f78a83cae6 - std::sys::unix::thread::Thread::new::thread_start::ha2762cba1ba415cc
  56:     0x7efe0d1c9609 - start_thread
  57:     0x7efe0d0d5103 - __clone
  58:                0x0 - <unknown>

Should I be looking for missing dependencies in the postgres compile phase, or is this something in pbx?
I did see a warning around Flex so I installed that.

Incorrect output type definition for psgree

code:

mod test_schema2 {
	use pgx::*;
	
	type OutTest1 = &'static str;  // <<<<<<<<<<<<
	#[pg_extern]
	fn test1() -> OutTest1 { // <<<<<<<<<<<<
	    "Hello from some_schema"
	}
	
	#[pg_extern]
	fn test2() -> &'static str {
	    "Hello from some_schema"
	}
}

--.sql:

CREATE OR REPLACE FUNCTION test_schema2."test1"() RETURNS OutTest1 
STRICT SET search_path TO test_schema2,@extschema@ LANGUAGE c AS 'MODULE_PATHNAME', 'test1_wrapper';
**<<<<<<<<<<< RETURNS OutTest1**


-- ./src/lib.rs:54:1
CREATE OR REPLACE FUNCTION test_schema2."test2"() RETURNS text 
STRICT SET search_path TO test_schema2,@extschema@ LANGUAGE c AS 'MODULE_PATHNAME', 'test2_wrapper';
**<<<<<<<<<<< RETURNS text (Normal)**

out:

psql:test/init.sql:3: ERROR:  type outtest1 is only a shell

Compilation failure

cargo --version
cargo 1.49.0 (d00d64df9 2020-12-05)
cargo pgx --version
cargo-pgx 0.1.13
cargo pgx status
Postgres v10 is running
Postgres v11 is running
Postgres v12 is running
Postgres v13 is running
building extension with features `pg13`
"cargo" "build" "--features" "pg13" "--no-default-features"
   Compiling pgx v0.1.13 (/home/XXX/src/pgx/pgx)
error[E0603]: module `export` is private
   --> /home/XXX/src/pgx/pgx/src/list.rs:10:12
    |
10  | use serde::export::PhantomData;
    |            ^^^^^^ private module
    |
note: the module `export` is defined here
   --> /home/XXX/.cargo/registry/src/github.com-1ecc6299db9ec823/serde-1.0.119/src/lib.rs:275:5
    |
275 | use self::__private as export;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0392]: parameter `T` is never used
   --> /home/XXX/src/pgx/pgx/src/list.rs:216:30
    |
216 | struct PgListIteratorPtr<'a, T> {
    |                              ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

error[E0392]: parameter `T` is never used
   --> /home/XXX/src/pgx/pgx/src/list.rs:221:30
    |
221 | struct PgListIteratorOid<'a, T> {
    |                              ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

error[E0392]: parameter `T` is never used
   --> /home/XXX/src/pgx/pgx/src/list.rs:226:30
    |
226 | struct PgListIteratorInt<'a, T> {
    |                              ^ unused parameter
    |
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`

error: aborting due to 4 previous errors

Some errors have detailed explanations: E0392, E0603.
For more information about an error, try `rustc --explain E0392`.
error: could not compile `pgx`

To learn more, run the command again with --verbose.
     [error] failed to build extension

Feature request: cargo pgx init --pg12=https://ftp.postgresql.org/pub/source/v12.6/postgresql-12.6.tar.bz2

It would be very helpful for Nix-based environments (or for reproducible builds in general) to specify an exact version of postgres to use during the cargo pgx init phase.

I have tried using a nix-shell with cargo pgx init --pg12=${postgresql_12}/bin/pg_config, however, since the nix store paths are not writable, this doesn't help much (e.g. pgx run, pgx install and pgx package will not work). I have also tried copying the nix postgresql_12 to a local writable directory, then using that directory during pgx init, however, the pg_config of that writable copy will still produce absolute nix store path outputs (nix has a very opinionated method to guarantee reproducible builds). Using pgx init --pg12=download will not produce reproducible builds in a clean CI environment.

Also see comment #105 (comment) by @Hoverbear.

Please consider allowing init to accept a specific download url (or a part of the url), or alternatively, to accept a full version number.

Examples:

cargo pgx init --pg12=https://ftp.postgresql.org/pub/source/v12.6/postgresql-12.6.tar.bz2
cargo pgx init --pg12=12.6

bgworker process not starting in example

Hi!

I've been trying to get the bgworker example working but I don't see the expected log output when I run the example. Other examples like arrays work fine, so I believe I have pgx set up correctly.

Steps to reproduce:

  1. Install cargo-pgx
  2. Clone https://github.com/zombodb/pgx
  3. Run cargo pgx init
  4. From pgx-examples/bgworker run cargo pgx run pg11 (to create the data-11 folder)
  5. Run cargo pgx stop pg11
  6. Add session_preload_libraries = 'bgworker.so' to the last line of ~/.pgx/data-11/postgresql.conf
  7. Re-run cargo pgx run pg11
  8. Observe the log output in ~/.pgx/11.log (I've been using tail -f)
  9. Should observe some output from example, e.g. "Hello from inside the worker", but this never shows up.

I've put a log! call in _PG_init and that shows up, so the extension is getting built and included ok. I've also tried CREATE EXTENSION bgworker; inside the psql prompt that cargo pgx run drops you into, to no avail. (The log! calls in _PG_init actually happen twice, but I'm not sure why)

I've also tried with the latest stable rust (v1.46.0) and 1.47.0-nightly; both build, but I'm not seeing the output I'd expect.

I think it's most likely I'm missing some obvious configuration or trigger somewhere, but I'm not quite sure where to look next. Let me know if there's any other

Fixed-size types without length prefix?

Hi, pgx looks cool!

I was just wondering about the ability to create new fixed-size datatypes that don't have a length prefix, i.e. that aren't just wrapping a variable length binary. basically just large integers. Is that something that's doable or that you've considered?

Fix a few Postgres<-->Rust type conversions

  • Rust's () (unit) type should convert to Postgres' void type. Right now, this converts to Postgres' bool type, and that's just plain wrong!
  • Postgres' "char" type (note the quotes! -- this is different from character(N)/char(N)) should convert to Rust's i8
  • Rust's char type should convert to Postgres' varchar

syn 1.0.58 breaks build due to private api usage

1.0.58 includes this commit dtolnay/syn@957840e that breaks builds with the following error:

error[E0432]: unresolved import `syn::export`
  --> <user>/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-utils-0.1.11/src/lib.rs:12:10
   |
12 | use syn::export::TokenStream2;
   |          ^^^^^^ could not find `export` in `syn`

error[E0432]: unresolved import `syn::export`
   --> <user>/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-utils-0.1.11/src/pg_config.rs:250:10
    |
250 | use syn::export::Formatter;
    |          ^^^^^^ could not find `export` in `syn`

Feature request: TimestampWithTimeZone conversion to std::time::SystemTime

According to https://github.com/zombodb/pgx/blob/e12d8e883dc9e882214db0e1393a1e0b9c43d2db/pgx/src/datum/time_stamp_with_timezone.rs#L10

pgx::TimestampWithTimeZone is related to time::OffsetDateTime of the crates.io time package. I am looking for a way to convert pgx::TimestampWithTimeZone to std::time::SystemTime, and could achieve it as follows:

#[pg_extern]
fn my_func(my_time: TimestampWithTimeZone) {
    let my_time_base: time::OffsetDateTime = *my_time;
    let my_time_sys = SystemTime::from(my_time_base); // SystemTime::from is implemented for time::OffsetDateTime
    ...
}

I also needed to add time = "0.2.26" to my Cargo.toml file.

Although my current solution seems to work (I am still going to test it), it would be better if I could decouple my solution from pgx implementation details (e.g. TimestampWithTimeZone may choose to use a different time library in the future, perhaps chrono, etc.). I also don't really want to have to synchronize my Cargo.toml file's time package with the one used by pgx.

I get the following error if I do SystemTime::from(my_time) instead:

 ^^^^^^^^^^^^^^^^ the trait `std::convert::From<pgx::TimestampWithTimeZone>` is not implemented for `SystemTime`

Please consider providing an implementation for the trait.

Apologies for not providing a better description, my understanding of Rust is still very basic.

Some references:

  1. https://github.com/time-rs/time/blob/b6c5128bff6fbf25a249eb09edf6d7521bdc6029/src/offset_date_time.rs#L1029
  2. https://github.com/time-rs/time/blob/b6c5128bff6fbf25a249eb09edf6d7521bdc6029/src/offset_date_time.rs#L1040
  3. time-rs/time@a51e23b

default search_path='public' causes performance degradation for some functions

After doing some profiling of a tuned pgx function running in a large table scan, I noticed a lot of overhead introduced by the postgres function AtEOXact_GUC.

Looking at the function comments for AtEOXact_GUC, it is called when a function sets a GUC parameter via proconfig in pg_proc. Setting proconfig to null in pg_proc for this function resulting in an 3x performance improvement in the full query.

This is really a postgres issue, but I think it would help to have a null proconfig where possible for pgx functions.

Requiring an extra argument when using a function with one pg_sys :: FunctionCallData

I don't understand why I am struggling with pgx?

I am writing a trigger using only pg_sys::FunctionCallData like

#[pg_guard]
#[pg_extern]
pub fn ext4test (fcinfo: pg_sys::FunctionCallInfo) -> Trigger<'static>

All is well, the function is being assembled.
During installation error:

./src/pg_mod.rs:71 0: Could not generate function for "ext4test" at - it contains only pg_sys :: FunctionCallData as its only argument

-- 1.1.sql is NULL.

However, if you do

echo "CREATE OR REPLACE FUNCTION" ext4test "() RETURNS Trigger STRICT SET search_path TO @ extschema @ LANGUAGE c AS 'MODULE_PATHNAME', 'ext4test_wrapper';" >> ./target/debug/---pg12/usr/share/postgresql/extension/-- 1.1.sql

Then everything works !!! What is it?

pgx init downloads pg versions it already has

If you run pgx init for a second time, pgx will download Postgres versions that you already have.

$ cargo pgx --version
cargo-pgx 0.1.21

$ cargo pgx init
  Discovered Postgres v13.3, v12.7, v11.12, v10.17
  Downloading Postgres v10.17 from https://ftp.postgresql.org/pub/source/v10.17/postgresql-10.17.tar.bz2
  Downloading Postgres v12.7 from https://ftp.postgresql.org/pub/source/v12.7/postgresql-12.7.tar.bz2
  Downloading Postgres v13.3 from https://ftp.postgresql.org/pub/source/v13.3/postgresql-13.3.tar.bz2
  Downloading Postgres v11.12 from https://ftp.postgresql.org/pub/source/v11.12/postgresql-11.12.tar.bz2
     Removing /home/tim/.pgx/10.17
    Untarring Postgres v10.17 to /home/tim/.pgx/10.17
  Configuring Postgres v10.17
    Compiling Postgres v10.17
...

Incorrect decoding of fcinfo type in function arguments

It seems to be the same code, but the behavior is different.

This made me suffer for a very long time.

#[pg_extern]
fn test(fcinfo: pg_sys::FunctionCallInfo) {

}

Output:

Valid.

And

use pg_sys::FunctionCallInfo;

#[pg_extern]
fn test(fcinfo: FunctionCallInfo) {

}

Output:

the trait bound `*mut FunctionCallInfoBaseData: PostgresType` is not satisfied
required because of the requirements on the impl of `FromDatum` for `*mut FunctionCallInfoBaseData`

Expanded Shared Memory Management

Looking at the Examples, i can see the usage of Postgres Shared Memory, where the Data-Structures are defined in size at compile time. A very useful addition to the pgx Project, would be a shared memory management if possible.

Say, i want to create an in memory key-value store in Postgres Memory, which you can access via functions. The easiest implementation, would be, to have a HashMap Datatype. This is possible right now, but one has to predefine how many elements the hashmap can store at maximum. Of course this can lead to various problems, either overflow of memory, if too less elements were chosen, or waste of memory, if too many are chosen (as HashMap element count has to be in Power of 2).

One Solution, circumventing that (and which is possible in C at least (have already implemented something like this)) is creating a memory pool. During Initialization the Extension Claims a Chunk of x MB (up to GB) Shared Memory and can allocate/deallocate all kinds of things in it, for example a dynamically allocated HashMap (and its element)

This Extension uses a similar approach, though in a less dynamic fashion: https://github.com/knizhnik/imcs

Unfortunately i am not an Expert in Rust (more of a C/C++ Guy), and i don't now if
a) it is possible to implement such a memory pool manager
and more importantly
b) it is possible to create objects like a HashMap or other container objects with a custom allocator / deallocator in Rust at runtime

If it is possible i would like to support with the implementation of such feature, as this takes down a big "infrastructural" problem in getting started with Postgres Extensions

Compile errors on all platforms

I'm a big fan, and been waiting for this project eagerly.
While giving it a spin I faced following issues.

Windows 10 Enterprise
cargo 1.43.0-nightly (bda50510d 2020-03-02)
rustc 1.43.0-nightly (c20d7eecb 2020-03-11)

cargo pgx new my_extension thread 'main' panicked at 'failed to open ./sql/._src\lib.generated.sql: Os { code: 3, kind: NotFound, message: "The system cannot find the path specified." }', C:\Users\name\.cargo\registry\src\github.com-1ecc6299db9ec823\cargo-pgx-0.0.5\src\schema_generator.rs:115:33 note: run with RUST_BACKTRACE=1environment variable to display a backtrace

Could you please have a look.

Thanks again

Cursor style functionality

Heya, i've been playing with the library for a few weeks now and it has been spot on in every way possible. The only thing i've been wondering about it either the limiting of rows returned in SRFs, or the ability to add in a cursor-like function/ality.

For example:

`
  #[pg_extern]
  fn jontest() -> impl std::iter::Iterator<Item = i32>
  {
	  pgx::log::elog(INFO, "called jontest initial");

	  return jontest { curval: 1 };
  }

	impl Iterator for jontest
  {
	type Item = i32;

	fn next(&mut self) -> Option<Self::Item>
	{
		pgx::log::elog(INFO, format!("next called cur is {}", self.curval).as_str());

		self.curval += 1;

		if self.curval < 200
		{
			return Some(self.curval);
		}

		return None;
	}
  }
`

currently this will hit the iterator 200 times (ie, you'd see 200 log messages) even if you do something like:

select * from jontest() limit 10

The situation I have is that i'd have an external service which would be accessed by http in batches each time the iterator is called (ie. in the above, curval % 10 == 0 ? get another batch of 10 things) which is costly. I'm not a postgres noob, but definitely not an expert, but the only thing i've heard of which can mimic this functionality is a cursor type. So i guess there are three questions:

  • firstly, am i doing something wrong with this?
  • is there any way to achieve this functionality without a cursor type (i appreciate this isn't stackoverflow and i'm sorry to ask but it hopefully will help someone else in the future if anyone knows)
  • lastly, do you think at some point a cursor style interface would be possible?

Thanks once again for the great lib

Failed to build: No such file or directory

I am trying to create a custom docker image. However, I could not manage to install zombodb. The error is as follows:

  ... rest of compilation
  Compiling zombodb v3000.0.0-beta1 (/zombodb)
error: failed to run custom build command for `pgx-pg-sys v0.1.19`

Caused by:
  process didn't exit successfully: `/zombodb/target/debug/build/pgx-pg-sys-73aba577412b0297/build-script-build` (exit code: 1)
  --- stdout
  cargo:rerun-if-changed=/root/.pgx/config.toml
  cargo:rerun-if-changed=include/pg10.h
  cargo:rerun-if-changed=include/pg11.h
  cargo:rerun-if-changed=include/pg12.h
  cargo:rerun-if-changed=include/pg13.h
  cargo:rerun-if-changed=cshim/pgx-cshim.c
  cargo:rerun-if-changed=cshim/Makefile

  --- stderr
  manifest_dir=/root/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.19
  shim_dir=/root/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.19/cshim
  Generating bindings for pg13
  /usr/local/include/postgresql/server/port.h:176:70: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/port.h:178:55: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/port.h:180:58: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/port.h:182:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:157:40: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:158:49: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:161:30: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:161:56: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:163:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:164:52: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:166:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:170:31: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:170:57: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:173:30: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:173:56: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:175:41: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:189:48: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:221:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/elog.h:437:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/palloc.h:133:44: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/utils/palloc.h:134:80: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/lib/stringinfo.h:96:67: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  /usr/local/include/postgresql/server/lib/stringinfo.h:107:78: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
  [[bindings_diff]] "rustfmt" "/root/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.19/src/pg13.rs"
       [error] Unable to write bindings file for pg13 to `/root/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.19/src/pg13.rs`: No such file or directory (os error 2)
     [error] failed to build extension

I'm trying to build with wsl2.

I can successfully install cargo-pgx with cargo install cargo-pgx
init also works: cargo pgx init --pg${1%.*}=which pg_config``
this line however does not work: cargo pgx install --release and produces the output above

It is related to zombodb but I felt that it is proper ask here.

Installing globally as a system-level package

I'm interested in packaging this for Arch Linux, but I'm having issues getting this to play nicely.

$  cargo install --no-track --locked --root "$pkgdir/usr/" --path .
[snip output]
   Compiling pgx-utils v0.1.21 (/build/cargo-pgx/src/pgx-0.1.21/pgx-utils)
   Compiling pgx-pg-sys v0.1.21 (/build/cargo-pgx/src/pgx-0.1.21/pgx-pg-sys)
   Compiling pgx-macros v0.1.21 (/build/cargo-pgx/src/pgx-0.1.21/pgx-macros)
error: failed to compile `pgx-parent v0.1.21 (/build/cargo-pgx/src/pgx-0.1.21)`, intermediate artifacts can be found at `/build/cargo-pgx/src/pgx-0.1.21/target`

Caused by:
  failed to run custom build command for `pgx-pg-sys v0.1.21 (/build/cargo-pgx/src/pgx-0.1.21/pgx-pg-sys)`

Caused by:
  process didn't exit successfully: `/build/cargo-pgx/src/pgx-0.1.21/target/release/build/pgx-pg-sys-509d9b225c37e71c/build-script-build` (exit status: 1)
  --- stderr
  manifest_dir=/build/cargo-pgx/src/pgx-0.1.21/pgx-pg-sys
  shim_dir=/build/cargo-pgx/src/pgx-0.1.21/pgx-pg-sys/cshim
  Error: Custom { kind: NotFound, error: "/build/.pgx/config.toml not found.  Have you run `cargo pgx init` yet?" }

Seems to be a bit of a chicken & egg situation. How is one meant to run the package before it is installed?

Need upgrade path for functions defined in rust

Related to #120 from Discord conversation.

Functions defined in Rust have no clean upgrade path between extension versions. A quick test seems to confirm that if I add a column to the function's return in a new version, an ALTER EXTENSION <extname> UPDATE; does not see the new column while a clean install does. (I did disconnect/reconnect to make sure that wasn't the issue!)

According to @zombodb:

The fix for this is that pgx needs to become a rust-to-sql compiler
And that ain’t easy
)but it’s doable(

Error message when installing without a ./sql folder

thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 2, kind: NotFound, message: "No such file or directory" }', /home/user/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-pgx-0.1.6/src/commands/schema.rs:217:14
note: run with RUST_BACKTRACE=1 environment variable to display a backtrace

Solved by:
mkdir ./sql && cargo pgx schema

Missing API for parsing qualified name string

I've tried to build a custom extension with a function that could take a name of an index or column as a parameter and do some work on it. After some time I realized, that I need to somehow obtain an oid for that object in order to make further work.

Using C API this looks more or less like this:

#include "postgres.h"
#include "utils/repgroc.h"
#include "catalog/namespace.h"

static Oid GetOid() {
    text* name = PG__GETARG_TEXT_P(0);
    char* relname = t2c(name);
    List* relname_list = stringToQualifiedNameList(relname, "");
    RangeVar* relvar = makeRangeVarFromNameList(relname_list);
    Oid relOid = RangeVarGetRelid(relvar, AccessExclusiveLock, false);
    return relOid;
}

static char* t2c(text* in) {
    char* out = palloc(VARSIZE(in));
    memcpy(out, VARDATA(in), VARSIZE(in)-VARHDRSZ);
    out[VARSIZE(in) - VARHDRSZ] = '\0';
    return out;
}

The thing is that utils/regproc.h file is not referenced by pgx, and therefore not all of the necessary functions - like stringToQualifiedNameList - are exposed.

#[derive(PostgresType)] for structs with lifetimes doesn't work

currently we support this:

#[derive(PostgresType, Serialize, Deserialize)]
pub struct Bar {
    name: String
}

we also need to support this:

#[derive(PostgresType, Serialize, Deserialize, Debug)]
pub struct Foo<'a> {
    name: &'a str
}

An implementation note is is that the owned struct ("Bar" in this case) is transparently encoded as CBOR by pgx for in-memory and on-disk representation.

A PostgresType that wants to use borrowed values ("Foo" in this case) needs to be encoded as something else from which we can borrow memory. We have chosen JSON.

Invent a #[pg_operator] macro to easily create OPERATOR functions

#[pg_operator] will work just like #[pg_extern] in that it's denoting a function to be exported to Postgres, but it'll also automatically generate the required CREATE OPERATOR ... DDL (https://www.postgresql.org/docs/12/sql-createoperator.html).

There'll be a number of corresponding proc macros for setting the various properties of CREATE OPERATOR:

  • #[opname( <opname> )]: ie: #[opname(==)]
  • #[commutator( <commutator opname> )]
  • #[negator( <negator opname> )]
  • #[restrict( <restrict fnname> )]
  • #[join( <join fnname> )]
  • #[hashes]
  • #[merges]

All of the above are optional except for #[opname(...)].

Need FromDatum/IntoDatum support for Postgres bytea type

pgx needs FromDatum and IntoDatum support for Postgres' bytea type.

I think FromDatum should be able to convert into a Vec<u8> and a &[u8]. For the &[u8] version, we should be able to do that as a "zero copy" thing, once detoasting the input Datum.

Same for IntoDatum, but in either the Vec<u8> or &[u8] versions, they'll still need to copy into a Postgres' palloc'd memory address.

At the end of the day, this won't be a much different implementation than the support we have for text/varchar into/from String and &str. With some refactoring we can probably share a lot of that code. Internally, Postgres' byteas are represented as a struct varlena * anyways.

cargo pgx test fails for want of a test schema

It seems that cargo pgx test fails to run normally. It looks like there is some wrapper SQL that is not getting generated properly.

Here is some info about my system:

$ uname -a
Linux closet 4.19.0-9-amd64 #1 SMP Debian 4.19.118-2+deb10u1 (2020-06-07) x86_64 GNU/Linux
$ rustc --version
rustc 1.45.2 (d3fb005a3 2020-07-31)

Here is the full output of cargo pgx test. This is running against the default template created by cargo pgx new:

$ cargo pgx test
    Finished test [unoptimized + debuginfo] target(s) in 0.10s
     Running target/debug/deps/nql-faedc460d5f14e6c

running 1 test
building extension with features `pg10 pg_test`
"cargo" "build" "--features" "pg10 pg_test" "--no-default-features"
   Compiling nql v0.0.0 (/home/ethan/repos/nql)
    Finished dev [unoptimized + debuginfo] target(s) in 1.96s

installing extension
     Copying control file to `/home/ethan/.pgx/10.13/pgx-install/share/postgresql/extension/nql.control`
     Copying shared library to `/home/ethan/.pgx/10.13/pgx-install/lib/postgresql/nql.so`
     Writing extension schema to `/home/ethan/.pgx/10.13/pgx-install/share/postgresql/extension/nql--1.0.sql`
    Finished installing nql
"/home/ethan/.pgx/10.13/pgx-install/bin/postmaster" "-D" "/home/ethan/repos/nql/target/pgx-test-data-10" "-h" "localhost" "-p" "32210", pid=5186
PostgreSQL 10.13 on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit
[2020-09-06 17:57:46.072 EDT] [5186] [5f555b59.1442]: LOG:  listening on IPv6 address "::1", port 32210
[2020-09-06 17:57:46.072 EDT] [5186] [5f555b59.1442]: LOG:  listening on IPv4 address "127.0.0.1", port 32210
[2020-09-06 17:57:46.183 EDT] [5186] [5f555b59.1442]: LOG:  listening on Unix socket "/tmp/.s.PGSQL.32210"
[2020-09-06 17:57:46.351 EDT] [5188] [5f555b5a.1444]: LOG:  database system was shut down at 2020-09-06 17:32:44 EDT
test tests::pg_test_hello_nql ... FAILED

failures:

---- tests::pg_test_hello_nql stdout ----
installing extension
    Creating database pgx_tests
thread 'tests::pg_test_hello_nql' panicked at '
[2020-09-06 17:57:46.072 EDT] [5186] [5f555b59.1442]: LOG:  listening on IPv6 address "::1", port 32210
[2020-09-06 17:57:46.072 EDT] [5186] [5f555b59.1442]: LOG:  listening on IPv4 address "127.0.0.1", port 32210
[2020-09-06 17:57:46.183 EDT] [5186] [5f555b59.1442]: LOG:  listening on Unix socket "/tmp/.s.PGSQL.32210"
[2020-09-06 17:57:46.396 EDT] [5186] [5f555b59.1442]: LOG:  database system is ready to accept connections
...
[2020-09-06 17:57:48.175 EDT] [5204] [5f555b5c.1454]: LOG:  statement: BEGIN
[2020-09-06 17:57:48.176 EDT] [5204] [5f555b5c.1454]: LOG:  statement: SELECT "tests"."test_hello_nql"();
[2020-09-06 17:57:48.176 EDT] [5204] [5f555b5c.1454]: ERROR:  schema "tests" does not exist at character 8
[2020-09-06 17:57:48.176 EDT] [5204] [5f555b5c.1454]: STATEMENT:  SELECT "tests"."test_hello_nql"();
[2020-09-06 17:57:48.176 EDT] [5204] [5f555b5c.1454]: LOG:  statement: ROLLBACK

schema "tests" does not exist
Postgres location: namespace.c:3023
Rust location: <unknown>

', /home/ethan/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-tests-0.0.13/src/framework.rs:120:21
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace


failures:
    tests::pg_test_hello_nql

test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out

Stopping Postgres

error: test failed, to rerun pass '--lib'
     [error] cargo pgx test failed with status = Some(101)

pgx-pg-sys compile issues on FreeBSD

I'm trying to compile the default extension (created via cargo pgx new) on FreeBSD 13.0, but the build fails with these errors:

out.txt

I was hopeful because compiling pgx and pgx init all worked fine. These seem like low-level errors, but I'm not sure about the cause. Any ideas? Thanks!

Examples for Customized options

Postgres has support for extension variables:

This feature was designed to allow parameters not normally known to PostgreSQL to be added by add-on modules (such as procedural languages). This allows extension modules to be configured in the standard ways.

Custom options have two-part names: an extension name, then a dot, then the parameter name proper, much like qualified names in SQL. An example is plpgsql.variable_conflict.

Because custom options may need to be set in processes that have not loaded the relevant extension module, PostgreSQL will accept a setting for any two-part parameter name. Such variables are treated as placeholders and have no function until the module that defines them is loaded. When an extension module is loaded, it will add its variable definitions, convert any placeholder values according to those definitions, and issue warnings for any unrecognized placeholders that begin with its extension name.

Does pgx provide a way to add/register variables for an extension?

Docs not available on Docs.rs

The documentation on docs.rs are not available due to:

docs.rs failed to build pgx-0.0.3
Please check the build logs and, if you believe this is docs.rs' fault, open an issue.

A few tests that use SPI and &str's fail when Postgres is compiled with --enable-debug and --enable-cassert

These tests fail:

failures:
    tests::datetime_tests::tests::pg_test_is_timezone_utc
    tests::default_arg_value_tests::tests::pg_test_option_default_argument
    tests::default_arg_value_tests::tests::pg_test_option_default_argument_specified
    tests::spi_tests::tests::pg_test_spi_returns_str
    tests::struct_type_tests::tests::pg_test_complex_out
    tests::struct_type_tests::tests::pg_test_complex_storage_and_retrieval
    tests::variadic_tests::tests::pg_test_func_with_variadic_array_args

An example failure for one is:

---- tests::struct_type_tests::tests::pg_test_complex_out stdout ----
thread 'tests::struct_type_tests::tests::pg_test_complex_out' panicked at '
[2020-07-16 13:42:25.582 MDT] [14531] [5f10ada1.38c3]: LOG:  listening on IPv6 address "::1", port 32211
[2020-07-16 13:42:25.582 MDT] [14531] [5f10ada1.38c3]: LOG:  listening on IPv4 address "127.0.0.1", port 32211
[2020-07-16 13:42:25.583 MDT] [14531] [5f10ada1.38c3]: LOG:  listening on Unix socket "/tmp/.s.PGSQL.32211"
[2020-07-16 13:42:25.594 MDT] [14531] [5f10ada1.38c3]: LOG:  database system is ready to accept connections
...
[2020-07-16 13:42:26.497 MDT] [14661] [5f10ada2.3945]: LOG:  statement: BEGIN
[2020-07-16 13:42:26.497 MDT] [14661] [5f10ada2.3945]: LOG:  statement: SELECT "tests"."test_complex_out"();
[2020-07-16 13:42:26.506 MDT] [14661] [5f10ada2.3945]: ERROR:  assertion failed: `(left == right)`
[2020-07-16 13:42:26.506 MDT] [14661] [5f10ada2.3945]: CONTEXT:  pgx-tests/src/tests/struct_type_tests.rs:80:9
[2020-07-16 13:42:26.506 MDT] [14661] [5f10ada2.3945]: STATEMENT:  SELECT "tests"."test_complex_out"();

assertion failed: `(left == right)`
  left: `"\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}\u{7f}"`,
 right: `"1.1, 2.2"`

It looks to me like pgx's SPI interface is calling SPI_finish() before it copes the resulting Datum back into the outer MemoryContext for return.

When Postgres isn't compiled with --enable-debug and --enable-cassert, the tests pass, but I think we're getting lucky and actually reading recently freed memory.

I'll fix this as part of PR #15.

Cannot run init as root

Since the latest version runs initdb I can no longer run the cargo pgx init command as root. I am trying to compile ZomboDB from source. I can run the init command as postgres but that user doesn't have permission to install the extension then so that has to be run as root but needs the pgx init run first.

pg_extern does not handle macros properly

Code prototype, your code generator doesn't understand macros.

#[doc(hidden)]
#[macro_export]
macro_rules! gen_doc {
	[$name: ident: $($all:tt)*] => {
		$crate::gen_doc! {
			@valid_doc_name: [stringify!($name)]:
			$($all)*
		}
	};
	[@valid_doc_name: [$name: expr]: $($all:tt)*] => {
		#[doc = $name]
		#[pg_extern]
		pub fn ext4test(fcinfo: pg_sys::FunctionCallInfo) -> () {
			
		}
	};
}


gen_doc! {
	ext4test:
	
}

out:

error: unexpected token: `stringify`
   --> src/pgx_path/macros_extern.rs:55:3     
    |
55  |           #[pg_extern]    <<<<<<<<<<<<<<<<<<<<<<<
    |           ^^^^^^^^^^^^
    | 
   ::: src/pg_mod.rs:39:1
    |
39  | / crate::pg_extern_trigger! [
40  | |     #[pg_extern]
41  | |     pub fn ext4test(fcinfo: pg_sys::FunctionCallInfo) -> Trigger<'static> {
42  | |        ...
...   |
135 | |     }
136 | | ];
    | |__- in this macro invocation
    |
    = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

If you remove # [pg_extern] then the code builds successfully.

Какже с вами трудно...

(Mac) error: failed to run custom build command for `pgx-pg-sys v0.1.21`

I following this Getting Started guide, when running command cargo pgx run pg13 got this errors:

(macOS 11.3.1, Xcode 12.5, rustc 1.54.0-nightly)

error: failed to run custom build command for `pgx-pg-sys v0.1.21`

Caused by:
  process didn't exit successfully: `/Users/hello/work/lab/myfile_fdw/target/debug/build/pgx-pg-sys-7e5dcc9e92761c9a/build-script-build` (exit status: 101)
  --- stdout
  cargo:rerun-if-changed=/Users/hello/.pgx/config.toml
  cargo:rerun-if-changed=include/pg10.h
  cargo:rerun-if-changed=include/pg11.h
  cargo:rerun-if-changed=include/pg12.h
  cargo:rerun-if-changed=include/pg13.h
  cargo:rerun-if-changed=cshim/pgx-cshim.c
  cargo:rerun-if-changed=cshim/Makefile

  --- stderr
  manifest_dir=/Users/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21
  shim_dir=/Users/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/cshim
  Generating bindings for pg13
  Generating bindings for pg10
  Generating bindings for pg11
  Generating bindings for pg12
  /Users/hello/.pgx/13.3/pgx-install/include/postgresql/server/c.h:59:10: fatal error: 'stdio.h' file not found
  /Users/hello/.pgx/13.3/pgx-install/include/postgresql/server/c.h:59:10: fatal error: 'stdio.h' file not found, err: true
  thread '<unnamed>' panicked at 'Unable to generate bindings for pg13: ()', /Users/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/build.rs:486:13
  note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
  /Users/hello/.pgx/11.12/pgx-install/include/postgresql/server/c.h:59:10: fatal error: 'stdio.h' file not found
  /Users/hello/.pgx/11.12/pgx-install/include/postgresql/server/c.h:59:10: fatal error: 'stdio.h' file not found, err: true
  thread '<unnamed>' panicked at 'Unable to generate bindings for pg11: ()', /Users/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/build.rs:486:13
  /Users/hello/.pgx/12.7/pgx-install/include/postgresql/server/c.h:59:10: fatal error: 'stdio.h' file not found
  /Users/hello/.pgx/12.7/pgx-install/include/postgresql/server/c.h:59:10: fatal error: 'stdio.h' file not found, err: true
  thread '<unnamed>' panicked at 'Unable to generate bindings for pg12: ()', /Users/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/build.rs:486:13
  /Users/hello/.pgx/10.17/pgx-install/include/postgresql/server/c.h:81:10: fatal error: 'stdio.h' file not found
  /Users/hello/.pgx/10.17/pgx-install/include/postgresql/server/c.h:81:10: fatal error: 'stdio.h' file not found, err: true
  thread '<unnamed>' panicked at 'Unable to generate bindings for pg10: ()', /Users/hello/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/build.rs:486:13
      [error] failed to build extension

The command cargo pgx init was successful:

  Discovered Postgres v13.3, v12.7, v11.12, v10.17
  Downloading Postgres v10.17 from https://ftp.postgresql.org/pub/source/v10.17/postgresql-10.17.tar.bz2
  Downloading Postgres v11.12 from https://ftp.postgresql.org/pub/source/v11.12/postgresql-11.12.tar.bz2
  Downloading Postgres v12.7 from https://ftp.postgresql.org/pub/source/v12.7/postgresql-12.7.tar.bz2
  Downloading Postgres v13.3 from https://ftp.postgresql.org/pub/source/v13.3/postgresql-13.3.tar.bz2
     Removing /Users/hello/.pgx/13.3
     Removing /Users/hello/.pgx/12.7
    Untarring Postgres v13.3 to /Users/hello/.pgx/13.3
    Untarring Postgres v12.7 to /Users/hello/.pgx/12.7
  Configuring Postgres v12.7
  Configuring Postgres v13.3
     Removing /Users/hello/.pgx/11.12
    Untarring Postgres v11.12 to /Users/hello/.pgx/11.12
  Configuring Postgres v11.12
     Removing /Users/hello/.pgx/10.17
    Untarring Postgres v10.17 to /Users/hello/.pgx/10.17
  Configuring Postgres v10.17
    Compiling Postgres v13.3
    Compiling Postgres v11.12
    Compiling Postgres v12.7
    Compiling Postgres v10.17
   Installing Postgres v11.12 to /Users/hello/.pgx/11.12/pgx-install
   Installing Postgres v12.7 to /Users/hello/.pgx/12.7/pgx-install
   Installing Postgres v13.3 to /Users/hello/.pgx/13.3/pgx-install
   Installing Postgres v10.17 to /Users/hello/.pgx/10.17/pgx-install
   Validating /Users/hello/.pgx/10.17/pgx-install/bin/pg_config
   Validating /Users/hello/.pgx/11.12/pgx-install/bin/pg_config
   Validating /Users/hello/.pgx/12.7/pgx-install/bin/pg_config
   Validating /Users/hello/.pgx/13.3/pgx-install/bin/pg_config
The last command took 418.053 seconds.

cargo pgx run fails without rustfmt

error: failed to run custom build command for `pgx-pg-sys v0.1.21`

Caused by:
  process didn't exit successfully: `/home/singpolyma/src/dhall-pg/dhall_pg/target/debug/build/pgx-pg-sys-696104a9c020e661/build-script-build` (exit code: 1)
--- stdout
cargo:rerun-if-changed=/home/singpolyma/.pgx/config.toml
cargo:rerun-if-changed=include/pg10.h
cargo:rerun-if-changed=include/pg11.h
cargo:rerun-if-changed=include/pg12.h
cargo:rerun-if-changed=include/pg13.h
cargo:rerun-if-changed=cshim/pgx-cshim.c
cargo:rerun-if-changed=cshim/Makefile

--- stderr
manifest_dir=/home/singpolyma/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21
shim_dir=/home/singpolyma/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/cshim
Generating bindings for pg10
Generating bindings for pg11
Generating bindings for pg12
Generating bindings for pg13
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/port.h:175:70: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/port.h:177:55: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/port.h:179:58: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/port.h:181:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:158:40: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:159:49: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:162:56: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:162:30: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:164:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:165:52: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:167:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:171:57: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:171:31: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:174:56: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:174:30: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:176:41: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:190:48: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:243:58: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:249:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/elog.h:434:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/palloc.h:133:44: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/utils/palloc.h:134:80: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/lib/stringinfo.h:95:67: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/12.7/pgx-install/include/postgresql/server/lib/stringinfo.h:106:78: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:136:40: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:137:49: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:140:53: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:140:27: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:142:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:143:52: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:145:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:149:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:149:28: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:152:53: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:152:27: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:154:41: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:168:48: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:225:58: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:231:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/elog.h:414:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/palloc.h:133:44: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/utils/palloc.h:134:80: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/lib/stringinfo.h:95:67: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/11.12/pgx-install/include/postgresql/server/lib/stringinfo.h:106:78: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/port.h:176:70: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/port.h:178:55: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/port.h:180:58: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/port.h:182:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:157:40: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:158:49: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:161:56: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:161:30: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:163:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:164:52: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:166:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:170:57: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:170:31: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:173:56: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:173:30: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:175:41: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:189:48: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:221:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/elog.h:437:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/palloc.h:133:44: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/utils/palloc.h:134:80: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/lib/stringinfo.h:96:67: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/13.3/pgx-install/include/postgresql/server/lib/stringinfo.h:107:78: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:136:40: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:137:49: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:140:53: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:140:27: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:142:43: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:143:52: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:145:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:149:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:149:28: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:152:53: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:152:27: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:154:41: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:168:48: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:225:58: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:231:54: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/elog.h:414:47: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/palloc.h:133:44: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/utils/palloc.h:134:80: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/lib/stringinfo.h:95:67: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
/home/singpolyma/.pgx/10.17/pgx-install/include/postgresql/server/lib/stringinfo.h:106:78: warning: 'format' attribute argument not supported: gnu_printf [-Wignored-attributes], err: false
[[bindings_diff]] "rustfmt" "/home/singpolyma/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/src/pg11.rs"
      [error] Unable to write bindings file for pg11 to `/home/singpolyma/.cargo/registry/src/github.com-1ecc6299db9ec823/pgx-pg-sys-0.1.21/src/pg11.rs`: No such file or directory (os error 2)

      [error] failed to build extension

Rework cargo-pgx with different abilities

  • build.rs no longer downloads/compiles postgres. It'll instead be limited to generating the "bindgen" bindings for each version and compiling pgx's "cshim" static library (this'll be difficult to resolve for Windows users, I think)
  • cargo pgx init comes to life and it does the dowload/compile Postgres versions dance (in parallel) into ~/.pgx/, or it can use any/all Postgres versions you might already have installed on your computer, specified via args to cargo pgx init. Paths to each version's pg_config will be saved in ~/.pgx/config.toml.
  • cargo pgx install stays, and continues to simply compile/install the extension to the Postgres instance specified by whatever pg_config binary is currently on the $PATH
  • cargo pgx start PG_VER comes to life to start a pg instance, specific to pgx
  • cargo pgx stop PG_VER comes to life to stop a pg instance, specific to pgx
  • cargo pgx status [pg_ver] comes to life to see what's up with a pg instance, specific to pgx
  • cargo pgx run PG_VER [dbname] comes to life and it compiles/installs the extension to the PG instance described in ~/.pgx/config.toml and starts it (if not already running) and immediately pops you into psql connected to the specified database (if unspecified, the dbname will be the extension name, creating it if necessary).
  • caro pgx test [pg_ver] stays, but will spin up a temporary Postgres instance using what ~/.pgx/config.toml points to
  • cargo pgx package builds (at least) a directory structure in target/ that can be manually (for now) turned into a tarball/deb/rpm

In the case of using Postgres instances already installed on your computer (likely through your OS' package manager) you'll need write access to the directories from pg_config --pkglibdir and pg_config --sharedir. You'll be on your own to sort that out.

I think maybe the typical workflow here is that you'll have one primary version of Postgres installed (via apt/dnf/brew/whatever), and then cargo pgx init will manage the other two. So for example, you might first invoke cargo pgx init like so:

$ cargo pgx init --pg12 /usr/bin/pg_config

At this point, cargo pgx init will only download/compile/install PG10 and PG11.

There'll be system requirements on (at least)

  • a C compiler toolchain (gcc, clang/llvm)
  • libreadline-dev [ubuntu] (for compiling Postgres with that support)
  • zlib1g-dev [ubuntu] (for compiling Postgres with that supprt)

Additionally, the Postgres versions that cargo pgx init does compile itself will have '--enable-debug' '--enable-cassert' turned on so that in the case of core dumps, they can be debugged with gdb/lldb.

Please add cargo-pgx to nixpkgs

I have tried to build a Nix derivation for cargo-pgx, that would build cargo-pgx and install it into my nix-shell, but my knowledge of nix is unfortunately lacking.

It would be great if cargo-pgx can be added to the Nix Package Registry. This would involve a contribution to https://github.com/NixOS/nixpkgs. Here are all the other cargo subcommands that can be found in the Nix Package Registry: https://search.nixos.org/packages?channel=20.09&from=0&size=50&sort=relevance&query=cargo

Here is the (very simple) Nix derivation for the cargo web subcommand: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/tools/cargo-web/default.nix

Here was my (failed) attempt at packaging cargo-pgx:

# https://github.com/NixOS/nixpkgs/issues/89563
# https://github.com/NixOS/nixpkgs/issues/32720
# https://github.com/NixOS/nixpkgs/issues/37945
# https://github.com/zombodb/pgx
# https://github.com/zombodb/pgx/tree/master/cargo-pgx
# https://eipi.xyz/blog/packaging-a-rust-project-for-nix/
# https://github.com/NixOS/nixpkgs/blob/master/doc/languages-frameworks/rust.section.md
# https://crates.io/crates/pgx
# https://discourse.nixos.org/t/how-to-install-openssl-to-compile-against/1249/2
# https://nixos.org/manual/nixpkgs/stable/#chap-multiple-output
# https://github.com/zombodb/pgx/issues/96
# https://nixos.org/manual/nixpkgs/stable/#chap-stdenv
# https://github.com/NixOS/nixpkgs/issues/31172
# https://github.com/NixOS/nixpkgs/issues/15495
# https://github.com/zombodb/pgx/blob/master/cargo-pgx/README.md
# https://github.com/kolloch/crate2nix/issues/148#issuecomment-699630254
# https://github.com/NixOS/nixpkgs/issues/15003
# https://github.com/rust-lang/cargo/wiki/Third-party-cargo-subcommands
# Adding ~/.cargo/bin: to your PATH might help.

{ rustPlatform, buildRustPackage, fetchFromGitHub, lib, openssl, pkg-config, mkDerivation }:

buildRustPackage rec {
    pname = "pgx";
    version = "0.1.19";

    src = fetchFromGitHub {
        owner = "zombodb";
        repo = pname;
        rev = "v${version}";
        # sha256 = "0000000000000000000000000000000000000000000000000000";
        # sha256 = lib.fakeSha256;
        sha256 = "0a5cifln9dg3wdlpvkdy3lkccdwdfn51a360hnqrwv27lpalw1ap";
    };

    # cargoSha256 = "0000000000000000000000000000000000000000000000000000";
    # cargoSha256 = lib.fakeSha256;
    cargoSha256 = "18501z19n3ca70jg5l62bn1rki41f2gdlyji5ygbv7fja7p7dsrv";

    # cargoRoot = "source";

    # sourceRoot = ".";
    # sourceRoot = "source/cargo-pgx";
    # cargoPatches = [
    #     ./add-Cargo.lock.patch
    # ];

    nativeBuildInputs = [ pkg-config ];

    buildInputs = [ openssl ];

    # https://github.com/zombodb/pgx/blob/master/cargo-pgx/Cargo.toml
    # cargoDepsName = "cargo-pgx";
    # https://github.com/zombodb/pgx/blob/master/Cargo.toml
    cargoDepsName = "pgx-parent";

    meta = with lib; {
        description = "Build Postgres Extensions with Rust!";
        homepage = "https://github.com/zombodb/pgx";
        license = licenses.mit;
        maintainers = [ maintainers.eeeebbbbrrrr ];
    };
}

Here is the error that I get when this Nix derivation is executed:

error: failed to run custom build command for `pgx-pg-sys v0.1.19 (/build/source/pgx-pg-sys)`

Caused by:
  process didn't exit successfully: `/build/source/target/release/build/pgx-pg-sys-1a789ec37c83b22c/build-script-build` (exit code: 1)
  --- stderr
  manifest_dir=/build/source/pgx-pg-sys
  shim_dir=/build/source/pgx-pg-sys/cshim
  Error: Custom { kind: NotFound, error: "/homeless-shelter/.pgx/config.toml not found.  Have you run `cargo pgx init` yet?" }
warning: build failed, waiting for other jobs to finish...
error: build failed
builder for '/nix/store/aq4y3jmvzy5jrakwv5lymz4a37hkhlnl-pgx-0.1.19.drv' failed with exit code 101
error: build of '/nix/store/aq4y3jmvzy5jrakwv5lymz4a37hkhlnl-pgx-0.1.19.drv' failed

I'm not sure whether the project layout would have to change, or whether a Cargo.lock would have to be added for the cargo-pgx project, or whether the pgx-pg-sys project can be excluded from the general build. With my Nix derivation, all the Rust projects in this repository is built. Ideally, I would like to have only cargo-pgx built.

pgx init fails on OSX

I was having some trouble running cargo pgx init --pg13 download on my machine. The command.spawn() in configure_postgres was failing saying [error] No such file or directory (os error 2).

The pgdir and command_str both looked fine and, PG builds from the command line. Spawn succeeds when the command is modified to use the full path. I think this is the same behavior at rust-lang/rust#37868 (comment)

Make raw-SQL DDL management more flexible

Details

Two related ideas for improvement to the handling of raw-SQL DDL in pgx extensions, bringing over from Discord conversation.

Part 1: Allow DDL from script

Creating raw-SQL DDL for an extension now happens in one (or more) extension_sql!(); blocks inside lib.rs. Currently I use this to create tables, views, comments, etc., and these blocks get lengthy.

extension_sql!(
    r#"
-- 100 lines of raw SQL inline, will continue to grow over time... ew.
"#
);

I would prefer to be able to remove the raw SQL from the .rs script and put in a dedicated .sql script. Something like this:

extension_sql!(include_str!("ddl_pre_pgx_v0_3.sql"));

Attempting to do so results in an error error: expected a single raw string literal with sql.

Part 2: Improve raw-DDL across extension versions

A change to the raw-SQL DDL requires adding the changes in both the SQL contained in lib.rs and in a version-to-version migration scripts, e.g. <extname>--<old_version>--<new_version>.sql. It'd be great to see pgx follow the pattern that Postgres takes with version to version scripts where subsequent versions follow the upgrade path to iterate through the version-specific DDL in order. e.g. Let me to define the initial DDL (v0.1) in a version-specific script (see Part 1). When a new feature requires DDL changes, allow me to define an additional v0.2 script to include. Installing the latest version should follow through the upgrade path to install all DDL without duplicating the code to handle clean install & upgrade separately.

The code just stopped building, which is weird.

cargo pgx package -d
installing extension
     Copying control file to `target/debug/x-pg12/usr/share/postgresql/extension/x.control`
     Copying shared library to `target/debug/x-pg12/usr/lib/postgresql/x.so`
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("expected identifier")', /home/denis/.cargo/registry/src/github.com-1ecc6299db9ec823/cargo-pgx-0.1.5/src/commands/schema.rs:238:46
stack backtrace:
   0:     0x5586c6a63a30 - std::backtrace_rs::backtrace::libunwind::trace::he85dfb3ae4206056
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/../../backtrace/src/backtrace/libunwind.rs:96
   1:     0x5586c6a63a30 - std::backtrace_rs::backtrace::trace_unsynchronized::h1ad28094d7b00c21
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/../../backtrace/src/backtrace/mod.rs:66
   2:     0x5586c6a63a30 - std::sys_common::backtrace::_print_fmt::h901b54610713cd21
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:79
   3:     0x5586c6a63a30 - <std::sys_common::backtrace::_print::DisplayBacktrace as core::fmt::Display>::fmt::hb0ad78ee1571f7e0
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:58
   4:     0x5586c6a8d48c - core::fmt::write::h1857a60b204f1b6a
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/fmt/mod.rs:1080
   5:     0x5586c6a5cb72 - std::io::Write::write_fmt::hf7b7d7b243f84a36
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/io/mod.rs:1516
   6:     0x5586c6a67afd - std::sys_common::backtrace::_print::hd093978a5287b8ff
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:61
   7:     0x5586c6a67afd - std::sys_common::backtrace::print::h20f46787581d56d7
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:48
   8:     0x5586c6a67afd - std::panicking::default_hook::{{closure}}::h486cbb4b82ffc357
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:208
   9:     0x5586c6a677a8 - std::panicking::default_hook::h4190c9e3edd4d591
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:227
  10:     0x5586c6a68206 - std::panicking::rust_panic_with_hook::h72e78719cdda225c
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:581
  11:     0x5586c6a67d89 - std::panicking::begin_panic_handler::{{closure}}::h8bd07dbd34150a96
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:484
  12:     0x5586c6a63ebc - std::sys_common::backtrace::__rust_end_short_backtrace::hdb6b3066ad29028a
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/sys_common/backtrace.rs:153
  13:     0x5586c6a67d49 - rust_begin_unwind
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:483
  14:     0x5586c6a8b0c1 - core::panicking::panic_fmt::hb15d6f55e8472f62
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/panicking.rs:85
  15:     0x5586c6a8aee3 - core::option::expect_none_failed::he492a18657d97593
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/option.rs:1234
  16:     0x5586c67220ea - cargo_pgx::commands::schema::generate_schema::hda22616a3eebdd0e
  17:     0x5586c6750dc9 - cargo_pgx::commands::install::install_extension::hc96cc1e8a41ad02f
  18:     0x5586c677a431 - cargo_pgx::commands::package::package_extension::he8eaf96779f7ce2f
  19:     0x5586c673a984 - cargo_pgx::do_it::h8dd20313c2db29d9
  20:     0x5586c673961d - cargo_pgx::main::h9d681428f61d126f
  21:     0x5586c6768d13 - std::sys_common::backtrace::__rust_begin_short_backtrace::hd8bb6822f116bd37
  22:     0x5586c6768f9c - std::rt::lang_start::{{closure}}::he5f098332b39b742
  23:     0x5586c6a68690 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h5e15f43ce28787f7
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/core/src/ops/function.rs:259
  24:     0x5586c6a68690 - std::panicking::try::do_call::h764f1891769113e9
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:381
  25:     0x5586c6a68690 - std::panicking::try::h0f2fe4fdd5e0ad19
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panicking.rs:345
  26:     0x5586c6a68690 - std::panic::catch_unwind::h1634e40dd3a19f80
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/panic.rs:382
  27:     0x5586c6a68690 - std::rt::lang_start_internal::h8d4bc7b854bbd5fe
                               at /rustc/7f7a1cbfd3b55daee191247770627afab09eece2/library/std/src/rt.rs:51
  28:     0x5586c673c712 - main
  29:     0x7f115c205152 - __libc_start_main
  30:     0x5586c67130ce - _start
  31:                0x0 - <unknown>

How to solve this? It seems that nothing has been updated, except for its own code.

Need ability to elide downloading/compiling 3 Postgres versions during build

pgx requires, right now, the header files from 3 different versions of Postgres (v10/11/12) for building, and for testing (via cargo pgx test).

Currently, pgx downloads, configures, compiles, and installs those three PG versions while building a crate that uses pgx.

We need a way, for pgx users to instead use already-locally-installed versions. It'll necessitate that the user have all three versions installed locally, but then pgx won't have to download/compile them -- drastically improving the initial build time and eliding a ton of computer-specific complexity.

I'll flesh out the details as I work through implementing this, but what I'm considering is having this controlled via a set of environment variables that point to the pg_config binary for each PG version. For example:

PGX_PG10_CONFIG=~zdb/pg10/bin/pg_config \
PGX_PG11_CONFIG=~zdb/pg11/bin/pg_config \
PGX_PG12_CONFIG=~zdb/pg10/bin/pg_config \
cargo pgx install

(on my laptop, I have each installed in the user "zdb"'s home directory, hence the paths).

For a computer that isn't mine, you'd likely install each Postgres version using your system's package manager, and then adjust the paths accordingly.

On my laptop, this already reduces the initial cargo pgx install from about 3m 30s minutes to 1m 8s. On slower computers, the difference will be even more significant.

I don't yet know how to handle running tests via cargo pgx test. Currently, that spins up a private Postgres instance from our build.rs compiled/installed Postgres'. Not sure how to handle when using system-installed Postgres'.

How to define an aggregate function?

Hi. Before I begin - thanks for this great project!

I'm trying to build an aggregate function for my custom data type as described in Postgres documentation. However I couldn't find a programmatic way of declaring such function using pgx API. It doesn't seem to be possible from Rust level - only from custom sql load scripts, or did I miss something?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.