diff --git a/src/ast/data_type.rs b/src/ast/data_type.rs index 3a4958c9f..ef04b7e4b 100644 --- a/src/ast/data_type.rs +++ b/src/ast/data_type.rs @@ -446,6 +446,14 @@ pub enum DataType { /// /// [PostgreSQL]: https://www.postgresql.org/docs/9.5/functions-geometry.html GeometricType(GeometricTypeKind), + /// PostgreSQL text search vectors, see [PostgreSQL]. + /// + /// [PostgreSQL]: https://www.postgresql.org/docs/17/datatype-textsearch.html + TsVector, + /// PostgreSQL text search query, see [PostgreSQL]. + /// + /// [PostgreSQL]: https://www.postgresql.org/docs/17/datatype-textsearch.html + TsQuery, } impl fmt::Display for DataType { @@ -738,6 +746,8 @@ impl fmt::Display for DataType { write!(f, "{} TABLE ({})", name, display_comma_separated(columns)) } DataType::GeometricType(kind) => write!(f, "{}", kind), + DataType::TsVector => write!(f, "TSVECTOR"), + DataType::TsQuery => write!(f, "TSQUERY"), } } } diff --git a/src/keywords.rs b/src/keywords.rs index f5c5e567e..f1257b10f 100644 --- a/src/keywords.rs +++ b/src/keywords.rs @@ -934,6 +934,8 @@ define_keywords!( TRY, TRY_CAST, TRY_CONVERT, + TSQUERY, + TSVECTOR, TUPLE, TYPE, UBIGINT, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 73cc3e0ed..d2817b077 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -9913,6 +9913,12 @@ impl<'a> Parser<'a> { Ok(DataType::Unsigned) } } + Keyword::TSVECTOR if dialect_is!(dialect is PostgreSqlDialect | GenericDialect) => { + Ok(DataType::TsVector) + } + Keyword::TSQUERY if dialect_is!(dialect is PostgreSqlDialect | GenericDialect) => { + Ok(DataType::TsQuery) + } _ => { self.prev_token(); let type_name = self.parse_object_name(false)?; diff --git a/tests/sqlparser_postgres.rs b/tests/sqlparser_postgres.rs index 6f0ba9c69..38a414a36 100644 --- a/tests/sqlparser_postgres.rs +++ b/tests/sqlparser_postgres.rs @@ -6201,3 +6201,49 @@ fn parse_alter_table_replica_identity() { _ => unreachable!(), } } + +#[test] +fn parse_tsvector_datatype() { + match pg_and_generic().verified_stmt("CREATE TABLE foo (x TSVECTOR)") { + Statement::CreateTable(CreateTable { columns, .. }) => { + assert_eq!( + columns, + vec![ColumnDef { + name: "x".into(), + data_type: DataType::TsVector, + options: vec![], + }] + ); + } + _ => unreachable!(), + } +} + +#[test] +fn parse_tsquery_datatype() { + match pg_and_generic().verified_stmt("CREATE TABLE foo (x TSQUERY)") { + Statement::CreateTable(CreateTable { columns, .. }) => { + assert_eq!( + columns, + vec![ColumnDef { + name: "x".into(), + data_type: DataType::TsQuery, + options: vec![], + }] + ); + } + _ => unreachable!(), + } +} + +#[test] +fn parse_to_tsvector_function() { + let sql = "SELECT to_tsvector('english', 'foo bar baz')"; + pg_and_generic().verified_only_select(sql); +} + +#[test] +fn parse_to_tsquery_function() { + let sql = "SELECT to_tsquery('Fat:ab & Cats')"; + pg_and_generic().verified_only_select(sql); +}