`unreachable` code entered when `SELECT`ing nested composite types and `DOMAIN`s
Closed this issue · 7 comments
Execute the following transaction on a PostgreSQL database:
BEGIN;
CREATE TYPE foo AS (x integer);
CREATE DOMAIN bar AS foo NOT NULL;
CREATE TYPE fizz AS (y bar);
CREATE TABLE buzz(z fizz NOT NULL);
INSERT INTO buzz VALUES (ROW(ROW(1)));
COMMIT;Now compile and run the following Rust program:
#![expect(
clippy::trait_duplication_in_bounds,
reason = "can't fix since part of ToSql macro"
)]
use core::{
net::{IpAddr, Ipv6Addr},
time::Duration,
};
use postgres_types::{FromSql, ToSql};
use tokio::runtime::Builder;
use tokio_postgres::{
config::{ChannelBinding, Config, LoadBalanceHosts, SslMode, TargetSessionAttrs},
tls::NoTls,
IsolationLevel,
};
#[derive(Debug, FromSql, ToSql)]
#[postgres(name = "foo")]
struct Foo {
x: i32,
}
#[derive(FromSql)]
#[postgres(name = "bar")]
struct Bar(Foo);
#[derive(FromSql)]
#[postgres(name = "fizz")]
struct Fizz {
y: Bar,
}
fn main() {
Builder::new_current_thread()
.enable_all()
.build()
.unwrap()
.block_on(async {
let mut config = Config::new();
let c = config
.application_name("bug")
.channel_binding(ChannelBinding::Disable)
.connect_timeout(Duration::from_secs(10))
.dbname("example")
.host("")
.hostaddr(IpAddr::V6(Ipv6Addr::LOCALHOST))
.keepalives(true)
.keepalives_idle(Duration::from_secs(300))
.load_balance_hosts(LoadBalanceHosts::Disable)
.password(b"password")
.port(5432)
.ssl_mode(SslMode::Disable)
.target_session_attrs(TargetSessionAttrs::Any)
.user("example");
let (mut client, con) = c.connect(NoTls).await.unwrap();
tokio::spawn(async move {
con.await.unwrap();
});
let txn = client
.build_transaction()
.isolation_level(IsolationLevel::Serializable)
.read_only(true)
.start()
.await
.unwrap();
let stmt = txn
.prepare_typed("SELECT z FROM buzz;", [].as_slice())
.await
.unwrap();
let row = txn.query_one(&stmt, &[]).await.unwrap();
// The `panic` occurs on the below line.
let col1 = row.get::<'_, _, Fizz>(0);
println!("{}", col1.y.0.x);
txn.commit().await.unwrap();
});
}[zack@laptop bug]$ export RUST_BACKTRACE=full && cargo run
Updating crates.io index
Locking 98 packages to latest compatible versions
Adding fallible-iterator v0.2.0 (latest: v0.3.0)
Adding generic-array v0.14.7 (latest: v1.1.0)
Adding hermit-abi v0.3.9 (latest: v0.4.0)
Adding siphasher v0.3.11 (latest: v1.0.1)
Adding wasi v0.11.0+wasi-snapshot-preview1 (latest: v0.13.3+wasi-0.2.2)
Adding windows-sys v0.52.0 (latest: v0.59.0)
Adding zerocopy v0.7.35 (latest: v0.8.10)
Adding zerocopy-derive v0.7.35 (latest: v0.8.10)
Compiling proc-macro2 v1.0.89
Compiling unicode-ident v1.0.13
Compiling libc v0.2.164
Compiling typenum v1.17.0
Compiling version_check v0.9.5
Compiling cfg-if v1.0.0
Compiling autocfg v1.4.0
Compiling byteorder v1.5.0
Compiling subtle v2.6.1
Compiling tinyvec_macros v0.1.1
Compiling bytes v1.8.0
Compiling unicode-bidi v0.3.17
Compiling unicode-properties v0.1.3
Compiling tinyvec v1.8.0
Compiling futures-sink v0.3.31
Compiling pin-project-lite v0.2.15
Compiling parking_lot_core v0.9.10
Compiling futures-core v0.3.31
Compiling cpufeatures v0.2.15
Compiling memchr v2.7.4
Compiling base64 v0.22.1
Compiling smallvec v1.13.2
Compiling generic-array v0.14.7
Compiling fallible-iterator v0.2.0
Compiling siphasher v0.3.11
Compiling slab v0.4.9
Compiling lock_api v0.4.12
Compiling heck v0.5.0
Compiling scopeguard v1.2.0
Compiling phf_shared v0.11.2
Compiling futures-task v0.3.31
Compiling quote v1.0.37
Compiling unicode-normalization v0.1.24
Compiling pin-utils v0.1.0
Compiling phf v0.11.2
Compiling futures-channel v0.3.31
Compiling log v0.4.22
Compiling whoami v1.5.2
Compiling getrandom v0.2.15
Compiling socket2 v0.5.7
Compiling mio v1.0.2
Compiling syn v2.0.87
Compiling rand_core v0.6.4
Compiling percent-encoding v2.3.1
Compiling tokio v1.41.1
Compiling parking_lot v0.12.3
Compiling stringprep v0.1.5
Compiling crypto-common v0.1.6
Compiling block-buffer v0.10.4
Compiling digest v0.10.7
Compiling md-5 v0.10.6
Compiling sha2 v0.10.8
Compiling hmac v0.12.1
Compiling zerocopy-derive v0.7.35
Compiling futures-macro v0.3.31
Compiling postgres-derive v0.4.6
Compiling async-trait v0.1.83
Compiling tokio-util v0.7.12
Compiling zerocopy v0.7.35
Compiling futures-util v0.3.31
Compiling ppv-lite86 v0.2.20
Compiling rand_chacha v0.3.1
Compiling rand v0.8.5
Compiling postgres-protocol v0.6.7
Compiling postgres-types v0.2.8
Compiling tokio-postgres v0.7.12
Compiling bug v0.1.0 (/home/zack/projects/bug)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 6.81s
Running `target/debug/bug`
thread 'main' panicked at src/main.rs:16:17:
internal error: entered unreachable code
stack backtrace:
0: 0x5b8541de129a - std::backtrace_rs::backtrace::libunwind::trace::h99efb0985cae5d78
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/../../backtrace/src/backtrace/libunwind.rs:116:5
1: 0x5b8541de129a - std::backtrace_rs::backtrace::trace_unsynchronized::he2c1aa63b3f7fad8
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/../../backtrace/src/backtrace/mod.rs:66:5
2: 0x5b8541de129a - std::sys::backtrace::_print_fmt::h8a221d40f5e0f88b
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/sys/backtrace.rs:66:9
3: 0x5b8541de129a - <std::sys::backtrace::BacktraceLock::print::DisplayBacktrace as core::fmt::Display>::fmt::h304520fd6a30aa07
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/sys/backtrace.rs:39:26
4: 0x5b8541e00cfb - core::fmt::rt::Argument::fmt::h5da9c218ec984eaf
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/fmt/rt.rs:177:76
5: 0x5b8541e00cfb - core::fmt::write::hf5713710ce10ff22
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/fmt/mod.rs:1178:21
6: 0x5b8541dde1f3 - std::io::Write::write_fmt::hda708db57927dacf
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/io/mod.rs:1823:15
7: 0x5b8541de2442 - std::sys::backtrace::BacktraceLock::print::hbcdbec4d97c91528
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/sys/backtrace.rs:42:9
8: 0x5b8541de2442 - std::panicking::default_hook::{{closure}}::he1ad87607d0c11c5
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:266:22
9: 0x5b8541de20ae - std::panicking::default_hook::h81c8cd2e7c59ee33
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:293:9
10: 0x5b8541de2ccf - std::panicking::rust_panic_with_hook::had2118629c312a4a
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:797:13
11: 0x5b8541de2983 - std::panicking::begin_panic_handler::{{closure}}::h7fa5985d111bafa2
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:664:13
12: 0x5b8541de1779 - std::sys::backtrace::__rust_end_short_backtrace::h704d151dbefa09c5
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/sys/backtrace.rs:170:18
13: 0x5b8541de2644 - rust_begin_unwind
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:662:5
14: 0x5b8541c24ba3 - core::panicking::panic_fmt::h3eea515d05f7a35e
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/panicking.rs:74:14
15: 0x5b8541c24c2c - core::panicking::panic::h102d65dbfa674afe
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/panicking.rs:148:5
16: 0x5b8541c65f92 - <bug::Foo as postgres_types::FromSql>::from_sql::h43e1abeab9a3c013
at /home/zack/projects/bug/src/main.rs:16:17
17: 0x5b8541c66626 - <bug::Bar as postgres_types::FromSql>::from_sql::h3bf354d1b63b138d
at /home/zack/projects/bug/src/main.rs:21:17
18: 0x5b8541c49be0 - postgres_types::FromSql::from_sql_nullable::heb890c98a7575749
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/postgres-types-0.2.8/src/lib.rs:553:26
19: 0x5b8541c3a5b6 - postgres_types::private::read_value::h60ed5086d229f1fd
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/postgres-types-0.2.8/src/private.rs:33:5
20: 0x5b8541c66c04 - <bug::Fizz as postgres_types::FromSql>::from_sql::hd1e47626297d0f67
at /home/zack/projects/bug/src/main.rs:24:17
21: 0x5b8541c49b60 - postgres_types::FromSql::from_sql_nullable::h8b6560ee4998bc3c
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/postgres-types-0.2.8/src/lib.rs:553:26
22: 0x5b8541c3ff59 - tokio_postgres::row::Row::get_inner::hbdb55d077f4a2675
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-postgres-0.7.12/src/row.rs:184:9
23: 0x5b8541c3fb8e - tokio_postgres::row::Row::get::h51f09083614dfe15
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-postgres-0.7.12/src/row.rs:151:15
24: 0x5b8541c4ac65 - bug::main::{{closure}}::hec6cf66abc2b37c0
at /home/zack/projects/bug/src/main.rs:67:24
25: 0x5b8541c3a1fd - <core::pin::Pin<P> as core::future::future::Future>::poll::h5b0901c32bd73ba6
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/future/future.rs:123:9
26: 0x5b8541c3a2bd - <core::pin::Pin<P> as core::future::future::Future>::poll::hcf178ea35cd368f9
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/future/future.rs:123:9
27: 0x5b8541c34bff - tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}}::h5c8ff6977dfd5361
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:729:57
28: 0x5b8541c34b25 - tokio::runtime::coop::with_budget::h79f7fee45e1fa95c
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/coop.rs:107:5
29: 0x5b8541c34b25 - tokio::runtime::coop::budget::ha98b8bca93bacaa2
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/coop.rs:73:5
30: 0x5b8541c34b25 - tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::h1c41bed8d6c2e705
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:729:25
31: 0x5b8541c324b0 - tokio::runtime::scheduler::current_thread::Context::enter::h75f2cabd0440a202
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:428:19
32: 0x5b8541c3420b - tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::hd312ed3b2fc5c4b0
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:728:36
33: 0x5b8541c336a4 - tokio::runtime::scheduler::current_thread::CoreGuard::enter::{{closure}}::hfcbec99e2427c975
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:807:68
34: 0x5b8541c66f9b - tokio::runtime::context::scoped::Scoped<T>::set::hfd7dc621c1a86dd6
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/context/scoped.rs:40:9
35: 0x5b8541c3e469 - tokio::runtime::context::set_scheduler::{{closure}}::he0284573d5eb0ca5
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/context.rs:180:26
36: 0x5b8541c5c65a - std::thread::local::LocalKey<T>::try_with::h705fa3e9e86b8046
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/thread/local.rs:283:12
37: 0x5b8541c5bc2a - std::thread::local::LocalKey<T>::with::hcbecfc679dd67832
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/thread/local.rs:260:9
38: 0x5b8541c3e3dd - tokio::runtime::context::set_scheduler::hac0d58a5dc54ad36
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/context.rs:180:9
39: 0x5b8541c33430 - tokio::runtime::scheduler::current_thread::CoreGuard::enter::h1e18d6ebd2188d54
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:807:27
40: 0x5b8541c33723 - tokio::runtime::scheduler::current_thread::CoreGuard::block_on::hf8078cbf5b28f26c
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:716:19
41: 0x5b8541c30efd - tokio::runtime::scheduler::current_thread::CurrentThread::block_on::{{closure}}::ha66859ddb7d9bad0
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:196:28
42: 0x5b8541c2a527 - tokio::runtime::context::runtime::enter_runtime::hae321f8f5ba61d93
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/context/runtime.rs:65:16
43: 0x5b8541c30bd3 - tokio::runtime::scheduler::current_thread::CurrentThread::block_on::h14c83c76c10473e3
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/scheduler/current_thread/mod.rs:184:9
44: 0x5b8541c2ab10 - tokio::runtime::runtime::Runtime::block_on_inner::h28918626ddecdeee
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/runtime.rs:368:47
45: 0x5b8541c2aefe - tokio::runtime::runtime::Runtime::block_on::h751fbbf92aa61924
at /home/zack/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.41.1/src/runtime/runtime.rs:340:13
46: 0x5b8541c65e4c - bug::main::ha7253ccdcb8d6d35
at /home/zack/projects/bug/src/main.rs:30:5
47: 0x5b8541c25b4b - core::ops::function::FnOnce::call_once::h9f3bb0ebd6d37fd7
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/ops/function.rs:250:5
48: 0x5b8541c5cd7e - std::sys::backtrace::__rust_begin_short_backtrace::h0b49c9502cd6f287
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/sys/backtrace.rs:154:18
49: 0x5b8541c2a081 - std::rt::lang_start::{{closure}}::hc1d9acf0009135ce
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/rt.rs:164:18
50: 0x5b8541ddae40 - core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once::h08ecba131ab90ec4
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/core/src/ops/function.rs:284:13
51: 0x5b8541ddae40 - std::panicking::try::do_call::hf33a59fd8ce953f4
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:554:40
52: 0x5b8541ddae40 - std::panicking::try::h5005ce80ce949fd8
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:518:19
53: 0x5b8541ddae40 - std::panic::catch_unwind::hfbae19e2e2c5b7ed
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panic.rs:345:14
54: 0x5b8541ddae40 - std::rt::lang_start_internal::{{closure}}::ha0331c3690741813
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/rt.rs:143:48
55: 0x5b8541ddae40 - std::panicking::try::do_call::hcdcbdb616b4d0295
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:554:40
56: 0x5b8541ddae40 - std::panicking::try::h3f2f1725a07d2256
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panicking.rs:518:19
57: 0x5b8541ddae40 - std::panic::catch_unwind::h51869e04b56b2dc3
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/panic.rs:345:14
58: 0x5b8541ddae40 - std::rt::lang_start_internal::h4d90db0530245041
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/rt.rs:143:20
59: 0x5b8541c2a05a - std::rt::lang_start::h0c5b3abe1e928f3c
at /rustc/f6e511eec7342f59a25f7c0534f1dbea00d01b14/library/std/src/rt.rs:163:17
60: 0x5b8541c66d8e - main
61: 0x747cf2318e08 - <unknown>
62: 0x747cf2318ecc - __libc_start_main
63: 0x5b8541c255f5 - _start
64: 0x0 - <unknown>Additional information:
[zack@laptop bug]$ cat Cargo.toml
[package]
name = "bug"
version = "0.1.0"
edition = "2021"
[dependencies]
postgres-types = { version = "0.2.8", default-features = false, features = ["derive"] }
tokio = { version = "1.41.1", default-features = false, features = ["rt"] }
tokio-postgres = { version = "0.7.12", default-features = false, features = ["runtime"] }
[zack@laptop bug]$ rustc --version
rustc 1.82.0 (f6e511eec 2024-10-15)
[zack@laptop bug]$ postgres --version
postgres (PostgreSQL) 16.3
[zack@laptop bug]$ uname -a
Linux laptop 6.11.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Fri, 08 Nov 2024 17:57:56 +0000 x86_64 GNU/LinuxSome extra information. The ToSql macro works fine (i.e., I can INSERT a Fizz into buzz). FromSql works fine for Bar (i.e., SELECT (z).y FROM buzz; successfully grabs a Bar). The &[u8] that is passed to Fizz::from_sql is the following:
[0, 0, 0, 1, 0, 0, 74, 174, 0, 0, 0, 16, 0, 0, 0, 1, 0, 0, 0, 23, 0, 0, 0, 4, 0, 0, 0, 1].
OK, I looked at the code that is generated; and I believe I found the issue. Bar::from_sql ends up passing its own type to the contained type's from_sql (i.e., Foo::from_sql is passed the type for Bar instead of itself).
Generated code:
#[postgres(name = "bar")]
struct Bar(Foo);
impl<'a> postgres_types::FromSql<'a> for Bar {
fn from_sql(_type: &postgres_types::Type, buf: &'a [u8])
->
std::result::Result<Bar,
std::boxed::Box<dyn std::error::Error + std::marker::Sync +
std::marker::Send>> {
<Foo as postgres_types::FromSql>::from_sql(_type, buf).map(Bar)
}
fn accepts(type_: &postgres_types::Type) -> bool {
if <Foo as postgres_types::FromSql>::accepts(type_) { return true; }
if type_.name() != "bar" { return false; }
match *type_.kind() {
::postgres_types::Kind::Domain(ref type_) => {
<Foo as ::postgres_types::ToSql>::accepts(type_)
}
_ => false,
}
}
}from_sql should instead look similar to below:
fn from_sql(_type: &postgres_types::Type, buf: &'a [u8])
->
std::result::Result<Bar,
std::boxed::Box<dyn std::error::Error + std::marker::Sync +
std::marker::Send>> {
match *_type.kind() {
postgres_types::Kind::Domain(ref type_) => {
<Foo as postgres_types::FromSql>::from_sql(type_, buf).map(Bar)
}
ref bad => unreachable!("Bar::from_sql was passed a type whose kind was {bad:?}, but it must be passed a type whose kind is Kind::Domain"),
}
}When I make that fix, the code works; however it now breaks when Bar is fetched directly (e.g., SELECT (z).y FROM buzz;). I'm pretty sure the Type that is passed to FromSql::from_sql is supposed to be the same as the implementing type, so my "fix" seems correct. There appears to be another bug in addition to postgres_derive::fromsql::domain_body that calls FromSql::from_sql "specially" for DOMAIN types where it passes the contained type instead of the DOMAIN type when the "root" type is a DOMAIN presumably to work around this bug.
It makes me suspicious how FromSql::accepts is derived too. Why does it first redirect to the contained type and not verify the name matches unless the contained type's accept fails? Presumably it is due to the unnamed bug(s) that is/are calling FromSql::from_sql for DOMAINs by passing in the contained type. This also makes manual implementations very fragile.
I remember there being some funkiness around domains where postgres uses the underlying type directly in some cases instead of the domain type. The logic might just need to handle both cases?
Hm, I'd be interested to see such an example. While I realize most people should just derive FromSql and ToSql, it should be possible to manually implement them. This seems very fragile to expect manual implementations to somehow assume calling code will intentionally pass the wrong Type. I almost feel like the warning for ToSql::to_sql_checked should be applied for the entire traits (i.e., All implementations of these traits should be generated by the fromsql!()/tosql!() macros).
OK, I submitted a fix that allows DOMAINs to work when they both contain a composite type and are also not the "root" type. I tested the diff on my local example, and it works for Fizz and Bar.
Any update on this? Would really love to see it merged.
@ZakSingh, there is nothing left for me to do as it's up to @sfackler. A lot of code use this crate, so I understand the hesitancy to merge the PR even if there is a clear bug (read bug compatibility).
As far as what to do in the meantime, you can always manually implement the trait yourself as it's not that difficult to do. You can fork the repo with this merged and use it. You can avoid using "complex" types like DOMAIN and composite types—honestly that's what I do now after reading the code since there is clearly a (likely negligible) performance hit when not using "primitives", there is a larger possibility of other bugs since less common code paths are less tested, and both the database structures and application code will be more portable to other database systems. You can use another library if it fits your needs (e.g., sqlx may merge this PR which should be free from this kind of bug).