Skip to content

Commit

Permalink
Merge branch 'v5.4' of github.com:ravendb/ravendb into v6.0
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/Raven.Client/Documents/Changes/DatabaseChanges.cs
#	src/Raven.Client/Documents/Changes/DatabaseConnectionState.cs
#	src/Raven.Client/Http/RequestExecutor.cs
#	src/Raven.Server/Documents/DatabaseRequestHandler.cs
#	src/Raven.Server/Documents/DocumentDatabase.cs
#	src/Raven.Server/Documents/Expiration/ExpirationStorage.cs
#	src/Raven.Server/Documents/Handlers/Admin/AdminAnalyzersHandler.cs
#	src/Raven.Server/Documents/Handlers/Admin/AdminIndexHandler.cs
#	src/Raven.Server/Documents/Handlers/Admin/AdminSortersHandler.cs
#	src/Raven.Server/Documents/Handlers/IndexHandler.cs
#	src/Raven.Server/Documents/PeriodicBackup/PeriodicBackupRunner.cs
#	src/Raven.Server/Documents/Queries/QueryRunner.cs
#	src/Raven.Server/Web/Authentication/AdminCertificatesHandler.cs
#	src/Raven.Server/Web/RequestHandler.Audit.cs
#	src/Raven.Server/Web/System/AdminDatabasesHandler.cs
#	test/SlowTests/Client/ChangesApiFailover.cs
#	test/SlowTests/Issues/RavenDB_19693.cs
#	test/SlowTests/Issues/RavenDB_9519.cs
#	test/SlowTests/Server/Documents/Expiration/ExpirationTests.cs
#	test/SlowTests/Tests/TestsInheritanceTests.cs
  • Loading branch information
arekpalinski committed May 16, 2024
2 parents 0deb428 + 8bd93ee commit d4f7c01
Show file tree
Hide file tree
Showing 8 changed files with 164 additions and 32 deletions.
31 changes: 17 additions & 14 deletions src/Raven.Client/Documents/Linq/RavenQueryProviderProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ internal sealed class RavenQueryProviderProcessor<T>
private readonly LinqQueryHighlightings _highlightings;
private readonly QueryStatistics _queryStatistics;
private bool _chainedWhere;
private int _insideWhere;
private int _insideFilter;
private int _insideWhereOrSearchCounter;
private int _insideFilterCounter;
private bool _insideNegate;
private bool _insideExact;
private SpecialQueryType _queryType = SpecialQueryType.None;
Expand Down Expand Up @@ -235,7 +235,7 @@ private void VisitExpression(Expression expression)

private void VisitBinaryExpression(BinaryExpression expression)
{
if (_insideWhere > 0)
if (_insideWhereOrSearchCounter > 0)
{
VerifyLegalBinaryExpression(expression);
}
Expand Down Expand Up @@ -315,7 +315,6 @@ private void VisitAndAlso(BinaryExpression andAlso)
if (TryHandleBetween(andAlso))
return;


if (_subClauseDepth > 0)
DocumentQuery.OpenSubclause();
_subClauseDepth++;
Expand Down Expand Up @@ -1686,7 +1685,6 @@ private void VisitSearch(MethodCallExpression searchExpression)
object value;
while (true)
{

expressions.Add(search);

if (LinqPathProvider.GetValueFromExpressionWithoutConversion(search.Arguments[4], out value) == false)
Expand All @@ -1706,7 +1704,12 @@ private void VisitSearch(MethodCallExpression searchExpression)
target = search.Arguments[0];
}

// This has to be set in order to have correct parentheses
// when using both search and where clause, e.g.
// where (Category = $p0 or Category = $p1) and search(Name, $p2)
_insideWhereOrSearchCounter++;
VisitExpression(target);
_insideWhereOrSearchCounter--;

if (expressions.Count > 1)
{
Expand Down Expand Up @@ -1898,7 +1901,7 @@ private void VisitQueryableMethodCall(MethodCallExpression expression)
break;
case "Filter":
{
_insideFilter++;
_insideFilterCounter++;
VisitExpression(expression.Arguments[0]);
using (FilterModeScope(true))
{
Expand All @@ -1908,15 +1911,15 @@ private void VisitQueryableMethodCall(MethodCallExpression expression)
DocumentQuery.OpenSubclause();
}

if (_chainedWhere == false && _insideFilter > 1)
if (_chainedWhere == false && _insideFilterCounter > 1)
DocumentQuery.OpenSubclause();

VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
if (_chainedWhere == false && _insideFilter > 1)
if (_chainedWhere == false && _insideFilterCounter > 1)
DocumentQuery.CloseSubclause();
if (_chainedWhere)
DocumentQuery.CloseSubclause();
_insideFilter--;
_insideFilterCounter--;
if (expression.Arguments.Count is 3 && LinqPathProvider.GetValueFromExpressionWithoutConversion(expression.Arguments[2], out var limit))
{
AddFilterLimit((int)limit);
Expand All @@ -1929,14 +1932,14 @@ private void VisitQueryableMethodCall(MethodCallExpression expression)
{
using (FilterModeScope(@on: false))
{
_insideWhere++;
_insideWhereOrSearchCounter++;
VisitExpression(expression.Arguments[0]);
if (_chainedWhere)
{
DocumentQuery.AndAlso();
DocumentQuery.OpenSubclause();
}
if (_chainedWhere == false && _insideWhere > 1)
if (_chainedWhere == false && _insideWhereOrSearchCounter > 1)
DocumentQuery.OpenSubclause();

if (expression.Arguments.Count == 3)
Expand All @@ -1945,12 +1948,12 @@ private void VisitQueryableMethodCall(MethodCallExpression expression)
VisitExpression(((UnaryExpression)expression.Arguments[1]).Operand);
_insideExact = false;

if (_chainedWhere == false && _insideWhere > 1)
if (_chainedWhere == false && _insideWhereOrSearchCounter > 1)
DocumentQuery.CloseSubclause();
if (_chainedWhere)
DocumentQuery.CloseSubclause();
_chainedWhere = true;
_insideWhere--;
_insideWhereOrSearchCounter--;
}
break;
}
Expand Down Expand Up @@ -2923,7 +2926,7 @@ private void AddReturnStatementToOutputFunction(Expression expression)

private void VisitLet(NewExpression expression)
{
if (_insideWhere > 0)
if (_insideWhereOrSearchCounter > 0)
throw new NotSupportedException("Queries with a LET clause before a WHERE clause are not supported. " +
"WHERE clauses should appear before any LET clauses.");

Expand Down
3 changes: 3 additions & 0 deletions src/Raven.Client/Http/RequestExecutor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2091,6 +2091,9 @@ public static HttpClientHandler CreateHttpMessageHandler(X509Certificate2 certif

if (certificate != null)
{
if (httpMessageHandler.ClientCertificates == null)
throw new NotSupportedException($"{typeof(HttpClientHandler)} does not support {nameof(httpMessageHandler.ClientCertificates)}. Setting the UseNativeHttpHandler property in project settings to false may solve the issue.");

httpMessageHandler.ClientCertificates.Add(certificate);
try
{
Expand Down
19 changes: 8 additions & 11 deletions src/Sparrow.Server/Compression/Encoder3Gram.cs
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,13 @@ private void BuildDictionary(in FastList<SymbolCode> symbolCodeList)
int maxBitSequenceLength = 1;
int minBitSequenceLength = int.MaxValue;

int tableI = 0;
for (int i = 0; i < dictSize; i++)
{
var symbol = symbolCodeList[i];
int symbolLength = symbol.Length;

ref var entry = ref EncodingTable[i];
var entry = EncodingTable[tableI];

// We update the size first to avoid getting a zero size start key.
entry.KeyLength = (byte)symbolLength;
Expand Down Expand Up @@ -476,24 +477,20 @@ private void BuildDictionary(in FastList<SymbolCode> symbolCodeList)
entry.PrefixLength = (byte)symbolLength;
}

if (entry.PrefixLength == 0)
{
i--;
continue;
}

Debug.Assert(entry.PrefixLength > 0);

entry.Code = symbolCodeList[i].Code;

maxBitSequenceLength = Math.Max(maxBitSequenceLength, entry.Code.Length);
minBitSequenceLength = Math.Min(minBitSequenceLength, entry.Code.Length);

tree.Add((uint)entry.Code.Value, entry.Code.Length, (short)i);

// We update the table.
EncodingTable[tableI] = entry;
tableI++;
}

_entries = dictSize;
NumberOfEntries = dictSize;
_entries = tableI;
NumberOfEntries = tableI;
MaxBitSequenceLength = maxBitSequenceLength;
MinBitSequenceLength = minBitSequenceLength;
}
Expand Down
4 changes: 2 additions & 2 deletions test/FastTests/Issues/RavenDB_12235.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void ShouldBeAbleToMoveBetweenDocumentQueryToIRavenQueryable()
q = q.Where(x => x.Name == "123");
q = q.Search(x => x.Age, "123");

Assert.Equal("from 'Users' where Name = $p0 and search(Age, $p1)", q.ToString());
Assert.Equal("from 'Users' where (Name = $p0) and search(Age, $p1)", q.ToString());
Assert.Equal("from 'Users'", docQuery.ToString());
}

Expand All @@ -35,7 +35,7 @@ public void ShouldBeAbleToMoveBetweenDocumentQueryToIRavenQueryable()
q = q.Where(x => x.Name == "123");
q = q.Search(x => x.Age, "123");

Assert.Equal("from 'Users' where Name = $p0 and search(Age, $p1)", q.ToString());
Assert.Equal("from 'Users' where (Name = $p0) and search(Age, $p1)", q.ToString());
Assert.Equal("from 'Users'", docQuery.ToString());
}
}
Expand Down
1 change: 1 addition & 0 deletions test/FastTests/Sparrow/Encoder3GramTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,7 @@ public void EnsureEscapedSequencesWithNullsWork(int randomSeed)
[Theory]
[MemberData("RandomSeed")]
[InlineData(7157)]
[InlineData(50407)]
public void VerifyCorrectDecodingWithNulls(int randomSeed)
{
State state = new(64000);
Expand Down
2 changes: 1 addition & 1 deletion test/SlowTests/Client/Queries/FullTextSearch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ public void SearchCanUseAnd2(Options options)

var query = RavenTestHelper.GetIndexQuery(ravenQueryable);

Assert.Equal("from index 'test' where Name = $p0 and search(Tags, $p1)", query.Query);
Assert.Equal("from index 'test' where (Name = $p0) and search(Tags, $p1)", query.Query);
Assert.Equal("i love cats", query.QueryParameters["p1"]);
Assert.Equal("User", query.QueryParameters["p0"]);
}
Expand Down
128 changes: 128 additions & 0 deletions test/SlowTests/Issues/RavenDB-22323.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
using System.Linq;
using FastTests;
using Raven.Client.Documents;
using Raven.Client.Documents.Indexes;
using Tests.Infrastructure;
using Xunit;
using Xunit.Abstractions;

namespace SlowTests.Issues;

public class RavenDB_22323 : RavenTestBase
{
public RavenDB_22323(ITestOutputHelper output) : base(output)
{
}

[RavenFact(RavenTestCategory.Querying)]
public void TestParenthesesWhenUsingSearchAndWhereClause()
{
using (var store = GetDocumentStore())
{
using (var session = store.OpenSession())
{
var query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Category == "A" || d.Category == "B")
.Search(d => d.Name, "Peter*")
.ToString();

Assert.Equal("from index 'DummyIndex' where (Category = $p0 or Category = $p1) and search(Name, $p2)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Search(d => d.Name, "Peter*")
.Where(d => d.Category == "A" || d.Category == "B")
.ToString();

Assert.Equal("from index 'DummyIndex' where search(Name, $p0) and (Category = $p1 or Category = $p2)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Category == "A" || d.Category == "B")
.ToString();

Assert.Equal("from index 'DummyIndex' where Category = $p0 or Category = $p1", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Category == "A")
.ToString();

Assert.Equal("from index 'DummyIndex' where Category = $p0", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Category == "A")
.Where(d => d.Name == "aaa")
.ToString();

Assert.Equal("from index 'DummyIndex' where (Category = $p0) and (Name = $p1)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Category == "A")
.Search(d => d.Name, "Peter*")
.ToString();

Assert.Equal("from index 'DummyIndex' where (Category = $p0) and search(Name, $p1)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Search(d => d.Name, "Peter*")
.Search(d => d.Category, "A", options: SearchOptions.Or)
.Where(d => d.Category == "A" || d.Category == "B")
.Search(d => d.Surname, "DDD", options: SearchOptions.And)
.ToString();

Assert.Equal("from index 'DummyIndex' where search(Name, $p0) or search(Category, $p1) and (Category = $p2 or Category = $p3) and search(Surname, $p4)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Category == "A" || d.Category == "B")
.Search(d => d.Name, "Peter*")
.Search(d => d.Category, "A", options: SearchOptions.Or)
.Search(d => d.Surname, "DDD", options: SearchOptions.And)
.ToString();

Assert.Equal("from index 'DummyIndex' where (Category = $p0 or Category = $p1) and search(Name, $p2) or search(Category, $p3) and search(Surname, $p4)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Search(d => d.Name, "Peter*")
.Where(d => d.Category == "A")
.Search(d => d.Category, "A")
.ToString();

Assert.Equal("from index 'DummyIndex' where search(Name, $p0) and (Category = $p1) and search(Category, $p2)", query);

query = session.Query<DummyIndex.Result, DummyIndex>()
.Where(d => d.Name == "Peter")
.Search(d => d.Name, "Peter*")
.Where(d => d.Category == "A")
.ToString();

Assert.Equal("from index 'DummyIndex' where (Name = $p0) and search(Name, $p1) and (Category = $p2)", query);
}
}
}

private class Dto
{
public string Category { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}

private class DummyIndex : AbstractIndexCreationTask<Dto>
{
public class Result
{
public string Category { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}

public DummyIndex()
{
Map = dtos => from dto in dtos
select new Result()
{
Category = dto.Category,
Name = dto.Name,
Surname = dto.Surname
};
}
}
}
8 changes: 4 additions & 4 deletions test/SlowTests/Issues/RavenDB_12346.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public void CanConvertFromQueryToDocumentQuery(Options options)
docQuery = q.ToDocumentQuery();

Assert.Equal(q.ToString(), docQuery.ToString());
Assert.Equal("from 'Users' where Name = $p0 and search(Age, $p1)", docQuery.ToString());
Assert.Equal("from 'Users' where (Name = $p0) and search(Age, $p1)", docQuery.ToString());

var e = Assert.Throws<InvalidOperationException>(() => q.ToAsyncDocumentQuery());
Assert.Equal("Cannot convert sync query to async document query.", e.Message);
Expand All @@ -43,7 +43,7 @@ public void CanConvertFromQueryToDocumentQuery(Options options)
docQuery = q.ToDocumentQuery();

Assert.Equal(q.ToString(), docQuery.ToString());
Assert.Equal("from 'Users' where Name = $p0 and search(Age, $p1) or Age > $p2", docQuery.ToString());
Assert.Equal("from 'Users' where (Name = $p0) and search(Age, $p1) or Age > $p2", docQuery.ToString());
}

using (var asyncSession = store.OpenAsyncSession())
Expand All @@ -56,7 +56,7 @@ public void CanConvertFromQueryToDocumentQuery(Options options)
docQuery = q.ToAsyncDocumentQuery();

Assert.Equal(q.ToString(), docQuery.ToString());
Assert.Equal("from 'Users' where Name = $p0 and search(Age, $p1)", docQuery.ToString());
Assert.Equal("from 'Users' where (Name = $p0) and search(Age, $p1)", docQuery.ToString());

var e = Assert.Throws<InvalidOperationException>(() => q.ToDocumentQuery());
Assert.Equal("Cannot convert async query to sync document query.", e.Message);
Expand All @@ -68,7 +68,7 @@ public void CanConvertFromQueryToDocumentQuery(Options options)
docQuery = q.ToAsyncDocumentQuery();

Assert.Equal(q.ToString(), docQuery.ToString());
Assert.Equal("from 'Users' where Name = $p0 and search(Age, $p1) or Age > $p2", docQuery.ToString());
Assert.Equal("from 'Users' where (Name = $p0) and search(Age, $p1) or Age > $p2", docQuery.ToString());
}
}
}
Expand Down

0 comments on commit d4f7c01

Please sign in to comment.