Skip to content

Commit 6017fdc

Browse files
authored
Use inner join instead of implicit join for implied entity joins (#2990)
1 parent 08df7ba commit 6017fdc

File tree

15 files changed

+60
-34
lines changed

15 files changed

+60
-34
lines changed

.github/workflows/NetCoreTests.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ jobs:
1515
- DB: Firebird
1616
CONNECTION_STRING: "DataSource=localhost;Database=nhibernate;User=SYSDBA;Password=nhibernate;charset=utf8;"
1717
- DB: MySQL
18-
CONNECTION_STRING: "Server=localhost;Uid=root;Password=nhibernate;Database=nhibernate;Old Guids=True;"
18+
CONNECTION_STRING: "Server=localhost;Uid=root;Password=nhibernate;Database=nhibernate;Old Guids=True;SslMode=none;"
1919
- DB: Oracle
2020
CONNECTION_STRING: "User ID=nhibernate;Password=nhibernate;Metadata Pooling=false;Self Tuning=false;Data Source=(DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = XEPDB1)))"
2121
- DB: SQLite

build-common/NHibernate.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<VersionPatch Condition="'$(VersionPatch)' == ''">0</VersionPatch>
77
<!-- Clear VersionSuffix for making release and set it to dev for making development builds -->
88
<VersionSuffix Condition="'$(VersionSuffix)' == ''">dev</VersionSuffix>
9+
<LangVersion Condition="'$(MSBuildProjectExtension)' != '.vbproj'">9.0</LangVersion>
910

1011
<VersionPrefix Condition="'$(VersionPrefix)' == ''">$(NhVersion).$(VersionPatch)</VersionPrefix>
1112
<VersionSuffix Condition="'$(VersionSuffix)' != '' AND '$(BuildNumber)' != ''">$(VersionSuffix).$(BuildNumber)</VersionSuffix>

src/NHibernate.DomainModel/Container.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ public Glarch Glarch
9292
private IDictionary<string, Ternary> _ternaryMap;
9393
//<set> mapping
9494
private ISet<Ternary> _ternarySet;
95+
private Simple _manyToOne;
9596

9697
public virtual IList<Simple> OneToMany
9798
{
@@ -129,6 +130,12 @@ public virtual long Id
129130
set { _id = value; }
130131
}
131132

133+
public virtual Simple ManyToOne
134+
{
135+
get => _manyToOne;
136+
set => _manyToOne = value;
137+
}
138+
132139
public virtual IList<Contained> Bag
133140
{
134141
get { return _bag; }

src/NHibernate.DomainModel/Container.hbm.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
>
2323
<generator class="native" />
2424
</id>
25-
25+
<many-to-one name="ManyToOne" lazy="proxy" />
2626
<list
2727
name="OneToMany"
2828
lazy="true"

src/NHibernate.Test/Async/Legacy/ParentChildTest.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -359,8 +359,8 @@ public async Task CollectionQueryAsync()
359359
if (!TestDialect.SupportsEmptyInsertsOrHasNonIdentityNativeGenerator)
360360
Assert.Ignore("Support of empty inserts is required");
361361

362-
ISession s = OpenSession();
363-
ITransaction t = s.BeginTransaction();
362+
using var s = OpenSession();
363+
using var t = s.BeginTransaction();
364364

365365
Simple s1 = new Simple();
366366
s1.Name = "s";
@@ -383,10 +383,15 @@ public async Task CollectionQueryAsync()
383383
l.Add(null);
384384
l.Add(s2);
385385
c.ManyToMany = l;
386+
c.ManyToOne = new Simple { Name = "x", Count = 4};
387+
await (s.SaveAsync(c.ManyToOne, c.ManyToOne.Count));
386388
await (s.SaveAsync(c));
387389

388390
Assert.AreEqual(1,
389391
(await (s.CreateQuery("select c from c in class ContainerX, s in class Simple where c.OneToMany[2] = s").ListAsync
392+
())).Count);
393+
Assert.AreEqual(1,
394+
(await (s.CreateQuery("select c from c in class ContainerX, s in class Simple where c.OneToMany[2] = s and c.ManyToOne.Name = 'x'").ListAsync
390395
())).Count);
391396
Assert.AreEqual(1,
392397
(await (s.CreateQuery("select c from c in class ContainerX, s in class Simple where c.ManyToMany[2] = s").
@@ -424,13 +429,13 @@ public async Task CollectionQueryAsync()
424429
"select c from c in class ContainerX where c.ManyToMany[ c.OneToMany[0].Count ].Name = 's'").ListAsync())).
425430
Count);
426431

432+
await (s.DeleteAsync(c.ManyToOne));
427433
await (s.DeleteAsync(c));
428434
await (s.DeleteAsync(s1));
429435
await (s.DeleteAsync(s2));
430436
await (s.DeleteAsync(s3));
431437

432438
await (t.CommitAsync());
433-
s.Close();
434439
}
435440

436441
[Test]

src/NHibernate.Test/Async/NHSpecificTest/NH1444/Fixture.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ public async Task BugAsync()
3737
var message = ls.GetWholeLog();
3838
var paramFormatter = (ISqlParameterFormatter)Sfi.ConnectionProvider.Driver;
3939
Assert.That(message, Does.Contain(
40-
"xchild0_.ParentId=xparent1_.Id and (" +
41-
$"{paramFormatter.GetParameterName(0)}={Dialect.ToBooleanValueString(true)} or " +
42-
$"xparent1_.A<{paramFormatter.GetParameterName(1)})"));
40+
"on xchild0_.ParentId=xparent1_.Id").And.Contain(
41+
$"where {paramFormatter.GetParameterName(0)}={Dialect.ToBooleanValueString(true)} or " +
42+
$"xparent1_.A<{paramFormatter.GetParameterName(1)};"));
4343
}
4444
}
4545
}

src/NHibernate.Test/Legacy/ParentChildTest.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,8 @@ public void CollectionQuery()
348348
if (!TestDialect.SupportsEmptyInsertsOrHasNonIdentityNativeGenerator)
349349
Assert.Ignore("Support of empty inserts is required");
350350

351-
ISession s = OpenSession();
352-
ITransaction t = s.BeginTransaction();
351+
using var s = OpenSession();
352+
using var t = s.BeginTransaction();
353353

354354
Simple s1 = new Simple();
355355
s1.Name = "s";
@@ -372,10 +372,15 @@ public void CollectionQuery()
372372
l.Add(null);
373373
l.Add(s2);
374374
c.ManyToMany = l;
375+
c.ManyToOne = new Simple { Name = "x", Count = 4};
376+
s.Save(c.ManyToOne, c.ManyToOne.Count);
375377
s.Save(c);
376378

377379
Assert.AreEqual(1,
378380
s.CreateQuery("select c from c in class ContainerX, s in class Simple where c.OneToMany[2] = s").List
381+
().Count);
382+
Assert.AreEqual(1,
383+
s.CreateQuery("select c from c in class ContainerX, s in class Simple where c.OneToMany[2] = s and c.ManyToOne.Name = 'x'").List
379384
().Count);
380385
Assert.AreEqual(1,
381386
s.CreateQuery("select c from c in class ContainerX, s in class Simple where c.ManyToMany[2] = s").
@@ -413,13 +418,13 @@ public void CollectionQuery()
413418
"select c from c in class ContainerX where c.ManyToMany[ c.OneToMany[0].Count ].Name = 's'").List().
414419
Count);
415420

421+
s.Delete(c.ManyToOne);
416422
s.Delete(c);
417423
s.Delete(s1);
418424
s.Delete(s2);
419425
s.Delete(s3);
420426

421427
t.Commit();
422-
s.Close();
423428
}
424429

425430
[Test]

src/NHibernate.Test/NHSpecificTest/NH1444/Fixture.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ public void Bug()
2626
var message = ls.GetWholeLog();
2727
var paramFormatter = (ISqlParameterFormatter)Sfi.ConnectionProvider.Driver;
2828
Assert.That(message, Does.Contain(
29-
"xchild0_.ParentId=xparent1_.Id and (" +
30-
$"{paramFormatter.GetParameterName(0)}={Dialect.ToBooleanValueString(true)} or " +
31-
$"xparent1_.A<{paramFormatter.GetParameterName(1)})"));
29+
"on xchild0_.ParentId=xparent1_.Id").And.Contain(
30+
$"where {paramFormatter.GetParameterName(0)}={Dialect.ToBooleanValueString(true)} or " +
31+
$"xparent1_.A<{paramFormatter.GetParameterName(1)};"));
3232
}
3333
}
3434
}

src/NHibernate/Hql/Ast/ANTLR/HqlSqlWalker.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -782,7 +782,12 @@ void CreateFromJoinElement(
782782

783783
if (fromElement.Parent == null)
784784
{
785+
// Most likely means association join is used in invalid context
786+
// I.e. in subquery: from EntityA a where exists (from EntityB join a.Assocation)
787+
// Maybe we should throw exception instead
785788
fromElement.FromClause.AddChild(fromElement);
789+
if (fromElement.IsImplied)
790+
fromElement.JoinSequence.SetUseThetaStyle(true);
786791
}
787792
}
788793

src/NHibernate/Hql/Ast/ANTLR/SessionFactoryHelperExtensions.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,7 +319,6 @@ public JoinSequence CreateCollectionJoinSequence(IQueryableCollection collPersis
319319
{
320320
JoinSequence joinSequence = CreateJoinSequence();
321321
joinSequence.SetRoot(collPersister, collectionName);
322-
joinSequence.SetUseThetaStyle(true); // TODO: figure out how this should be set.
323322

324323
///////////////////////////////////////////////////////////////////////////////
325324
// This was the reason for failures regarding INDEX_OP and subclass joins on

0 commit comments

Comments
 (0)