Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

postgres: sqlx prepare fails if shared_preload_libraries=pg_stat_statements #2622

Closed
mrl5 opened this issue Jul 16, 2023 · 4 comments
Closed
Labels

Comments

@mrl5
Copy link
Contributor

mrl5 commented Jul 16, 2023

duplicates #2587

Bug Description

since sqlx-cli version >=0.7.0 sqlx prepare fails if target database has pg_stat_statements in shared_preload_libraries

bug doesn't exists in =0.6.3

Minimal Reproduction

  1. init project
cargo init sqlx-test
cd sqlx-test
  1. setup db
    docker-compose.yml
version: '3.7'

services:
  db:
    image: postgres:15.3
    restart: unless-stopped
    volumes:
      - db_data:/var/lib/postgresql/data
    command: postgres -c shared_preload_libraries=pg_stat_statements
    ports:
      - 5432:5432
    environment:
      POSTGRES_PASSWORD: changeme
      POSTGRES_DB: test
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U postgres" ]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  db_data: null
  1. Cargo.toml
[package]
name = "sqlx-test"
version = "0.1.0"
edition = "2021"

[dependencies]
sqlx = { version = "0.7.1", features = [
    "macros",
    "postgres",
    "runtime-tokio-rustls",
] }
tokio = { version = "^1", features = ["full"] }
  1. src/main.rs
use sqlx::postgres::PgPoolOptions;

#[tokio::main]
async fn main() -> Result<(), sqlx::Error> {
    let database_url = std::env::var("DATABASE_URL")
        .map_err(|_| "DATABASE_URL env var is missing".to_string()).unwrap();

    let pool = PgPoolOptions::new()
        .max_connections(5)
        .connect(&database_url).await?;

    sqlx::query!("SELECT 1 as foo").fetch_one(&pool).await?;
    Ok(())
}
  1. installl sqlx-cli
cargo install --version 0.7.1 sqlx-cli
  1. run db
docker compose up db
  1. set DATABASE_URL
export DATABASE_URL="postgres://postgres:changeme@localhost:5432/test?sslmode=disable"
  1. run
cargo sqlx prepare
error: error occurred while decoding column 0: expected value at line 12 column 5
  --> src/main.rs:12:5
   |
12 |     sqlx::query!("SELECT 1 as foo").fetch_one(&pool).await?;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = 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)
  1. now change this in docker-compose.yml, stop database container and repeat steps 6 and 8
     restart: unless-stopped
     volumes:
       - db_data:/var/lib/postgresql/data
-    command: postgres -c shared_preload_libraries=pg_stat_statements
+    command: postgres -c shared_preload_libraries=
     ports:
       - 5432:5432
     environment:

Info

  • SQLx version: 0.7.1
  • SQLx features enabled: [REQUIRED]
  • Database server and version: Postgres 15.3
  • Operating system: linux
  • rustc --version: rustc 1.71.0 (8ede3aae2 2023-07-12)
@mrl5 mrl5 added the bug label Jul 16, 2023
@mrl5
Copy link
Contributor Author

mrl5 commented Jul 16, 2023

this is not a big deal really:

  • one can use SQLX_OFFLINE=true
  • and in dev env disable pg_stat_statements when running sqlx prepare

that being said I figured that it's worth reporting anyway

@abonander
Copy link
Collaborator

It appears that it's somehow changing the output of the EXPLAIN (VERBOSE, FORMAT JSON) <query> statement that the macros use to analyze the query. Can you post the output of that command?

@mrl5
Copy link
Contributor Author

mrl5 commented Jul 16, 2023

diff

       "Output": [
         "1"
       ]
-    },
-    "Query Identifier": 1147616880456321400
+    }
   }
 ]

pg_stat_statements enabled

SHOW shared_preload_libraries;
 shared_preload_libraries 
--------------------------
 pg_stat_statements
(1 row)
EXPLAIN (VERBOSE, FORMAT JSON) SELECT 1 as foo;
                 QUERY PLAN                  
---------------------------------------------
 [                                          +
   {                                        +
     "Plan": {                              +
       "Node Type": "Result",               +
       "Parallel Aware": false,             +
       "Async Capable": false,              +
       "Startup Cost": 0.00,                +
       "Total Cost": 0.01,                  +
       "Plan Rows": 1,                      +
       "Plan Width": 4,                     +
       "Output": ["1"]                      +
     },                                     +
     "Query Identifier": 1147616880456321454+
   }                                        +
 ]
(1 row)

pg_stat_statements disabled

SHOW shared_preload_libraries;
 shared_preload_libraries 
--------------------------
 
(1 row)
EXPLAIN (VERBOSE, FORMAT JSON) SELECT 1 as foo;
           QUERY PLAN           
--------------------------------
 [                             +
   {                           +
     "Plan": {                 +
       "Node Type": "Result",  +
       "Parallel Aware": false,+
       "Async Capable": false, +
       "Startup Cost": 0.00,   +
       "Total Cost": 0.01,     +
       "Plan Rows": 1,         +
       "Plan Width": 4,        +
       "Output": ["1"]         +
     }                         +
   }                           +
 ]
(1 row)

@abonander
Copy link
Collaborator

Yeah, the parsing doesn't know what to do with thatbQuery Identifier field: https://github.com/launchbadge/sqlx/blob/main/sqlx-postgres/src/connection/describe.rs#L495

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants