Usage with Postgres uint extension
Currently sqlx 0.4.0-beta.1 doesn't support the Postgres uint extension.
What can I do to have my app support the unsigned types from the extension apart from switching to signed types in my database?
If I need to contribute code directly to sqlx, where do I start?
Here's an example of code that returns an error:
-- Assuming the uint extension is installed:
CREATE EXTENSION uint;
CREATE TABLE streamers (
username_id text CONSTRAINT username PRIMARY KEY,
video_id text REFERENCES video_ids (id)
);
CREATE TABLE video_ids (
id text PRIMARY KEY,
people_playing uint8
);
INSERT INTO video_ids (id)
VALUES ('8iEukLpRyDU');
use sqlx::postgres::PgPoolOptions;
use anyhow::Result;
#[async_std::main]
async fn main() -> Result<()> {
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(&"postgres://username@localhost/db_name").await?;
let row: (u64,) = sqlx::query_as("SELECT people_playing FROM video_ids")
.fetch_one(&pool).await?;
println!("{}", row.0);
Ok(())
}
And the error:
Error: error returned from database: no binary output function available for type uint8
no binary output function available for type uint8
that's not an error from SQLx, does that query work in psql?
It actually does work, both in Emacs' sql-mode (which I assume wraps psql) and in Rust after working on my app some more.
It must've been an error on my side so I'm closing this.
Sorry for the spam, but I think I was wrong about there being no problem.
Running this through the Emacs pgsql interface while connected to my database:
CREATE EXTENSION uint;
CREATE TABLE video_ids (
id varchar(11) CONSTRAINT id PRIMARY KEY,
people_playing uint8 DEFAULT 0 NOT NULL
);
CREATE TABLE users (
username text CONSTRAINT username PRIMARY KEY,
video_id varchar(11) REFERENCES video_ids (id) NOT NULL,
progress_seconds uint8 DEFAULT 0 NOT NULL
);
And then trying to compile this code:
use anyhow::Result;
use sqlx::postgres::PgPoolOptions;
use std::env;
#[async_std::main]
async fn main() -> Result<()> {
dotenv::dotenv()?;
let pool = PgPoolOptions::new()
.max_connections(5)
.connect(&env::var("DATABASE_URL")?)
.await?;
sqlx::query!(
r#"
UPDATE users
SET progress_seconds = $1
WHERE username = $2
"#,
32,
"ohmree"
)
.execute(&pool)
.await?;
Ok(())
}
Results in the error error: unsupported type uint8 for param #1.
If I change 32 to 32_u64 compilation fails with the same error.
If it matters I installed pguint from the AUR, the non-git version.
I wonder what the best way for implementing support for this extension is? https://github.com/rksm/sqlx/commit/0d140dd00a01b11d1dba8f87320706d300b38147 is an approach but it hard codes the type ids for the extension types as returned by select oid, typarray from pg_type where typname = 'uint8'. Those change, however, with each CREATE EXTENSION. Is there a better approach?
I've taken a crack at this, and it seems to work in my limited use case. JohnPeel/sqlx:pguint
It did however require some changes to pguint. I pulled in one of (the three) PRs for send & recv implementations on the uint types. JohnPeel/pguint:binary