Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions packages/Postgrest/Postgrest.Tests/Linq/WhereClauseTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,20 @@ public void Where_ShouldTranslateNegatedBooleanMemberIntoNotEqTrue()
.GenerateUrl().Should().Be($"{BaseUrl}/kitchen_sink?bool_value=not.eq.True");
}

[TestMethod]
public void Where_ShouldUseColumnName_GivenBareNullableBooleanValueMember()
{
this.client.Table<NullableFlag>().Where(x => x.IsActive!.Value)
.GenerateUrl().Should().Be($"{BaseUrl}/nullable_flag?is_active=eq.True");
}

[TestMethod]
public void Where_ShouldUseColumnName_GivenNegatedNullableBooleanValueMember()
{
this.client.Table<NullableFlag>().Where(x => !x.IsActive!.Value)
.GenerateUrl().Should().Be($"{BaseUrl}/nullable_flag?is_active=not.eq.True");
}

[TestMethod]
public void Where_ShouldNestBooleanMember_GivenAnAndPredicate()
{
Expand Down
18 changes: 18 additions & 0 deletions packages/Postgrest/Postgrest.Tests/Models/NullableFlag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#nullable enable
using Supabase.Postgrest.Attributes;
using Supabase.Postgrest.Models;

namespace Postgrest.Tests.Models;

/// <summary>
/// A model with a nullable boolean column, used to assert that a bare `Nullable&lt;bool&gt;.Value`
/// predicate (i.e. `x => x.IsActive!.Value`) resolves to the mapped column rather than `Value`.
/// URL-generation only; it is not backed by a seeded table.
/// </summary>
[Table("nullable_flag")]
public class NullableFlag : BaseModel
{
[PrimaryKey("id")] public int? Id { get; set; }

[Column("is_active")] public bool? IsActive { get; set; }
}
9 changes: 6 additions & 3 deletions packages/Postgrest/Postgrest/Linq/WhereExpressionVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -182,8 +182,9 @@ protected override Expression VisitConditional(ConditionalExpression node) =>
Expression.AndAlso(Expression.Not(node.Test), node.IfFalse)));

/// <summary>
/// Handles a boolean column used directly as a predicate (i.e. `x => x.IsActive`, or negated via
/// <see cref="VisitUnary"/> `x => !x.IsActive`), translating it into a `column.eq.true` filter.
/// Handles a boolean column used directly as a predicate (i.e. `x => x.IsActive`, its nullable
/// `x => x.IsActive!.Value` form, or negated via <see cref="VisitUnary"/> `x => !x.IsActive`),
/// translating it into a `column.eq.true` filter.
/// </summary>
/// <param name="node"></param>
/// <returns></returns>
Expand All @@ -192,7 +193,9 @@ protected override Expression VisitMember(MemberExpression node)
if (node.Type != typeof(bool) || !this.ContainsParameter(node))
return base.VisitMember(node);

this.Filter = new QueryFilter(this.GetColumnFromMemberExpression(node), Operator.Equals, true);
var column = this.ResolveColumn(node) ?? throw new ArgumentException(
$"Expression: '{node}' is expected to be property with a ColumnAttribute or PrimaryKeyAttribute");
this.Filter = new QueryFilter(column, Operator.Equals, true);
return node;
}

Expand Down
Loading