diff --git a/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs b/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs index ed7ac6ebc..29712673c 100644 --- a/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs +++ b/src/EFCore.PG/Storage/Internal/NpgsqlTypeMappingSource.cs @@ -352,6 +352,13 @@ public NpgsqlTypeMappingSource( { typeof(NpgsqlRange), _tstzrange }, { typeof(NpgsqlRange), _dateOnlyDaterange }, { typeof(NpgsqlTsQuery), _tsquery }, + { typeof(NpgsqlTsQueryLexeme), _tsquery }, + { typeof(NpgsqlTsQueryNot), _tsquery }, + { typeof(NpgsqlTsQueryBinOp), _tsquery }, + { typeof(NpgsqlTsQueryAnd), _tsquery }, + { typeof(NpgsqlTsQueryOr), _tsquery }, + { typeof(NpgsqlTsQueryFollowedBy), _tsquery }, + { typeof(NpgsqlTsQueryEmpty), _tsquery }, { typeof(NpgsqlTsVector), _tsvector }, { typeof(NpgsqlTsRankingNormalization), _rankingNormalization }, { typeof(LTree), _ltree } diff --git a/test/EFCore.PG.FunctionalTests/Query/Translations/FullTextSearchTranslationsTest.cs b/test/EFCore.PG.FunctionalTests/Query/Translations/FullTextSearchTranslationsTest.cs new file mode 100644 index 000000000..765e2bbbd --- /dev/null +++ b/test/EFCore.PG.FunctionalTests/Query/Translations/FullTextSearchTranslationsTest.cs @@ -0,0 +1,38 @@ +namespace Microsoft.EntityFrameworkCore.Query.Translations; + +public class FullTextSearchTranslationsTest : IClassFixture +{ + private BasicTypesQueryNpgsqlFixture Fixture { get; } + + public FullTextSearchTranslationsTest(BasicTypesQueryNpgsqlFixture fixture, ITestOutputHelper testOutputHelper) + { + Fixture = fixture; + Fixture.TestSqlLoggerFactory.Clear(); + Fixture.TestSqlLoggerFactory.SetTestOutputHelper(testOutputHelper); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public async Task Matches_with_derived_tsquery_parameter(bool async) + { + using var context = Fixture.CreateContext(); + var tsQuery = new NpgsqlTsQueryLexeme("firs", NpgsqlTsQueryLexeme.Weight.None, true); + var query = context.BasicTypesEntities + .Select(b => EF.Functions.ToTsVector("simple", "first").Matches(tsQuery)); + + var results = async ? await query.ToArrayAsync() : query.ToArray(); + + Assert.NotEmpty(results); + Assert.All(results, Assert.True); + Fixture.TestSqlLoggerFactory.AssertBaseline( + [ + """ +@tsQuery=''firs':*' (DbType = Object) + +SELECT to_tsvector('simple', 'first') @@ @tsQuery +FROM "BasicTypesEntities" AS b +""" + ]); + } +} diff --git a/test/EFCore.PG.Tests/Storage/NpgsqlTypeMappingSourceTest.cs b/test/EFCore.PG.Tests/Storage/NpgsqlTypeMappingSourceTest.cs index e05035581..203b4aff1 100644 --- a/test/EFCore.PG.Tests/Storage/NpgsqlTypeMappingSourceTest.cs +++ b/test/EFCore.PG.Tests/Storage/NpgsqlTypeMappingSourceTest.cs @@ -140,6 +140,22 @@ public void By_ClrType(Type clrType, string expectedStoreType) Assert.Same(clrType, mapping.ClrType); } + [Theory] + [InlineData(typeof(NpgsqlTsQuery))] + [InlineData(typeof(NpgsqlTsQueryLexeme))] + [InlineData(typeof(NpgsqlTsQueryNot))] + [InlineData(typeof(NpgsqlTsQueryBinOp))] + [InlineData(typeof(NpgsqlTsQueryAnd))] + [InlineData(typeof(NpgsqlTsQueryOr))] + [InlineData(typeof(NpgsqlTsQueryFollowedBy))] + [InlineData(typeof(NpgsqlTsQueryEmpty))] + public void TsQuery(Type clrType) + { + var mapping = Assert.IsType(CreateTypeMappingSource().FindMapping(clrType)); + Assert.Equal("tsquery", mapping.StoreType); + Assert.Same(typeof(NpgsqlTsQuery), mapping.ClrType); + } + [Theory] [InlineData(typeof(decimal), "numeric(5)")] [InlineData(typeof(DateTime), "timestamp(5) with time zone")]