launchbadge / sqlx

🧰 The Rust SQL Toolkit. An async, pure Rust SQL crate featuring compile-time checked queries without a DSL. Supports PostgreSQL, MySQL, and SQLite.
Apache License 2.0
13.15k stars 1.24k forks source link

optional sqlx feature `json` required for type JSONB of column/param X #3316

Closed jay3332 closed 2 months ago

jay3332 commented 3 months ago

Bug Description

Compiling my project on using sqlx from latest GitHub commit gives me an error akin to:

$ cargo check --all-features
error: optional sqlx feature `json` required for type JSONB of column #6 ("embeds")
   --> src/db/channel.rs:340:27
    |
340 |           let mut message = sqlx::query!(
    |  ___________________________^
341 | |             r#"SELECT
342 | |                 messages.*,
343 | |                 embeds AS "embeds_ser: sqlx::types::Json<Vec<Embed>>"
...   |
351 | |             channel_id as i64,
352 | |         )
    | |_________^
    |
    = note: this error originates in the macro `$crate::sqlx_macros::expand_query` which comes from the expansion of the macro `sqlx::query` (in Nightly builds, run with -Z macro-backtrace for more info)

My Cargo.toml:

[dependencies.sqlx]
git = "https://github.com/launchbadge/sqlx.git"
version = "0.8.0-alpha.0"
features = ["postgres", "macros", "runtime-tokio-rustls", "chrono", "json", "uuid"]
optional = true

(as seen, i have the json feature enabled)

This occurs is all places where JSONB is used

Minimal Reproduction

Use the latest commit of sqlx, enabling the json feature, then write a query using the sqlx::query! macro that uses JSONB

Info

Notes

Using the following patch fixes this error:

git = "https://github.com/benluelo/sqlx.git"
branch = "fix-encode-decode-derives"
abonander commented 3 months ago

Why not open a PR?

jay3332 commented 3 months ago

Why not open a PR?

The patch was taken from an old PR by another author that was merged that solved an unrelated issue. This PR was created before a commit (not to my knowledge) that led to the referenced error (thus this breaking commit was not in the PR branch) but merged after this commit was pushed.

CommanderStorm commented 2 months ago

Okay.. so that seems somewhat git bisect-able As said by you, https://github.com/launchbadge/sqlx/pull/2940 is unrelated. I have included it in the bisect table below anyways for completeness.

Date Commit issue(s)^1 note
31.Nov 31d402b469dde449eecca8af02447b9f8dd8dca8 lifetime
03.Mar 791a7f5417ca46859ababd97ee0d52c0356f4024 lifetime
14.Mar 8f926e590cce1fb3a0d4120f215c771ddd88a084 lifetime
14.Mar e0a1f1633c115bb5653fc7bd54b233c677546b95 lifetime
14.Mar 1f6642cafa98a2ae8cc2c407d85fcad17564bf01 lifetime
30.Mar 1c7b3d0751cdca5a08fbfa7f24c985fc3774cf11 lifetime 1 before #2970
30.Mar 02c68a46c7c64b03b2a4eb7375041e0ca86d2fe5 JSON + lifetime #2970
31.May 240b4fffd319b20c872fa4c5f05fa17c455db6f5 JSON + lifetime 1 before #2940
31.May 1ce0e760deb8ad70ed17931a9981377ae42855fe JSON #2940
  - `JSON` => optional sqlx feature `json` required for type JSONB
  - `lifetime` => lifetime may not live long enough
CommanderStorm commented 2 months ago

(very much partially) debugging this:

Here it goes into my code as above does not have a reproducible example attached ^^

My code is this. I have included just the relevant parts, and it is not fully minimal. If this turns out to be a problem, I will contribute a minimal example

```sql CREATE TABLE en ( key TEXT UNIQUE PRIMARY KEY NOT NULL, data TEXT NOT NULL, ); alter table en alter column data type jsonb using data::jsonb; ``` ```rust let key = "1"; let result = sqlx::query_scalar!("SELECT data FROM en WHERE key = $1", key) .fetch_optional(&pool) .await; ```

The macro expands to:

I am somewhat lost what happens in that macros' type_info or compatible calls don't end up matching..

https://github.com/launchbadge/sqlx/blob/3bec3f0f0c0ae979679517a95279d71c8dea5717/sqlx-postgres/src/types/json.rs#L17-L25

So to me it seems like param_ty is not correct. The probelm is that param_ty is JSONB (the Display implementation of PgTypeInfo::JSONB) as by error message. type_info() returns PgTypeInfo::JSONB

CommanderStorm commented 2 months ago

expanding the impl_type_checking macro just once makes also does not yield anything wrong I can see

#[cfg(feature = "json")]
_   if <sqlx::types::JsonValue as sqlx_core::types::Type<Postgres>>::type_info() == *info => Some(::sqlx_core::select_input_type!( sqlx::types::JsonValue )),
#[cfg(feature = "json")]
_   if <sqlx::types::JsonValue as sqlx_core::types::Type<Postgres>>::compatible(info) => Some(select_input_type!( sqlx::types::JsonValue )),
abonander commented 2 months ago

@CommanderStorm is it fixed if you add sqlx-postgres?/json here: https://github.com/launchbadge/sqlx/blob/main/sqlx-macros-core/Cargo.toml#L31