Skip to content

Commit

Permalink
Fix NH-3142 by having the JoinWalker avoid reusing Parameter instance…
Browse files Browse the repository at this point in the history
…s. Parameter instances are later assigned a value to their BackTrack property. If the same instance is used in multiple positions the BackTracks will be incorrect, since all occurrences will get the same BackTrack and therefore the same value. But in this situation, they really do represent separate values.
  • Loading branch information
oskarb committed May 26, 2012
1 parent f31be36 commit a35aaa6
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 15 deletions.
30 changes: 15 additions & 15 deletions src/NHibernate/Loader/JoinWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -772,29 +772,29 @@ protected SqlStringBuilder WhereString(string alias, string[] columnNames, int b
}
else
{
Parameter[] columnParameters = Parameter.GenerateParameters(columnNames.Length);
ConditionalFragment byId = new ConditionalFragment()
.SetTableAlias(alias)
.SetCondition(columnNames, columnParameters);
var fragments = new ConditionalFragment[batchSize];
for (int i = 0; i < batchSize; i++)
{
fragments[i] = new ConditionalFragment()
.SetTableAlias(alias)
.SetCondition(columnNames, Parameter.GenerateParameters(columnNames.Length));
}

SqlStringBuilder whereString = new SqlStringBuilder();
var whereString = new SqlStringBuilder();

if (batchSize == 1)
if (fragments.Length == 1)
{
// if no batch, use "foo = ? and bar = ?"
whereString.Add(byId.ToSqlStringFragment());
whereString.Add(fragments[0].ToSqlStringFragment());
}
else
{
// if a composite key, use "( (foo = ? and bar = ?) or (foo = ? and bar = ?) )" for batching
whereString.Add(StringHelper.OpenParen); // TODO: unnecessary for databases with ANSI-style joins
DisjunctionFragment df = new DisjunctionFragment();
for (int i = 0; i < batchSize; i++)
{
df.AddCondition(byId);
}
// if batching, use "( (foo = ? and bar = ?) or (foo = ? and bar = ?) )"
var df = new DisjunctionFragment(fragments);

whereString.Add(StringHelper.OpenParen);
whereString.Add(df.ToFragmentString());
whereString.Add(StringHelper.ClosedParen); // TODO: unnecessary for databases with ANSI-style joins
whereString.Add(StringHelper.ClosedParen);
}

return whereString;
Expand Down
13 changes: 13 additions & 0 deletions src/NHibernate/SqlCommand/DisjunctionFragment.cs
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
using System;
using System.Collections.Generic;

namespace NHibernate.SqlCommand
{
public class DisjunctionFragment
{
private SqlStringBuilder buffer = new SqlStringBuilder();

public DisjunctionFragment()
{
}


public DisjunctionFragment(IEnumerable<ConditionalFragment> fragments)
{
foreach (var conditionalFragment in fragments)
AddCondition(conditionalFragment);
}


public DisjunctionFragment AddCondition(ConditionalFragment fragment)
{
if (buffer.Count > 0)
Expand Down

0 comments on commit a35aaa6

Please sign in to comment.