Skip to content

Commit 9757301

Browse files
committed
[MEVD] Fix filtering by true
Fixes #13293
1 parent 3bc2a64 commit 9757301

File tree

13 files changed

+70
-34
lines changed

13 files changed

+70
-34
lines changed

dotnet/src/VectorData/Common/SqlFilterTranslator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ protected void Translate(Expression? node, bool isSearchCondition = false)
5757
return;
5858

5959
case ConstantExpression constant:
60-
this.TranslateConstant(constant.Value);
60+
this.TranslateConstant(constant.Value, isSearchCondition);
6161
return;
6262

6363
case QueryParameterExpression { Name: var name, Value: var value }:
@@ -136,7 +136,7 @@ static bool IsNull(Expression expression)
136136
=> expression is ConstantExpression { Value: null } or QueryParameterExpression { Value: null };
137137
}
138138

139-
protected virtual void TranslateConstant(object? value)
139+
protected virtual void TranslateConstant(object? value, bool isSearchCondition)
140140
{
141141
switch (value)
142142
{

dotnet/src/VectorData/CosmosMongoDB/CosmosMongoFilterTranslator.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ or ExpressionType.LessThan or ExpressionType.LessThanOrEqual
5555
// Special handling for bool constant as the filter expression (r => r.Bool)
5656
Expression when node.Type == typeof(bool) && this.TryBindProperty(node, out var property)
5757
=> this.GenerateEqualityComparison(property, value: true, ExpressionType.Equal),
58+
// Handle true literal (r => true), which is useful for fetching all records
59+
ConstantExpression { Value: true }
60+
=> [],
5861

5962
MethodCallExpression methodCall => this.TranslateMethodCall(methodCall),
6063

dotnet/src/VectorData/MongoDB/MongoFilterTranslator.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ or ExpressionType.LessThan or ExpressionType.LessThanOrEqual
5151
// Handle converting non-nullable to nullable; such nodes are found in e.g. r => r.Int == nullableInt
5252
UnaryExpression { NodeType: ExpressionType.Convert } convert when Nullable.GetUnderlyingType(convert.Type) == convert.Operand.Type
5353
=> this.Translate(convert.Operand),
54+
// Handle true literal (r => true), which is useful for fetching all records
55+
ConstantExpression { Value: true }
56+
=> [],
5457

5558
// Special handling for bool constant as the filter expression (r => r.Bool)
5659
Expression when node.Type == typeof(bool) && this.TryBindProperty(node, out var property)

dotnet/src/VectorData/PgVector/PostgresFilterTranslator.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ internal PostgresFilterTranslator(
2525

2626
internal List<object> ParameterValues { get; } = new();
2727

28-
protected override void TranslateConstant(object? value)
28+
protected override void TranslateConstant(object? value, bool isSearchCondition)
2929
{
3030
switch (value)
3131
{
@@ -55,14 +55,14 @@ protected override void TranslateConstant(object? value)
5555
this._sql.Append(',');
5656
}
5757

58-
this.TranslateConstant(element);
58+
this.TranslateConstant(element, isSearchCondition: false);
5959
}
6060

6161
this._sql.Append(']');
6262
return;
6363

6464
default:
65-
base.TranslateConstant(value);
65+
base.TranslateConstant(value, isSearchCondition);
6666
break;
6767
}
6868
}

dotnet/src/VectorData/Qdrant/QdrantFilterTranslator.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
namespace Microsoft.SemanticKernel.Connectors.Qdrant;
1919

20+
// https://qdrant.tech/documentation/concepts/filtering
2021
internal class QdrantFilterTranslator
2122
{
2223
private CollectionModel _model = null!;
@@ -58,6 +59,8 @@ private Filter Translate(Expression? node)
5859
// Special handling for bool constant as the filter expression (r => r.Bool)
5960
Expression when node.Type == typeof(bool) && this.TryBindProperty(node, out var property)
6061
=> this.GenerateEqual(property.StorageName, value: true),
62+
// Handle true literal (r => true), which is useful for fetching all records
63+
ConstantExpression { Value: true } => new Filter(),
6164

6265
MethodCallExpression methodCall => this.TranslateMethodCall(methodCall),
6366

dotnet/src/VectorData/Redis/RedisFilterTranslator.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ internal string Translate(LambdaExpression lambdaExpression, CollectionModel mod
2727
Debug.Assert(lambdaExpression.Parameters.Count == 1);
2828
this._recordParameter = lambdaExpression.Parameters[0];
2929

30+
// Weaviate doesn't seem to have a native way of expressing "always true" filters; since this scenario is important for fetching
31+
// all records (via GetAsync with filter), we special-case and support it here. Note that false isn't supported (useless),
32+
// nor is 'x && true'.
33+
if (lambdaExpression.Body is ConstantExpression { Value: true })
34+
{
35+
return "*";
36+
}
37+
3038
var preprocessor = new FilterTranslationPreprocessor { SupportsParameterization = false };
3139
var preprocessedExpression = preprocessor.Preprocess(lambdaExpression.Body);
3240

dotnet/src/VectorData/SqlServer/SqlServerFilterTranslator.cs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,15 @@ internal SqlServerFilterTranslator(
2929

3030
internal List<object> ParameterValues => this._parameterValues;
3131

32-
protected override void TranslateConstant(object? value)
32+
protected override void TranslateConstant(object? value, bool isSearchCondition)
3333
{
3434
switch (value)
3535
{
36+
case bool boolValue when isSearchCondition:
37+
this._sql.Append(boolValue ? "1 = 1" : "1 = 0");
38+
return;
3639
case bool boolValue:
37-
this._sql.Append(boolValue ? "1" : "0");
40+
this._sql.Append(boolValue ? "CAST(1 AS BIT)" : "CAST(0 AS BIT)");
3841
return;
3942
case DateTime dateTime:
4043
this._sql.Append('\'').Append(dateTime.ToString("o")).Append('\'');
@@ -54,7 +57,7 @@ protected override void TranslateConstant(object? value)
5457
#endif
5558

5659
default:
57-
base.TranslateConstant(value);
60+
base.TranslateConstant(value, isSearchCondition);
5861
break;
5962
}
6063
}
@@ -108,7 +111,7 @@ protected override void TranslateContainsOverParameterizedArray(Expression sourc
108111
this._sql.Append(", ");
109112
}
110113

111-
this.TranslateConstant(element);
114+
this.TranslateConstant(element, isSearchCondition: false);
112115
}
113116

114117
this._sql.Append(')');

dotnet/src/VectorData/SqliteVec/SqliteFilterTranslator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ protected override void TranslateContainsOverParameterizedArray(Expression sourc
4545
this._sql.Append(", ");
4646
}
4747

48-
this.TranslateConstant(element);
48+
this.TranslateConstant(element, isSearchCondition: false);
4949
}
5050

5151
this._sql.Append(')');

dotnet/src/VectorData/Weaviate/WeaviateFilterTranslator.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal class WeaviateFilterTranslator
2020
private ParameterExpression _recordParameter = null!;
2121
private readonly StringBuilder _filter = new();
2222

23-
internal string Translate(LambdaExpression lambdaExpression, CollectionModel model)
23+
internal string? Translate(LambdaExpression lambdaExpression, CollectionModel model)
2424
{
2525
Debug.Assert(this._filter.Length == 0);
2626

@@ -29,6 +29,14 @@ internal string Translate(LambdaExpression lambdaExpression, CollectionModel mod
2929
Debug.Assert(lambdaExpression.Parameters.Count == 1);
3030
this._recordParameter = lambdaExpression.Parameters[0];
3131

32+
// Weaviate doesn't seem to have a native way of expressing "always true" filters; since this scenario is important for fetching
33+
// all records (via GetAsync with filter), we special-case and support it here. Note that false isn't supported (useless),
34+
// nor is 'x && true'.
35+
if (lambdaExpression.Body is ConstantExpression { Value: true })
36+
{
37+
return null;
38+
}
39+
3240
var preprocessor = new FilterTranslationPreprocessor { SupportsParameterization = false };
3341
var preprocessedExpression = preprocessor.Preprocess(lambdaExpression.Body);
3442

dotnet/src/VectorData/Weaviate/WeaviateQueryBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ public static string BuildQuery<TRecord>(
9797
{{collectionName}} (
9898
limit: {{top}}
9999
offset: {{queryOptions.Skip}}
100-
where: {{translatedFilter}}
100+
{{(translatedFilter is null ? "" : "where: " + translatedFilter)}}
101101
sort: [ {{sortPaths}} ]
102102
) {
103103
{{string.Join(" ", model.DataProperties.Select(p => p.StorageName))}}

0 commit comments

Comments
 (0)