Skip to content

Commit

Permalink
Switch from position to strpos for text comparisons
Browse files Browse the repository at this point in the history
Fixes npgsql#154

Both unit tests appear to only call into the `IndexOf` case in SqlBaseGenerator.cs but all three occurrences of `position` were changed just to be safe.
  • Loading branch information
Tyler Reynolds committed Apr 5, 2020
1 parent 55c1900 commit 5c04021
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 16 deletions.
40 changes: 40 additions & 0 deletions EF6.PG.Tests/EntityFrameworkBasicTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,46 @@ where p.Rating < 3
}
}

[Test]
public void Contains()
{
using (var context = new BloggingContext(ConnectionString))
{
context.Blogs.Add(new Blog
{
Name = "foo blog"
});
context.SaveChanges();
}

using (var context = new BloggingContext(ConnectionString))
{
var searchTerms = new[] { "foo", "bar" };
var matches = context.Blogs.Count(b => searchTerms.Any(t => b.Name.Contains(t)));
Assert.AreEqual(1, matches);
}
}

[Test]
public void StartsWith()
{
using (var context = new BloggingContext(ConnectionString))
{
context.Blogs.Add(new Blog
{
Name = "foo blog"
});
context.SaveChanges();
}

using (var context = new BloggingContext(ConnectionString))
{
var searchTerms = new[] { "foo", "bar" };
var matches = context.Blogs.Count(b => searchTerms.Any(t => b.Name.StartsWith(t)));
Assert.AreEqual(1, matches);
}
}

[Test]
public void SelectWithWhere_Ef_TruncateTime()
{
Expand Down
25 changes: 9 additions & 16 deletions EF6.PG/SqlGenerators/SqlBaseGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -935,7 +935,6 @@ VisitedExpression VisitFunction(EdmFunction function, IList<DbExpression> args,
{
if (function.NamespaceName == "Edm")
{
VisitedExpression arg;
switch (function.Name)
{
// string functions
Expand All @@ -944,21 +943,17 @@ VisitedExpression VisitFunction(EdmFunction function, IList<DbExpression> args,
return OperatorExpression.Build(Operator.Concat, _useNewPrecedences, args[0].Accept(this), args[1].Accept(this));
case "Contains":
Debug.Assert(args.Count == 2);
var contains = new FunctionExpression("position");
arg = args[1].Accept(this);
arg.Append(" in ");
arg.Append(args[0].Accept(this));
contains.AddArgument(arg);
var contains = new FunctionExpression("strpos");
contains.AddArgument(args[0].Accept(this));
contains.AddArgument(args[1].Accept(this));
// if position returns zero, then contains is false
return OperatorExpression.Build(Operator.GreaterThan, _useNewPrecedences, contains, new LiteralExpression("0"));
// case "EndsWith": - depends on a reverse function to be able to implement with parameterized queries
case "IndexOf":
Debug.Assert(args.Count == 2);
var indexOf = new FunctionExpression("position");
arg = args[0].Accept(this);
arg.Append(" in ");
arg.Append(args[1].Accept(this));
indexOf.AddArgument(arg);
var indexOf = new FunctionExpression("strpos");
indexOf.AddArgument(args[1].Accept(this));
indexOf.AddArgument(args[0].Accept(this));
return indexOf;
case "Left":
Debug.Assert(args.Count == 2);
Expand Down Expand Up @@ -995,11 +990,9 @@ VisitedExpression VisitFunction(EdmFunction function, IList<DbExpression> args,
return Substring(args[0].Accept(this), args[1].Accept(this), args[2].Accept(this));
case "StartsWith":
Debug.Assert(args.Count == 2);
var startsWith = new FunctionExpression("position");
arg = args[1].Accept(this);
arg.Append(" in ");
arg.Append(args[0].Accept(this));
startsWith.AddArgument(arg);
var startsWith = new FunctionExpression("strpos");
startsWith.AddArgument(args[0].Accept(this));
startsWith.AddArgument(args[1].Accept(this));
return OperatorExpression.Build(Operator.Equals, _useNewPrecedences, startsWith, new LiteralExpression("1"));
case "ToLower":
return StringModifier("lower", args);
Expand Down

0 comments on commit 5c04021

Please sign in to comment.