diff --git a/sqlx-postgres/src/type_checking.rs b/sqlx-postgres/src/type_checking.rs index 95f5f3d40a..e41e59e5cc 100644 --- a/sqlx-postgres/src/type_checking.rs +++ b/sqlx-postgres/src/type_checking.rs @@ -211,9 +211,6 @@ impl_type_checking!( // Full text search sqlx::postgres::types::TsVector, Vec | &[sqlx::postgres::types::TsVector], - - sqlx::postgres::types::TsQuery, - Vec | &[sqlx::postgres::types::TsQuery], }, ParamChecking::Strong, feature-types: info => info.__type_feature_gate(), diff --git a/sqlx-postgres/src/types/mod.rs b/sqlx-postgres/src/types/mod.rs index dac50d8b09..4476c4eb05 100644 --- a/sqlx-postgres/src/types/mod.rs +++ b/sqlx-postgres/src/types/mod.rs @@ -234,7 +234,6 @@ mod mac_address; #[cfg(feature = "bit-vec")] mod bit_vec; -mod ts_query; mod ts_vector; pub use array::PgHasArrayType; @@ -254,7 +253,6 @@ pub use range::PgRange; #[cfg(any(feature = "chrono", feature = "time"))] pub use time_tz::PgTimeTz; -pub use ts_query::TsQuery; pub use ts_vector::TsVector; // used in derive(Type) for `struct` diff --git a/sqlx-postgres/src/types/ts_query.rs b/sqlx-postgres/src/types/ts_query.rs deleted file mode 100644 index 4364f81902..0000000000 --- a/sqlx-postgres/src/types/ts_query.rs +++ /dev/null @@ -1,213 +0,0 @@ -use crate::{PgArgumentBuffer, PgHasArrayType, PgTypeInfo, PgValueFormat, PgValueRef, Postgres}; -use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt}; -use sqlx_core::decode::Decode; -use sqlx_core::encode::{Encode, IsNull}; -use sqlx_core::error::BoxDynError; -use sqlx_core::types::Type; -use std::io::{BufRead, Cursor, Write}; - -#[derive(Clone, Debug)] -pub struct TsQuery { - entries: Vec, -} - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum Operators { - Not = 1, - And = 2, - Or = 3, - Phrase = 4, -} - -impl Into for Operators { - fn into(self) -> u8 { - match self { - Self::Not => 1, - Self::And => 2, - Self::Or => 3, - Self::Phrase => 4, - } - } -} - -impl TryFrom for Operators { - type Error = BoxDynError; - - fn try_from(value: u8) -> Result { - match value { - 1 => Ok(Operators::Not), - 2 => Ok(Operators::And), - 3 => Ok(Operators::Or), - 4 => Ok(Operators::Phrase), - _ => Err(BoxDynError::from("Invalid operator")), - } - } -} - -#[derive(Clone, Debug)] -pub struct Operator { - operator: Operators, - distance: Option, -} - -#[derive(Clone, Debug)] -pub struct Value { - weight: u8, - text: String, - prefix: u8, -} - -#[derive(Clone, Debug)] -pub enum Entry { - Operator(Operator), - Value(Value), -} - -#[derive(Copy, Clone, Eq, PartialEq, Debug)] -pub enum EntryType { - Value = 1, - Operator = 2, -} - -impl Into for EntryType { - fn into(self) -> u8 { - match self { - EntryType::Value => 1, - EntryType::Operator => 2, - } - } -} - -impl TryFrom for EntryType { - type Error = BoxDynError; - - fn try_from(value: u8) -> Result { - match value { - 1 => Ok(EntryType::Value), - 2 => Ok(EntryType::Operator), - _ => Err(BoxDynError::from("Invalid type")), - } - } -} - -impl TryFrom<&[u8]> for TsQuery { - type Error = BoxDynError; - - /// Decode binary data into [`TsQuery`] based on the binary data format defined in - /// https://github.com/postgres/postgres/blob/252dcb32397f64a5e1ceac05b29a271ab19aa960/src/backend/utils/adt/tsquery.c#L1174 - fn try_from(bytes: &[u8]) -> Result { - let mut reader = Cursor::new(bytes); - - let count = reader.read_u32::()?; - - let mut entries = Vec::::with_capacity(count as usize); - - for _ in 0..count { - let entry_type: EntryType = reader.read_u8()?.try_into()?; - - match entry_type { - EntryType::Value => { - let weight = reader.read_u8()?; - let mut text = String::new().into_bytes(); - - reader.read_until(b'\0', &mut text)?; - - let text = String::from_utf8(text)?; - let prefix = reader.read_u8()?; - - entries.push(Entry::Value(Value { - weight, - text, - prefix, - })); - } - EntryType::Operator => { - let operator: Operators = reader.read_u8()?.try_into()?; - let distance = if let Operators::Phrase = operator { - Some(reader.read_u16::()?) - } else { - None - }; - - entries.push(Entry::Operator(Operator { operator, distance })); - } - } - } - - Ok(TsQuery { entries }) - } -} - -impl TryInto> for &TsQuery { - type Error = BoxDynError; - - fn try_into(self) -> Result, Self::Error> { - let buf: &mut Vec = &mut vec![]; - - buf.write_u32::(u32::try_from(self.entries.len())?)?; - - for entry in &self.entries { - match entry { - Entry::Operator(operator) => { - buf.write_u8(EntryType::Operator.into())?; - buf.write_u8(operator.operator.into())?; - - if let Some(distance) = operator.distance { - buf.write_u16::(distance)?; - } - } - Entry::Value(value) => { - buf.write_u8(EntryType::Value.into())?; - buf.write_u8(value.weight)?; - - buf.write(value.text.as_bytes())?; - buf.write(&[b'\0'])?; - - buf.write_u8(value.prefix)?; - } - } - } - - buf.flush()?; - - Ok(buf.to_vec()) - } -} - -impl Type for TsQuery { - fn type_info() -> PgTypeInfo { - PgTypeInfo::TS_QUERY - } -} - -impl PgHasArrayType for TsQuery { - fn array_type_info() -> PgTypeInfo { - PgTypeInfo::TS_QUERY_ARRAY - } -} - -impl Encode<'_, Postgres> for TsQuery { - fn encode_by_ref(&self, buf: &mut PgArgumentBuffer) -> IsNull { - if let Ok(encoded_ts_query) = <&TsQuery as TryInto>>::try_into(self) { - buf.extend_from_slice(encoded_ts_query.as_slice()); - - IsNull::No - } else { - IsNull::Yes - } - } -} - -impl Decode<'_, Postgres> for TsQuery { - fn decode(value: PgValueRef<'_>) -> Result { - match value.format() { - PgValueFormat::Binary => { - let bytes = value.as_bytes()?; - let ts_query = bytes.try_into()?; - - Ok(ts_query) - } - _ => unimplemented!(), - } - } -}