Skip to content

Commit cbcd638

Browse files
committed
Translate conditional expressions
1 parent 5ec8874 commit cbcd638

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

src/PgKeyValueDB/SqlExpressionVisitor.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -498,4 +498,18 @@ protected override Expression VisitUnary(UnaryExpression node)
498498

499499
return base.VisitUnary(node);
500500
}
501+
502+
protected override Expression VisitConditional(ConditionalExpression node)
503+
{
504+
// Translate conditional expressions (ternary operator ?: ) to PostgreSQL CASE WHEN syntax
505+
// Example: condition ? ifTrue : ifFalse becomes (case when condition then ifTrue else ifFalse end)
506+
whereClause.Append("(case when ");
507+
Visit(node.Test);
508+
whereClause.Append(" then ");
509+
Visit(node.IfTrue);
510+
whereClause.Append(" else ");
511+
Visit(node.IfFalse);
512+
whereClause.Append(" end)");
513+
return node;
514+
}
501515
}

test/PgKeyValueDB.Tests/PgKeyValueDBTest.cs

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@ public class Address
3535
public int ZipCode { get; set; }
3636
}
3737

38+
public class User
39+
{
40+
public string? DataType { get; set; }
41+
public string? Email { get; set; }
42+
public string? Phone { get; set; }
43+
public string? Username { get; set; }
44+
public string? UserId { get; set; }
45+
}
46+
3847
public class UserProfile : UserProfileBase1
3948
{
4049
public override string? Id { get; set; } // Add this line
@@ -866,4 +875,99 @@ public async Task FilterWithExtensionMethodIsNullOrWhiteSpaceTest()
866875
var result6 = await kv.GetListAsync(pid, query6).ToListAsync();
867876
Assert.AreEqual(2, result6.Count, "Static method should find Bob and Charlie (null/empty DisplayName)");
868877
}
878+
879+
[TestMethod]
880+
public async Task ComplexConditionalExpressionTest()
881+
{
882+
var pid = nameof(ComplexConditionalExpressionTest);
883+
var key1 = pid + "1";
884+
var key2 = pid + "2";
885+
var key3 = pid + "3";
886+
887+
var user1 = new User
888+
{
889+
DataType = "Employee",
890+
Email = "[email protected]",
891+
Phone = "123-456-7890",
892+
Username = "alice123",
893+
UserId = "user001"
894+
};
895+
896+
var user2 = new User
897+
{
898+
DataType = "Employee",
899+
Email = "[email protected]",
900+
Phone = "987-654-3210",
901+
Username = "bobuser",
902+
UserId = "user002"
903+
};
904+
905+
var user3 = new User
906+
{
907+
DataType = "Customer",
908+
Email = "[email protected]",
909+
Phone = "555-123-4567",
910+
Username = "charlie_c",
911+
UserId = "user003"
912+
};
913+
914+
await kv.UpsertAsync(key1, user1, pid);
915+
await kv.UpsertAsync(key2, user2, pid);
916+
await kv.UpsertAsync(key3, user3, pid);
917+
918+
// Test variables matching the upstream pattern
919+
bool queryFilters = true;
920+
string UserDataType = "Employee";
921+
string filterEmail = "alice";
922+
string filterPhone = "";
923+
string filterUsername = "";
924+
string filterUserId = "";
925+
926+
// This expression mirrors the upstream code that causes the PostgreSQL syntax error
927+
Expression<Func<User, bool>> whereQuery = u => !queryFilters ? u.DataType!.Equals(UserDataType) :
928+
u.DataType!.Equals(UserDataType) && (
929+
(!string.IsNullOrWhiteSpace(filterEmail) && u.Email!.Contains(filterEmail, StringComparison.CurrentCultureIgnoreCase)) ||
930+
(!string.IsNullOrWhiteSpace(filterPhone) && u.Phone!.Contains(filterPhone, StringComparison.CurrentCultureIgnoreCase)) ||
931+
(!string.IsNullOrWhiteSpace(filterUsername) && u.Username!.Contains(filterUsername, StringComparison.CurrentCultureIgnoreCase)) ||
932+
(!string.IsNullOrWhiteSpace(filterUserId) && u.UserId!.Contains(filterUserId, StringComparison.CurrentCultureIgnoreCase))
933+
);
934+
935+
// This should trigger the PostgreSQL syntax error at position 142
936+
var users = await kv.GetListAsync(pid, whereQuery).ToListAsync();
937+
938+
// If the test passes, we expect to find [email protected]
939+
Assert.AreEqual(1, users.Count);
940+
Assert.AreEqual("[email protected]", users[0].Email);
941+
}
942+
943+
[TestMethod]
944+
public async Task SimpleConditionalExpressionTest()
945+
{
946+
var pid = nameof(SimpleConditionalExpressionTest);
947+
var key1 = pid + "1";
948+
949+
var user1 = new User
950+
{
951+
DataType = "Employee",
952+
Email = "[email protected]",
953+
Phone = "123-456-7890",
954+
Username = "alice123",
955+
UserId = "user001"
956+
};
957+
958+
await kv.UpsertAsync(key1, user1, pid);
959+
960+
// Simple conditional expression that should trigger the PostgreSQL syntax error
961+
bool useSimpleFilter = false;
962+
string targetDataType = "Employee";
963+
964+
Expression<Func<User, bool>> simpleConditional = u => useSimpleFilter ? u.DataType!.Equals("Customer") : u.DataType!.Equals(targetDataType);
965+
966+
// This should also trigger the PostgreSQL syntax error at some position
967+
var users = await kv.GetListAsync(pid, simpleConditional).ToListAsync();
968+
969+
// If the test passes, we expect to find the employee
970+
Assert.AreEqual(1, users.Count);
971+
Assert.AreEqual("[email protected]", users[0].Email);
972+
}
869973
}

0 commit comments

Comments
 (0)