You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ignite.apache.org by pt...@apache.org on 2017/11/17 09:52:48 UTC
ignite git commit: IGNITE-6907 .NET: Fix LINQ multitable conditional
joins
Repository: ignite
Updated Branches:
refs/heads/master 69eced659 -> 1ebeee00e
IGNITE-6907 .NET: Fix LINQ multitable conditional joins
This closes #3049
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo
Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/1ebeee00
Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/1ebeee00
Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/1ebeee00
Branch: refs/heads/master
Commit: 1ebeee00e96f18fab851930e672525a62c29fdd0
Parents: 69eced6
Author: Alexey Popov <ta...@gmail.com>
Authored: Fri Nov 17 12:52:38 2017 +0300
Committer: Pavel Tupitsyn <pt...@apache.org>
Committed: Fri Nov 17 12:52:38 2017 +0300
----------------------------------------------------------------------
.../Cache/Query/Linq/CacheLinqTest.Base.cs | 3 +-
.../Cache/Query/Linq/CacheLinqTest.Join.cs | 110 +++++++++++++++++--
.../Cache/Query/Linq/CacheLinqTest.Misc.cs | 11 +-
.../Impl/CacheQueryModelVisitor.cs | 28 ++++-
4 files changed, 133 insertions(+), 19 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/ignite/blob/1ebeee00/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Base.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Base.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Base.cs
index ae9fd5f..9132de7 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Base.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Base.cs
@@ -295,7 +295,8 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
var persons = GetPersonCache().AsCacheQueryable();
var res = persons
- .Select(x => new {Foo = x.Key % 2 == 0 ? even : odd, x.Value})
+ .Select(x => new { x.Key, Foo = x.Key % 2 == 0 ? even : odd, x.Value })
+ .OrderBy(x => x.Key)
.ToArray();
if (comparer != null)
http://git-wip-us.apache.org/repos/asf/ignite/blob/1ebeee00/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Join.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Join.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Join.cs
index f589329..4192fb0 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Join.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Join.cs
@@ -85,6 +85,23 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
}
/// <summary>
+ /// Tests the multi key join inline
+ /// </summary>
+ [Test]
+ public void TestMultiKeyJoinInline()
+ {
+ var organizations = GetOrgCache().AsCacheQueryable();
+ var persons = GetPersonCache().AsCacheQueryable();
+
+ var multiKey = persons.Where(p => p.Key == 1).Join(organizations,
+ p => new { OrgId = p.Value.OrganizationId, p.Key },
+ o => new { OrgId = o.Value.Id, Key = o.Key - 1000 },
+ (p, o) => new { PersonName = p.Value.Name, OrgName = o.Value.Name });
+
+ Assert.AreEqual(" Person_1 ", multiKey.Single().PersonName);
+ }
+
+ /// <summary>
/// Tests the cross cache join.
/// </summary>
[Test]
@@ -243,17 +260,23 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
[Test]
public void TestMultipleFrom()
{
- var persons = GetPersonCache().AsCacheQueryable().Where(x => x.Key < PersonCount);
- var roles = GetRoleCache().AsCacheQueryable().Where(x => x.Value.Name != "1");
-
- var all = persons.SelectMany(person => roles.Select(role => new { role, person }));
- Assert.AreEqual(RoleCount * PersonCount, all.Count());
+ var persons = GetPersonCache().AsCacheQueryable();
+ var roles = GetRoleCache().AsCacheQueryable();
+ var organizations = GetOrgCache().AsCacheQueryable();
var filtered =
from person in persons
from role in roles
- where person.Key == role.Key.Foo
- select new { Person = person.Value.Name, Role = role.Value.Name };
+ from org in organizations
+ where person.Key == role.Key.Foo && person.Value.OrganizationId == org.Value.Id
+ select new
+ {
+ PersonKey = person.Key,
+ Person = person.Value.Name,
+ RoleFoo = role.Key.Foo,
+ Role = role.Value.Name,
+ Org = org.Value.Name
+ };
var res = filtered.ToArray();
@@ -261,22 +284,85 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
}
/// <summary>
- /// Tests query with multiple from clause with inline query sources.
+ /// Tests query with two from clause.
/// </summary>
[Test]
- public void TestMultipleFromInline()
+ public void TestTwoFromSubquery()
{
+ var persons = GetPersonCache().AsCacheQueryable();
+ var roles = GetRoleCache().AsCacheQueryable();
+ var personsSubquery = persons.Where(x => x.Key < PersonCount);
+ var rolesSubquery = roles.Where(x => x.Value.Name == "Role_2");
+
var filtered =
- from person in GetPersonCache().AsCacheQueryable()
- from role in GetRoleCache().AsCacheQueryable()
+ from person in persons
+ from role in rolesSubquery
where person.Key == role.Key.Foo
- select new { Person = person.Value.Name, Role = role.Value.Name };
+ select new
+ {
+ PersonKey = person.Key, Person = person.Value.Name,
+ RoleFoo = role.Key.Foo, Role = role.Value.Name
+ };
var res = filtered.ToArray();
+ Assert.AreEqual(1, res.Length);
+
+ filtered =
+ from person in personsSubquery
+ from role in rolesSubquery
+ where person.Key == role.Key.Foo
+ select new
+ {
+ PersonKey = person.Key, Person = person.Value.Name,
+ RoleFoo = role.Key.Foo, Role = role.Value.Name
+ };
+ res = filtered.ToArray();
+ Assert.AreEqual(1, res.Length);
+
+ filtered =
+ from person in personsSubquery
+ from role in roles
+ where person.Key == role.Key.Foo
+ select new
+ {
+ PersonKey = person.Key, Person = person.Value.Name,
+ RoleFoo = role.Key.Foo, Role = role.Value.Name
+ };
+
+ res = filtered.ToArray();
Assert.AreEqual(RoleCount, res.Length);
}
+
+ /// <summary>
+ /// Tests query with two from clause.
+ /// </summary>
+ [Test]
+ public void TestMultipleFromSubquery()
+ {
+ var organizations = GetOrgCache().AsCacheQueryable().Where(x => x.Key == 1001);
+ var persons = GetPersonCache().AsCacheQueryable().Where(x => x.Key < 20);
+ var roles = GetRoleCache().AsCacheQueryable().Where(x => x.Key.Foo >= 0);
+
+ var filtered =
+ from person in persons
+ from role in roles
+ from org in organizations
+ where person.Key == role.Key.Foo && person.Value.OrganizationId == org.Value.Id
+ select new
+ {
+ PersonKey = person.Key,
+ Person = person.Value.Name,
+ RoleFoo = role.Key.Foo,
+ Role = role.Value.Name,
+ Org = org.Value.Name
+ };
+
+ var res = filtered.ToArray();
+ Assert.AreEqual(2, res.Length);
+ }
+
/// <summary>
/// Tests the join of a table to itself.
/// </summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/1ebeee00/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Misc.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Misc.cs b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Misc.cs
index c4ef11f..3585281 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Misc.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Core.Tests/Cache/Query/Linq/CacheLinqTest.Misc.cs
@@ -59,7 +59,7 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
// Multiple values
Assert.AreEqual(new[] { 0, 1, 2 },
- cache.Where(x => x.Key < 3).Select(x => x.Value.Address.Zip).ToArray());
+ cache.Where(x => x.Key < 3).OrderBy(x => x.Key).Select(x => x.Value.Address.Zip).ToArray());
// Single value
Assert.AreEqual(0, cache.Where(x => x.Key < 0).Select(x => x.Value.Age).FirstOrDefault());
@@ -313,19 +313,20 @@ namespace Apache.Ignite.Core.Tests.Cache.Query.Linq
var persons = personCache.AsCacheQueryable();
var roles = roleCache.AsCacheQueryable();
- var res = persons.Join(roles, person => person.Key - PersonCount, role => role.Key, (person, role) => role)
+ // we have role.Keys = [1, 2, 3] and persons.Key = [0, .. PersonCount)
+ var res = persons.Join(roles, person => person.Key % 2, role => role.Key, (person, role) => role)
.ToArray();
- Assert.AreEqual(res.Length, RoleCount);
+ Assert.IsTrue(PersonCount / 2 > res.Length);
// Test distributed join: returns complete results
persons = personCache.AsCacheQueryable(new QueryOptions { EnableDistributedJoins = true });
roles = roleCache.AsCacheQueryable(new QueryOptions { EnableDistributedJoins = true });
- res = persons.Join(roles, person => person.Key - PersonCount, role => role.Key, (person, role) => role)
+ res = persons.Join(roles, person => person.Key % 2, role => role.Key, (person, role) => role)
.ToArray();
- Assert.AreEqual(RoleCount, res.Length);
+ Assert.AreEqual(PersonCount / 2, res.Length);
}
/// <summary>
http://git-wip-us.apache.org/repos/asf/ignite/blob/1ebeee00/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
----------------------------------------------------------------------
diff --git a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
index 3a3e5fd..56c3ff5 100644
--- a/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
+++ b/modules/platforms/dotnet/Apache.Ignite.Linq/Impl/CacheQueryModelVisitor.cs
@@ -394,11 +394,13 @@ namespace Apache.Ignite.Linq.Impl
ValidateFromClause(fromClause);
_aliases.AppendAsClause(_builder, fromClause).Append(" ");
+ var i = 0;
foreach (var additionalFrom in queryModel.BodyClauses.OfType<AdditionalFromClause>())
{
_builder.AppendFormat(", ");
ValidateFromClause(additionalFrom);
- _aliases.AppendAsClause(_builder, additionalFrom).Append(" ");
+
+ VisitAdditionalFromClause(additionalFrom, queryModel, i++);
}
}
@@ -506,6 +508,30 @@ namespace Apache.Ignite.Linq.Impl
_builder.Append(") ");
}
+ /** <inheritdoc /> */
+ [SuppressMessage("Microsoft.Design", "CA1062:Validate arguments of public methods")]
+ public override void VisitAdditionalFromClause(AdditionalFromClause fromClause, QueryModel queryModel,
+ int index)
+ {
+ base.VisitAdditionalFromClause(fromClause, queryModel, index);
+
+ var subQuery = fromClause.FromExpression as SubQueryExpression;
+ if (subQuery != null)
+ {
+ _builder.Append("(");
+
+ VisitQueryModel(subQuery.QueryModel, true);
+
+ var alias = _aliases.GetTableAlias(subQuery.QueryModel.MainFromClause);
+ _builder.AppendFormat(") as {0} ", alias);
+ }
+ else
+ {
+ _aliases.AppendAsClause(_builder, fromClause).Append(" ");
+ }
+ }
+
+
/// <summary>
/// Visists Join clause in case of join with local collection
/// </summary>