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

sqlx doesn't handle array_agg and composite type correctly #1547

Closed
winston0410 opened this issue Nov 17, 2021 · 2 comments
Closed

sqlx doesn't handle array_agg and composite type correctly #1547

winston0410 opened this issue Nov 17, 2021 · 2 comments

Comments

@winston0410
Copy link

I am using postgres, and I am making a query like this:

use chrono::{DateTime, Utc};
use ormx::{Patch, Table};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, Type};

#[derive(Debug, Table, Clone, Serialize, Type, FromRow)]
#[ormx(table = "tags", id = id, insertable, deletable)]
pub struct Tag {
    #[ormx(default)]
    pub id: i32,
    pub name: String,
    pub updated_at: DateTime<Utc>,
}

#[derive(Debug, Clone, Serialize, FromRow)]
pub struct TaskEntity {
    pub tags: Option<Vec<Tag>>,
}

impl TaskEntity {
    pub async fn all_by_gid(pool: &Pool<Postgres>, gid: u32) -> Result<Vec<TaskEntity>, Error> {
        sqlx::query_as!(TaskEntity, r#"
        select array_agg(tags.*) as "tags: Vec<Tag>" 
        from tasks_tags
        join tags on tasks_tags.tag_id = tags.id
        "#).fetch_all(pool).await
    }
}

And then I got an error like this:

thread 'actix-rt|system:0|arbiter:0' panicked at 'internal error: entered unreachable code: (bug) use of unresolved type declaration [oid=22100]', /home/hugosum/.cache/cargo/registry/src/github.com-1ecc6299db9ec823/sqlx-core-0.5.9/src/postgres/type_info.rs:746:17

I have then tried to change the type to String like this:

#[derive(Debug, Clone, Serialize, FromRow)]
pub struct TaskEntity {
    pub tags: Option<Vec<String>>,
}

impl TaskEntity {
    pub async fn all_by_gid(pool: &Pool<Postgres>, gid: u32) -> Result<Vec<TaskEntity>, Error> {
        sqlx::query_as!(TaskEntity, r#"
        select array_agg(tags.*) as "tags: Vec<String>" 
        from tasks_tags
        join tags on tasks_tags.tag_id = tags.id
        "#).fetch_all(pool).await
    }
}

And got this error this time:

ColumnDecode { index: "0", source: Utf8Error { valid_up_to: 33, error_len: Some(1) } }

And it would work if I just get a single field with String:

#[derive(Debug, Clone, Serialize, FromRow)]
pub struct TaskEntity {
    pub tags: Option<Vec<String>>,
}

impl TaskEntity {
    pub async fn all_by_gid(pool: &Pool<Postgres>, gid: u32) -> Result<Vec<TaskEntity>, Error> {
        sqlx::query_as!(TaskEntity, r#"
        select array_agg(tags.name) as "tags: Vec<String>" 
        from tasks_tags
        join tags on tasks_tags.tag_id = tags.id
        "#).fetch_all(pool).await
    }
}

So I suspect the issue is with the composite type created by array_agg. Is there any workaround right now?

database schema as a reference:

CREATE TYPE status AS ENUM ('completed', 'incomplete');

drop table if exists tasks;
create table if not exists tasks(
    id int GENERATED ALWAYS AS IDENTITY,
    name varchar(256) not null,
    -- created_at timestamptz not null,
    updated_at timestamptz not null,
    status status not null,
    primary key(id)
);

drop table if exists tags;
create table if not exists tags(
    id int GENERATED ALWAYS AS IDENTITY,
    name varchar(256) not null,
    updated_at timestamptz not null,
    primary key(id)
);

drop table if exists tasks_tags;
create table if not exists tasks_tags(
    id int GENERATED ALWAYS AS IDENTITY,
    task_id int not null,
    tag_id int not null,
    primary key(id),
    foreign key(task_id) references tasks ON DELETE CASCADE,
    foreign key(tag_id) references tags ON DELETE CASCADE
);
@abonander
Copy link
Collaborator

I believe this is a duplicate of #1477

@belyakov-am
Copy link

Fixed here #1477

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

No branches or pull requests

3 participants