Skip to content

Commit

Permalink
Fix PostgreSQL enum arrays and case-sensitive types (#108)
Browse files Browse the repository at this point in the history
* Fix PostgreSQL enum arrays

* Remove redundant clones

* Put back `udt_name_regtype` and refactoring

* Refactoring

* Fixup

* Refactoring

* `to_regtype` instead of `::regtype` to avoid panic

* CONCAT-fix for ::regtype and minimal test case

* cleanup

* cleanup

---------

Co-authored-by: Billy Chan <[email protected]>
  • Loading branch information
niklaskorz and billy1624 authored Jul 21, 2023
1 parent 4588776 commit 50f2383
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 10 deletions.
17 changes: 10 additions & 7 deletions src/postgres/parser/column.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,13 +213,16 @@ pub fn parse_array_attributes(
def.col_type = match udt_name_regtype {
None => panic!("parse_array_attributes(_) received an empty udt_name_regtype"),
Some(typename) => {
let typename = typename.replacen("[]", "", 1);
let is_enum = enums.contains_key(&typename);
Some(RcOrArc::new(Type::from_str(
&typename,
Some(&typename),
is_enum,
)))
let typename = &typename.replacen('"', "", 2).replacen("[]", "", 1);
let arr_col_type = if let Some(variants) = enums.get(typename) {
Type::Enum(EnumDef {
typename: typename.to_string(),
values: variants.clone(),
})
} else {
Type::from_str(typename, Some(typename), false)
};
Some(RcOrArc::new(arr_col_type))
}
};
}
Expand Down
13 changes: 10 additions & 3 deletions src/postgres/query/column.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::{InformationSchema, SchemaQueryBuilder};
use crate::sqlx_types::postgres::PgRow;
use sea_query::{Alias, BinOper, Expr, Iden, Query, SeaRc, SelectStatement};
use sea_query::{BinOper, Expr, Iden, Query, SeaRc, SelectStatement};

#[derive(Debug, sea_query::Iden)]
/// Ref: https://www.postgresql.org/docs/13/infoschema-columns.html
Expand Down Expand Up @@ -94,8 +94,10 @@ impl SchemaQueryBuilder {
ColumnsField::UdtName,
])
.expr(
Expr::expr(Expr::cust("udt_name::regtype").cast_as(Alias::new("text")))
.binary(BinOper::As, Expr::col(Alias::new("udt_name_regtype"))),
// The double quotes are required to correctly handle user types containing
// upper case letters.
Expr::expr(Expr::cust("CONCAT('\"', udt_name, '\"')::regtype").cast_as(Text))
.binary(BinOper::As, Expr::col(UdtNameRegtype)),
)
.from((InformationSchema::Schema, InformationSchema::Columns))
.and_where(Expr::col(ColumnsField::TableSchema).eq(schema.to_string()))
Expand Down Expand Up @@ -135,3 +137,8 @@ impl From<&PgRow> for ColumnQueryResult {
Self::default()
}
}

#[derive(Iden)]
struct Text;
#[derive(Iden)]
struct UdtNameRegtype;

0 comments on commit 50f2383

Please sign in to comment.