diff --git a/libs/user-facing-errors/src/query_engine/mod.rs b/libs/user-facing-errors/src/query_engine/mod.rs index 804ab2406533..a30b33210f3d 100644 --- a/libs/user-facing-errors/src/query_engine/mod.rs +++ b/libs/user-facing-errors/src/query_engine/mod.rs @@ -282,9 +282,9 @@ pub struct QueryParameterLimitExceeded { #[derive(Debug, UserFacingError, Serialize)] #[user_facing( code = "P2030", - message = "Cannot find a fulltext index to use for the search, try adding a @@fulltext([Fields...]) to your schema" + message = "Cannot find a fulltext index to use for the native search, try adding a @@fulltext([Fields...]) to your schema" )] -pub struct MissingFullTextSearchIndex {} +pub struct MissingNativeFullTextSearchIndex {} #[derive(Debug, UserFacingError, Serialize)] #[user_facing( diff --git a/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs b/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs index 69a1f3b6e05f..e1dc09e4b6fd 100644 --- a/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs +++ b/psl/psl-core/src/builtin_connectors/mysql_datamodel_connector.rs @@ -47,8 +47,8 @@ pub const CAPABILITIES: ConnectorCapabilities = enumflags2::make_bitflags!(Conne AdvancedJsonNullability | IndexColumnLengthPrefixing | FullTextIndex | - FullTextSearch | - FullTextSearchWithIndex | + NativeFullTextSearch | + NativeFullTextSearchWithIndex | MultipleFullTextAttributesPerModel | ImplicitManyToManyRelation | DecimalType | diff --git a/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector.rs b/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector.rs index 65a0d929995f..bc41d1635680 100644 --- a/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector.rs +++ b/psl/psl-core/src/builtin_connectors/postgres_datamodel_connector.rs @@ -39,8 +39,8 @@ pub const CAPABILITIES: ConnectorCapabilities = enumflags2::make_bitflags!(Conne CreateSkipDuplicates | Enums | EnumArrayPush | - FullTextSearch | - FullTextSearchWithoutIndex | + NativeFullTextSearch | + NativeFullTextSearchWithoutIndex | InsensitiveFilters | Json | JsonFiltering | diff --git a/psl/psl-core/src/common/preview_features.rs b/psl/psl-core/src/common/preview_features.rs index 36a64ad2af0e..1584c0e42dc0 100644 --- a/psl/psl-core/src/common/preview_features.rs +++ b/psl/psl-core/src/common/preview_features.rs @@ -53,6 +53,7 @@ features!( FilterJson, FullTextIndex, FullTextSearch, + NativeFullTextSearchPostgres, GroupBy, ImprovedQueryRaw, InteractiveTransactions, @@ -90,7 +91,6 @@ pub const ALL_PREVIEW_FEATURES: FeatureMap = FeatureMap { active: enumflags2::make_bitflags!(PreviewFeature::{ Deno | DriverAdapters - | FullTextSearch | Metrics | MultiSchema | NativeDistinct @@ -117,6 +117,7 @@ pub const ALL_PREVIEW_FEATURES: FeatureMap = FeatureMap { | FilteredRelationCount | FilterJson | FullTextIndex + | FullTextSearch | GroupBy | ImprovedQueryRaw | InteractiveTransactions @@ -136,7 +137,7 @@ pub const ALL_PREVIEW_FEATURES: FeatureMap = FeatureMap { | TransactionApi | UncheckedScalarInputs }), - hidden: enumflags2::make_bitflags!(PreviewFeature::{ReactNative | TypedSql}), + hidden: enumflags2::make_bitflags!(PreviewFeature::{ReactNative | TypedSql | NativeFullTextSearchPostgres}), }; #[derive(Debug)] diff --git a/psl/psl-core/src/datamodel_connector/capabilities.rs b/psl/psl-core/src/datamodel_connector/capabilities.rs index cf3f36eeea13..49c8fa54f0b9 100644 --- a/psl/psl-core/src/datamodel_connector/capabilities.rs +++ b/psl/psl-core/src/datamodel_connector/capabilities.rs @@ -87,9 +87,9 @@ capabilities!( AnyId, // Any (or combination of) uniques and not only id fields can constitute an id for a model. SqlQueryRaw, MongoDbQueryRaw, - FullTextSearch, - FullTextSearchWithoutIndex, - FullTextSearchWithIndex, + NativeFullTextSearch, + NativeFullTextSearchWithoutIndex, + NativeFullTextSearchWithIndex, AdvancedJsonNullability, // Connector distinguishes between their null type and JSON null. UndefinedType, // Connector distinguishes `null` and `undefined` DecimalType, // Connector supports Prisma Decimal type. diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/chunking.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/chunking.rs index 025915703852..64181e80a270 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/chunking.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/chunking.rs @@ -216,7 +216,7 @@ mod chunking { Ok(()) } - #[connector_test(capabilities(FullTextSearchWithoutIndex), exclude(MongoDb))] + #[connector_test(capabilities(NativeFullTextSearchWithoutIndex), exclude(MongoDb))] async fn order_by_relevance_should_fail(runner: Runner) -> TestResult<()> { create_test_data(&runner).await?; diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/search_filter.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/search_filter.rs index 218ecb7eb877..b8fceb657dad 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/search_filter.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/filters/search_filter.rs @@ -130,7 +130,7 @@ async fn create_row(runner: &Runner, data: &str) -> TestResult<()> { Ok(()) } -#[test_suite(schema(schema), capabilities(FullTextSearchWithoutIndex))] +#[test_suite(schema(schema), capabilities(NativeFullTextSearchWithoutIndex))] mod search_filter_without_index { use indoc::indoc; @@ -178,7 +178,7 @@ mod search_filter_without_index { } } -#[test_suite(schema(schema), capabilities(FullTextSearchWithIndex))] +#[test_suite(schema(schema), capabilities(NativeFullTextSearchWithIndex))] mod search_filter_with_index { use indoc::indoc; diff --git a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/order_and_pagination/order_by_relevance.rs b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/order_and_pagination/order_by_relevance.rs index a5c9252681ff..933ec2e080da 100644 --- a/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/order_and_pagination/order_by_relevance.rs +++ b/query-engine/connector-test-kit-rs/query-engine-tests/tests/queries/order_and_pagination/order_by_relevance.rs @@ -490,7 +490,7 @@ async fn create_row(runner: &Runner, data: &str) -> TestResult<()> { Ok(()) } -#[test_suite(schema(schema), capabilities(FullTextSearchWithoutIndex))] +#[test_suite(schema(schema), capabilities(NativeFullTextSearchWithoutIndex))] mod order_by_relevance_without_index { use indoc::indoc; @@ -572,7 +572,7 @@ mod order_by_relevance_without_index { } } -#[test_suite(schema(schema), capabilities(FullTextSearchWithIndex))] +#[test_suite(schema(schema), capabilities(NativeFullTextSearchWithIndex))] mod order_by_relevance_with_index { use indoc::indoc; diff --git a/query-engine/connectors/query-connector/src/error.rs b/query-engine/connectors/query-connector/src/error.rs index d9f7e99688ac..289a022f596c 100644 --- a/query-engine/connectors/query-connector/src/error.rs +++ b/query-engine/connectors/query-connector/src/error.rs @@ -89,8 +89,8 @@ impl ConnectorError { }, )), - ErrorKind::MissingFullTextSearchIndex => Some(KnownError::new( - user_facing_errors::query_engine::MissingFullTextSearchIndex {}, + ErrorKind::NativeMissingFullTextSearchIndex => Some(KnownError::new( + user_facing_errors::query_engine::MissingNativeFullTextSearchIndex {}, )), ErrorKind::TransactionAborted { message } => Some(KnownError::new( user_facing_errors::query_engine::InteractiveTransactionError { error: message.clone() }, @@ -270,8 +270,8 @@ pub enum ErrorKind { #[error("The query parameter limit supported by your database is exceeded: {0}.")] QueryParameterLimitExceeded(String), - #[error("Cannot find a fulltext index to use for the search")] - MissingFullTextSearchIndex, + #[error("Cannot find a fulltext index to use for the native search")] + NativeMissingFullTextSearchIndex, #[error("Replica Set required for Transactions")] MongoReplicaSetRequired, diff --git a/query-engine/connectors/sql-query-connector/src/error.rs b/query-engine/connectors/sql-query-connector/src/error.rs index 29664f2b1185..33f94aa40c4a 100644 --- a/query-engine/connectors/sql-query-connector/src/error.rs +++ b/query-engine/connectors/sql-query-connector/src/error.rs @@ -290,7 +290,9 @@ impl SqlError { SqlError::QueryParameterLimitExceeded(e) => { ConnectorError::from_kind(ErrorKind::QueryParameterLimitExceeded(e)) } - SqlError::MissingFullTextSearchIndex => ConnectorError::from_kind(ErrorKind::MissingFullTextSearchIndex), + SqlError::MissingFullTextSearchIndex => { + ConnectorError::from_kind(ErrorKind::NativeMissingFullTextSearchIndex) + } SqlError::InvalidIsolationLevel(msg) => ConnectorError::from_kind(ErrorKind::InternalConversionError(msg)), SqlError::ExternalError(error_id) => ConnectorError::from_kind(ErrorKind::ExternalError(error_id)), SqlError::TooManyConnections(e) => ConnectorError::from_kind(ErrorKind::TooManyConnections(e)), diff --git a/query-engine/connectors/sql-query-connector/src/filter/visitor.rs b/query-engine/connectors/sql-query-connector/src/filter/visitor.rs index f067cf94f8c3..75c5ce77bb7b 100644 --- a/query-engine/connectors/sql-query-connector/src/filter/visitor.rs +++ b/query-engine/connectors/sql-query-connector/src/filter/visitor.rs @@ -355,7 +355,7 @@ impl FilterVisitorExt for FilterVisitor { fn visit_scalar_filter(&mut self, filter: ScalarFilter, ctx: &Context<'_>) -> ConditionTree<'static> { match filter.condition { ScalarCondition::Search(_, _) | ScalarCondition::NotSearch(_, _) => { - reachable_only_with_capability!(ConnectorCapability::FullTextSearch); + reachable_only_with_capability!(ConnectorCapability::NativeFullTextSearch); let mut projections = match filter.condition.clone() { ScalarCondition::Search(_, proj) => proj, ScalarCondition::NotSearch(_, proj) => proj, @@ -958,7 +958,7 @@ fn default_scalar_filter( comparable.not_equals(Expression::from(field_ref.aliased_col(alias, ctx)).all()) } ScalarCondition::Search(value, _) => { - reachable_only_with_capability!(ConnectorCapability::FullTextSearch); + reachable_only_with_capability!(ConnectorCapability::NativeFullTextSearch); let query: String = value .into_value() .unwrap() @@ -968,7 +968,7 @@ fn default_scalar_filter( comparable.matches(query) } ScalarCondition::NotSearch(value, _) => { - reachable_only_with_capability!(ConnectorCapability::FullTextSearch); + reachable_only_with_capability!(ConnectorCapability::NativeFullTextSearch); let query: String = value .into_value() .unwrap() @@ -1140,7 +1140,7 @@ fn insensitive_scalar_filter( comparable.compare_raw("NOT ILIKE", Expression::from(field_ref.aliased_col(alias, ctx)).all()) } ScalarCondition::Search(value, _) => { - reachable_only_with_capability!(ConnectorCapability::FullTextSearch); + reachable_only_with_capability!(ConnectorCapability::NativeFullTextSearch); let query: String = value .into_value() .unwrap() @@ -1150,7 +1150,7 @@ fn insensitive_scalar_filter( comparable.matches(query) } ScalarCondition::NotSearch(value, _) => { - reachable_only_with_capability!(ConnectorCapability::FullTextSearch); + reachable_only_with_capability!(ConnectorCapability::NativeFullTextSearch); let query: String = value .into_value() .unwrap() diff --git a/query-engine/connectors/sql-query-connector/src/ordering.rs b/query-engine/connectors/sql-query-connector/src/ordering.rs index 061c6e05f4a1..3906a3ca0aa9 100644 --- a/query-engine/connectors/sql-query-connector/src/ordering.rs +++ b/query-engine/connectors/sql-query-connector/src/ordering.rs @@ -49,7 +49,7 @@ impl OrderByBuilder { } OrderBy::ToManyAggregation(order_by) => self.build_order_aggr_rel(order_by, needs_reversed_order, ctx), OrderBy::Relevance(order_by) => { - reachable_only_with_capability!(ConnectorCapability::FullTextSearch); + reachable_only_with_capability!(ConnectorCapability::NativeFullTextSearch); self.build_order_relevance(order_by, needs_reversed_order, ctx) } }) diff --git a/query-engine/schema/src/query_schema.rs b/query-engine/schema/src/query_schema.rs index 8bf7a2b2e99a..6294f4afd76a 100644 --- a/query-engine/schema/src/query_schema.rs +++ b/query-engine/schema/src/query_schema.rs @@ -105,7 +105,8 @@ impl QuerySchema { } pub(crate) fn can_full_text_search(&self) -> bool { - self.has_feature(PreviewFeature::FullTextSearch) && self.has_capability(ConnectorCapability::FullTextSearch) + // TODO: add connector-specific `self.has_native_feature(ConnectorCapability::NativeFullTextSearch)` in conjunction with the next bool. + self.has_capability(ConnectorCapability::NativeFullTextSearch) } /// Returns whether the loaded connector supports the join strategy.