Help returning SetOf PgHeapTuple
Hello,
I am trying to fiddle with pgrx but I can't figure out how to return a SetOf PgHeapTuple. The primary purpose is to be able to return a SETOF with an unknown number of columns (and unknown column types and name) at compile time. I thought of using Tupdesc like this
#[pg_extern]
fn test() -> SetOfIterator<'static, PgHeapTuple<'static, AllocatedByRust>> {
// 1) Tuple descriptor
let tupdesc = unsafe {
let tupdesc = pg_sys::CreateTemplateTupleDesc(1);
let cname1 = std::ffi::CString::new("id").unwrap();
pg_sys::TupleDescInitEntry(tupdesc, 1, cname1.as_ptr(), pg_sys::INT8OID, -1, 0);
pg_sys::BlessTupleDesc(tupdesc)
};
let tupdesc = unsafe { PgTupleDesc::from_pg(tupdesc)};
let heaptuple = unsafe {
PgHeapTuple::from_datums(tupdesc, vec![1i64.into_datum()])
.expect("Fail in PgHeapTuple")
};
SetOfIterator::new(vec![heaptuple].into_iter())
}
But I get this :
thread 'main' panicked at /home/simon/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pgrx-sql-entity-graph-0.16.1/src/pg_extern/entity/mod.rs:215:128:
called `Option::unwrap()` on a `None` value
with the stack backstrace :
stack backtrace:
0: 0x5ade6d45a712 - std::backtrace_rs::backtrace::libunwind::trace::h9c1aa7b29a521839
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/../../backtrace/src/backtrace/libunwind.rs:117:9
1: 0x5ade6d45a712 - std::backtrace_rs::backtrace::trace_unsynchronized::hb123c31478ec901c
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/../../backtrace/src/backtrace/mod.rs:66:14
2: 0x5ade6d45a712 - std::sys::backtrace::_print_fmt::hdda75a118fd2034a
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/sys/backtrace.rs:66:9
3: 0x5ade6d45a712 - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::hf435e8e9347709a8
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/sys/backtrace.rs:39:26
4: 0x5ade6d477723 - core::fmt::rt::Argument::fmt::h9802ea71fd88c728
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/core/src/fmt/rt.rs:173:76
5: 0x5ade6d477723 - core::fmt::write::h0a51fad3804c5e7c
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/core/src/fmt/mod.rs:1465:25
6: 0x5ade6d458663 - std::io::default_write_fmt::h7e00b0a8732ee2a2
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/io/mod.rs:639:11
7: 0x5ade6d458663 - std::io::Write::write_fmt::h9759e4151bf4a45e
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/io/mod.rs:1954:13
8: 0x5ade6d45a562 - std::sys::backtrace::BacktraceLock::print::h1ec5ce5bb8ee285e
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/sys/backtrace.rs:42:9
9: 0x5ade6d45b5d6 - std::panicking::default_hook::{{closure}}::h5ffefe997a3c75e4
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:300:27
10: 0x5ade6d45b3d9 - std::panicking::default_hook::h820c77ba0601d6bb
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:327:9
11: 0x5ade6d45be82 - std::panicking::rust_panic_with_hook::h8b29cbe181d50030
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:833:13
12: 0x5ade6d45bce6 - std::panicking::begin_panic_handler::{{closure}}::h9f5b6f6dc6fde83e
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:699:13
13: 0x5ade6d45ac09 - std::sys::backtrace::__rust_end_short_backtrace::hd7b0c344383b0b61
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/sys/backtrace.rs:168:18
14: 0x5ade6d45b9ad - __rustc[5224e6b81cd82a8f]::rust_begin_unwind
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:697:5
15: 0x5ade6d369420 - core::panicking::panic_fmt::hc49fc28484033487
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/core/src/panicking.rs:75:14
16: 0x5ade6d3694ac - core::panicking::panic::h239804395728b21f
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/core/src/panicking.rs:145:5
17: 0x5ade6d369399 - core::option::unwrap_failed::hec54eb4737b382ca
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/core/src/option.rs:2072:5
18: 0x5ade6d3fdca5 - core::option::Option<T>::unwrap::h8e15c36271be674f
at /home/simon/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:1005:21
19: 0x5ade6d3fdca5 - <pgrx_sql_entity_graph::pg_extern::entity::PgExternEntity as pgrx_sql_entity_graph::to_sql::ToSql>::to_sql::h63418e106595c73e
at /home/simon/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pgrx-sql-entity-graph-0.16.1/src/pg_extern/entity/mod.rs:215:128
20: 0x5ade6d3e15a4 - <pgrx_sql_entity_graph::SqlGraphEntity as pgrx_sql_entity_graph::to_sql::ToSql>::to_sql::h035345ed78f6a808
at /home/simon/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pgrx-sql-entity-graph-0.16.1/src/lib.rs:272:26
21: 0x5ade6d3ebe05 - pgrx_sql_entity_graph::pgrx_sql::PgrxSql::to_sql::h871cbf5e96970ad4
at /home/simon/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pgrx-sql-entity-graph-0.16.1/src/pgrx_sql.rs:428:32
22: 0x5ade6d36d176 - pgrx_sql_entity_graph::pgrx_sql::PgrxSql::to_file::h038075d68f29814f
at /home/simon/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/pgrx-sql-entity-graph-0.16.1/src/pgrx_sql.rs:257:30
23: 0x5ade6d3723a8 - pgrx_embed_pg_datafusion::pgrx_embed::main::h5baf6284bb804583
at /tmp/.tmp8LWM5n:1:1539
24: 0x5ade6d37090b - core::ops::function::FnOnce::call_once::h82fb2985a4b9ad66
at /home/simon/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:250:5
25: 0x5ade6d38121e - std::sys::backtrace::__rust_begin_short_backtrace::h9a89f23cb6f95050
at /home/simon/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/sys/backtrace.rs:152:18
26: 0x5ade6d379bb1 - std::rt::lang_start::{{closure}}::h51e379f2aa336956
at /home/simon/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:206:18
27: 0x5ade6d454a00 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::hf19f6f3c4f0cdb1c
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/core/src/ops/function.rs:284:21
28: 0x5ade6d454a00 - std::panicking::catch_unwind::do_call::hdc689d1fa1f67ace
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:589:40
29: 0x5ade6d454a00 - std::panicking::catch_unwind::h1025d97250558c4b
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:552:19
30: 0x5ade6d454a00 - std::panic::catch_unwind::h3f76beef3f07b6dc
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panic.rs:359:14
31: 0x5ade6d454a00 - std::rt::lang_start_internal::{{closure}}::haf71a34e0fbc4d76
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/rt.rs:175:24
32: 0x5ade6d454a00 - std::panicking::catch_unwind::do_call::hbd7dad3d92d409ee
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:589:40
33: 0x5ade6d454a00 - std::panicking::catch_unwind::h69749cff2ef3daa8
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panicking.rs:552:19
34: 0x5ade6d454a00 - std::panic::catch_unwind::ha18d8f0ab15c4858
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/panic.rs:359:14
35: 0x5ade6d454a00 - std::rt::lang_start_internal::h31bbb7f936fd6b5d
at /rustc/29483883eed69d5fb4db01964cdf2af4d86e9cb2/library/std/src/rt.rs:171:5
36: 0x5ade6d379b97 - std::rt::lang_start::h097ed4613240bdf6
at /home/simon/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/std/src/rt.rs:205:5
37: 0x5ade6d37256e - main
38: 0x746c8e22a1ca - __libc_start_call_main
at ./csu/../sysdeps/nptl/libc_start_call_main.h:58:16
39: 0x746c8e22a28b - __libc_start_main_impl
at ./csu/../csu/libc-start.c:360:3
40: 0x5ade6d369ce5 - _start
41: 0x0 - <unknown>
Am i missing something ?
Thanks !
I think what you're trying to do is a bit documented here: https://github.com/pgcentralfoundation/pgrx/blob/2e515ae3fe3d350258ce9cd492ce41a7afcbaaef/pgrx-tests/src/tests/heap_tuple.rs#L558-L577
The issue is that returning SetOfIterator<PgHeapTuple> directly doesn't work because the SQL generator can't determine what composite type name to use in the generated RETURNS SETOF clause, i.e. it panics because ty.composite_type is None.
I'm guessing you can either
- Use a named composite type with
composite_type!("TypeName")if your structure is known at compile time - Override the SQL with
#[pg_extern(sql = "...")]to returnSETOF RECORDif columns are truly dynamic
Thank you for your input, and I am sorry for the late answer !
The idea is that columns are not known at compile time. Hence, I will explore the possibility of returning a SETOF RECORD !