Skip to content

Commit cd04590

Browse files
bahusoidfredericDelaporte
authored andcommitted
Fix NoViableAltException in delete query
1 parent 66629c2 commit cd04590

File tree

4 files changed

+40
-3
lines changed

4 files changed

+40
-3
lines changed

src/NHibernate.Test/Async/Hql/EntityJoinHqlTest.cs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
//------------------------------------------------------------------------------
99

1010

11+
using System;
1112
using System.Text.RegularExpressions;
1213
using NHibernate.Cfg.MappingSchema;
1314
using NHibernate.Mapping.ByCode;
@@ -233,6 +234,21 @@ public async Task NullablePropRefWhereIdEntityNotNullShouldAddJoinAsync()
233234
}
234235
}
235236

237+
[Test(Description = "GH-2688")]
238+
public async Task NullableManyToOneDeleteQueryAsync()
239+
{
240+
using (var session = OpenSession())
241+
{
242+
await (session
243+
.CreateQuery(
244+
"delete "
245+
+ "from NullableOwner ex "
246+
+ "where ex.ManyToOne.id = :id"
247+
).SetParameter("id", Guid.Empty)
248+
.ExecuteUpdateAsync());
249+
}
250+
}
251+
236252
[Test]
237253
public async Task NullableOneToOneFetchQueryIsNotAffectedAsync()
238254
{
@@ -515,6 +531,7 @@ protected override HbmMapping GetMappings()
515531
m.ForeignKey("none");
516532
m.NotFound(NotFoundMode.Ignore);
517533
});
534+
rc.ManyToOne(e => e.ManyToOne, m => m.NotFound(NotFoundMode.Ignore));
518535
});
519536

520537

src/NHibernate.Test/Hql/EntityJoinHqlTest.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System.Text.RegularExpressions;
1+
using System;
2+
using System.Text.RegularExpressions;
23
using NHibernate.Cfg.MappingSchema;
34
using NHibernate.Mapping.ByCode;
45
using NHibernate.Test.Hql.EntityJoinHqlTestEntities;
@@ -222,6 +223,21 @@ public void NullablePropRefWhereIdEntityNotNullShouldAddJoin()
222223
}
223224
}
224225

226+
[Test(Description = "GH-2688")]
227+
public void NullableManyToOneDeleteQuery()
228+
{
229+
using (var session = OpenSession())
230+
{
231+
session
232+
.CreateQuery(
233+
"delete "
234+
+ "from NullableOwner ex "
235+
+ "where ex.ManyToOne.id = :id"
236+
).SetParameter("id", Guid.Empty)
237+
.ExecuteUpdate();
238+
}
239+
}
240+
225241
[Test]
226242
public void NullableOneToOneFetchQueryIsNotAffected()
227243
{
@@ -520,6 +536,7 @@ protected override HbmMapping GetMappings()
520536
m.ForeignKey("none");
521537
m.NotFound(NotFoundMode.Ignore);
522538
});
539+
rc.ManyToOne(e => e.ManyToOne, m => m.NotFound(NotFoundMode.Ignore));
523540
});
524541

525542

src/NHibernate.Test/Hql/EntityJoinHqlTestEntities.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public class NullableOwner
3131
public virtual string Name { get; set; }
3232
public virtual OneToOneEntity OneToOne { get; set; }
3333
public virtual PropRefEntity PropRef { get; set; }
34+
public virtual OneToOneEntity ManyToOne { get; set; }
3435
}
3536

3637
public class EntityWithCompositeId

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,9 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
386386
string property = _propertyName;
387387
bool joinIsNeeded;
388388

389-
//For nullable entity comparisons we always need to add join (like not constrained one-to-one or not-found ignore associations)
389+
//For nullable entity comparisons we always need to add join (like not constrained one-to-one or not-found ignore associations)
390+
//NOTE: This fix is not fully correct. It doesn't work for comparisons with null (where e.OneToOneProp is null)
391+
// as by default implicit join is generated and to work propelry left join is required (see GH-2611)
390392
bool comparisonWithNullableEntity = false;
391393

392394
if ( IsDotNode( parent ) )
@@ -396,7 +398,7 @@ private void DereferenceEntity(EntityType entityType, bool implicitJoin, string
396398
// entity's PK (because 'our' table would know the FK).
397399
parentAsDotNode = ( DotNode ) parent;
398400
property = parentAsDotNode._propertyName;
399-
joinIsNeeded = generateJoin && (entityType.IsNullable || !IsReferenceToPrimaryKey( parentAsDotNode._propertyName, entityType ));
401+
joinIsNeeded = generateJoin && ((Walker.IsSelectStatement && entityType.IsNullable) || !IsReferenceToPrimaryKey( parentAsDotNode._propertyName, entityType ));
400402
}
401403
else if ( ! Walker.IsSelectStatement )
402404
{

0 commit comments

Comments
 (0)