Skip to content

Commit 67efb6c

Browse files
Merge branch 'master' into master
2 parents 6b24c04 + 6017fdc commit 67efb6c

File tree

15 files changed

+60
-34
lines changed

15 files changed

+60
-34
lines changed

.github/workflows/NetCoreTests.yml

+1-1
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

+1
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

+7
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

+1-1
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

+8-3
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

+3-3
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

+8-3
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

+3-3
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

+5
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

-1
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

src/NHibernate/Hql/Ast/ANTLR/Tree/DotNode.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -516,10 +516,8 @@ private void DereferenceEntityJoin(string classAlias, EntityType propertyType, b
516516

517517
if ( ! useFoundFromElement )
518518
{
519-
// If this is an implied join in a from element, then use the impled join type which is part of the
520-
// tree parser's state (set by the gramamar actions).
521519
JoinSequence joinSequence = SessionFactoryHelper
522-
.CreateJoinSequence(!forceLeftJoin && impliedJoin, propertyType, tableAlias, _joinType, joinColumns);
520+
.CreateJoinSequence(false, propertyType, tableAlias, _joinType, joinColumns);
523521

524522
var factory = new FromElementFactory(
525523
currentFromClause,

src/NHibernate/Hql/Ast/ANTLR/Tree/FromElement.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -590,13 +590,13 @@ public void SetOrigin(FromElement origin, bool manyToMany)
590590
}
591591
else
592592
{
593-
if (!Walker.IsInFrom && !Walker.IsInSelect)
593+
if ((IsImplied && !JoinSequence.IsThetaStyle) || Walker.IsInFrom || Walker.IsInSelect)
594594
{
595-
FromClause.AddChild(this);
595+
origin.AddChild(this);
596596
}
597597
else
598598
{
599-
origin.AddChild(this);
599+
FromClause.AddChild(this);
600600
}
601601
}
602602
}

src/NHibernate/Hql/Ast/ANTLR/Tree/FromElementFactory.cs

+18-11
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ private FromElement CreateFromElementInSubselect(
122122

123123
string tableAlias = correlatedSubselect ? fromElement.TableAlias : null;
124124

125+
//To properly generete subselect implicit join is required by SqlGenerator
126+
if (fromElement.IsImplied)
127+
fromElement.JoinSequence.SetUseThetaStyle(true);
128+
125129
// If the from element isn't in the same clause, create a new from element.
126130
if (fromElement.FromClause != _fromClause)
127131
{
@@ -189,18 +193,18 @@ public FromElement CreateCollection(IQueryableCollection queryableCollection,
189193
if (elementType.IsEntityType)
190194
{
191195
// A collection of entities...
192-
elem = CreateEntityAssociation(role, roleAlias, joinType);
196+
elem = CreateEntityAssociation(role, roleAlias, joinType, indexed);
193197
}
194198
else if (elementType.IsComponentType)
195199
{
196200
// A collection of components...
197-
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType);
201+
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType, indexed);
198202
elem = CreateCollectionJoin(joinSequence, roleAlias);
199203
}
200204
else
201205
{
202206
// A collection of scalar elements...
203-
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType);
207+
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType, indexed);
204208
elem = CreateCollectionJoin(joinSequence, roleAlias);
205209
}
206210

@@ -332,7 +336,8 @@ public FromElement CreateEntityJoin(
332336
private FromElement CreateEntityAssociation(
333337
string role,
334338
string roleAlias,
335-
JoinType joinType)
339+
JoinType joinType,
340+
bool implicitJoin)
336341
{
337342
FromElement elem;
338343
IQueryable entityPersister = (IQueryable)_queryableCollection.ElementPersister;
@@ -346,7 +351,7 @@ private FromElement CreateEntityAssociation(
346351
Log.Debug("createEntityAssociation() : One to many - path = {0} role = {1} associatedEntityName = {2}", _path, role, associatedEntityName);
347352
}
348353

349-
var joinSequence = CreateJoinSequence(roleAlias, joinType);
354+
var joinSequence = CreateJoinSequence(roleAlias, joinType, implicitJoin);
350355

351356
elem = CreateJoin(associatedEntityName, roleAlias, joinSequence, (EntityType) _queryableCollection.ElementType, false);
352357
elem.UseFromFragment |= elem.IsImplied && elem.Walker.IsSubQuery;
@@ -358,7 +363,7 @@ private FromElement CreateEntityAssociation(
358363
Log.Debug("createManyToMany() : path = {0} role = {1} associatedEntityName = {2}", _path, role, associatedEntityName);
359364
}
360365

361-
elem = CreateManyToMany(role, associatedEntityName, roleAlias, entityPersister, (EntityType)_queryableCollection.ElementType, joinType);
366+
elem = CreateManyToMany(role, associatedEntityName, roleAlias, entityPersister, (EntityType)_queryableCollection.ElementType, joinType, implicitJoin);
362367
_fromClause.Walker.AddQuerySpaces(_queryableCollection);
363368
}
364369
elem.CollectionTableAlias = roleAlias;
@@ -401,15 +406,16 @@ private FromElement CreateManyToMany(
401406
string roleAlias,
402407
IEntityPersister entityPersister,
403408
EntityType type,
404-
JoinType joinType)
409+
JoinType joinType,
410+
bool implicitJoin)
405411
{
406412
FromElement elem;
407413
SessionFactoryHelperExtensions sfh = _fromClause.SessionFactoryHelper;
408414

409415
if (_inElementsFunction /*implied*/ )
410416
{
411417
// For implied many-to-many, just add the end join.
412-
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType);
418+
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType, implicitJoin);
413419
elem = CreateJoin(associatedEntityName, roleAlias, joinSequence, type, true);
414420
}
415421
else
@@ -421,23 +427,24 @@ private FromElement CreateManyToMany(
421427
string[] secondJoinColumns = sfh.GetCollectionElementColumns(role, roleAlias);
422428

423429
// Add the second join, the one that ends in the destination table.
424-
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType);
430+
JoinSequence joinSequence = CreateJoinSequence(roleAlias, joinType, implicitJoin);
425431
joinSequence.AddJoin(sfh.GetElementAssociationType(_collectionType), tableAlias, joinType, secondJoinColumns);
426432
elem = CreateJoin(associatedEntityName, tableAlias, joinSequence, type, false);
427433
elem.UseFromFragment = true;
428434
}
429435
return elem;
430436
}
431437

432-
private JoinSequence CreateJoinSequence(string roleAlias, JoinType joinType)
438+
//TODO: Investigate why not implicit indexed collection join is incorrectly generated and get rid of implicitJoin parameter (check IndexNode.Resolve)
439+
private JoinSequence CreateJoinSequence(string roleAlias, JoinType joinType, bool implicitJoin)
433440
{
434441
SessionFactoryHelperExtensions sessionFactoryHelper = _fromClause.SessionFactoryHelper;
435442
string[] joinColumns = Columns;
436443
if (_collectionType == null)
437444
{
438445
throw new InvalidOperationException("collectionType is null!");
439446
}
440-
return sessionFactoryHelper.CreateJoinSequence(_implied, _collectionType, roleAlias, joinType, joinColumns);
447+
return sessionFactoryHelper.CreateJoinSequence(implicitJoin, _collectionType, roleAlias, joinType, joinColumns);
441448
}
442449

443450
private FromElement CreateJoin(

src/NHibernate/Hql/CollectionSubqueryFactory.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.Text;
44
using NHibernate.Engine;
55
using NHibernate.SqlCommand;
6-
using NHibernate.Util;
76

87
namespace NHibernate.Hql
98
{
@@ -16,6 +15,7 @@ public static string CreateCollectionSubquery(
1615
{
1716
try
1817
{
18+
joinSequence.SetUseThetaStyle(true);
1919
JoinFragment join = joinSequence.ToJoinFragment(enabledFilters, true);
2020
return new StringBuilder()
2121
.Append("select ")

src/NHibernate/NHibernate.csproj

-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
<PackageDescription>NHibernate is a mature, open source object-relational mapper for the .NET framework. It is actively developed, fully featured and used in thousands of successful projects.</PackageDescription>
1414
<PackageTags>ORM; O/RM; DataBase; DAL; ObjectRelationalMapping; NHibernate; ADO.Net; Core</PackageTags>
15-
<LangVersion>7.3</LangVersion>
1615
</PropertyGroup>
1716

1817
<ItemGroup>

0 commit comments

Comments
 (0)