diff --git a/Cargo.toml b/Cargo.toml index 4d86574..b74fd37 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,6 +47,7 @@ default = ["mysql", "postgres", "sqlite", "discovery", "writer", "probe"] debug-print = ["log"] mysql = ["sea-query/backend-mysql"] postgres = ["sea-query/backend-postgres"] +postgres-vector = ["sea-query/postgres-vector", "sea-query-binder/postgres-vector"] sqlite = ["sea-query/backend-sqlite"] def = [] discovery = ["futures", "parser"] diff --git a/src/postgres/def/types.rs b/src/postgres/def/types.rs index df7d0fe..9f2688e 100644 --- a/src/postgres/def/types.rs +++ b/src/postgres/def/types.rs @@ -116,6 +116,10 @@ pub enum Type { /// Variable-length multidimensional array Array(ArrayDef), + #[cfg(feature = "postgres-vector")] + /// The postgres vector type introduced by the vector extension. + Vector(VectorDef), + // TODO: // /// The structure of a row or record; a list of field names and types // Composite, @@ -268,6 +272,14 @@ pub struct ArrayDef { pub col_type: Option>, } +#[cfg(feature = "postgres-vector")] +/// Defines an enum for the PostgreSQL module +#[derive(Clone, Debug, PartialEq, Default)] +#[cfg_attr(feature = "with-serde", derive(Serialize, Deserialize))] +pub struct VectorDef { + pub length: Option, +} + impl Type { pub fn has_numeric_attr(&self) -> bool { matches!(self, Type::Numeric(_) | Type::Decimal(_)) @@ -302,4 +314,9 @@ impl Type { pub fn has_array_attr(&self) -> bool { matches!(self, Type::Array(_)) } + + #[cfg(feature = "postgres-vector")] + pub fn has_vector_attr(&self) -> bool { + matches!(self, Type::Vector(_)) + } } diff --git a/src/postgres/parser/column.rs b/src/postgres/parser/column.rs index d5cf7c2..62a9595 100644 --- a/src/postgres/parser/column.rs +++ b/src/postgres/parser/column.rs @@ -57,6 +57,10 @@ pub fn parse_column_type(result: &ColumnQueryResult, enums: &EnumVariantMap) -> if ctype.has_array_attr() { ctype = parse_array_attributes(result.udt_name_regtype.as_deref(), ctype, enums); } + #[cfg(feature = "postgres-vector")] + if ctype.has_vector_attr() { + ctype = parse_vector_attributes(result.character_maximum_length, ctype); + } ctype } @@ -240,3 +244,24 @@ pub fn parse_array_attributes( ctype } + +#[cfg(feature = "postgres-vector")] +pub fn parse_vector_attributes( + character_maximum_length: Option, + mut ctype: ColumnType, +) -> ColumnType { + match ctype { + Type::Vector(ref mut attr) => { + attr.length = match character_maximum_length { + None => None, + Some(num) => match u32::try_from(num) { + Ok(num) => Some(num), + Err(_) => None, + }, + }; + } + _ => panic!("parse_vector_attributes(_) received a type that does not have StringAttr"), + }; + + ctype +} diff --git a/src/postgres/writer/column.rs b/src/postgres/writer/column.rs index 43072fe..7582f60 100644 --- a/src/postgres/writer/column.rs +++ b/src/postgres/writer/column.rs @@ -121,6 +121,11 @@ impl ColumnInfo { Type::TsTzRange => ColumnType::Custom(Alias::new("tstzrange").into_iden()), Type::DateRange => ColumnType::Custom(Alias::new("daterange").into_iden()), Type::PgLsn => ColumnType::Custom(Alias::new("pg_lsn").into_iden()), + #[cfg(feature = "postgres-vector")] + Type::Vector(vector_attr) => match vector_attr.length { + Some(length) => ColumnType::Vector(Some(length)), + None => ColumnType::Vector(None), + }, Type::Unknown(s) => ColumnType::Custom(Alias::new(s).into_iden()), Type::Enum(enum_def) => { let name = Alias::new(&enum_def.typename).into_iden();