Skip to content

Commit

Permalink
Fix ordinal bind parameter binding to fix SQLLoaderTest testComposite…
Browse files Browse the repository at this point in the history
…IdId.
  • Loading branch information
Naros authored and sebersole committed May 6, 2016
1 parent 33c4f3b commit c10c006
Showing 1 changed file with 87 additions and 17 deletions.
Expand Up @@ -40,6 +40,7 @@
* Manages the group of QueryParameterBinding for a particular query.
*
* @author Steve Ebersole
* @author Chris Cranford
*/
@Incubating
public class QueryParameterBindingsImpl implements QueryParameterBindings {
Expand All @@ -49,6 +50,7 @@ public class QueryParameterBindingsImpl implements QueryParameterBindings {

private Map<QueryParameter, QueryParameterBinding> parameterBindingMap;
private Map<QueryParameter, QueryParameterListBinding> parameterListBindingMap;
private Map<QueryParameter, QueryParameterBinding> positionParameterBindingMap;

public static QueryParameterBindingsImpl from(ParameterMetadata parameterMetadata, SessionFactoryImplementor sessionFactory) {
if ( parameterMetadata == null ) {
Expand All @@ -65,6 +67,7 @@ public QueryParameterBindingsImpl(SessionFactoryImplementor sessionFactory) {

public QueryParameterBindingsImpl(SessionFactoryImplementor sessionFactory, Set<QueryParameter<?>> queryParameters) {
this.sessionFactory = sessionFactory;
this.positionParameterBindingMap = new HashMap<>();

if ( queryParameters == null || queryParameters.isEmpty() ) {
parameterBindingMap = Collections.emptyMap();
Expand Down Expand Up @@ -165,12 +168,28 @@ protected QueryParameterBinding locateAndRemoveBinding(String name) {
}

protected QueryParameterBinding locateBinding(int position) {
Map.Entry<QueryParameter, QueryParameterBinding> entry = locateBindingEntry( position );
if ( entry != null ) {
return entry.getValue();
}
return null;
}

protected Map.Entry<QueryParameter, QueryParameterBinding> locateBindingEntry(int position) {
for ( Map.Entry<QueryParameter, QueryParameterBinding> entry : parameterBindingMap.entrySet() ) {
if ( entry.getKey().getPosition() != null && position == entry.getKey().getPosition() ) {
return entry.getValue();
return entry;
}
}
return null;
}

protected Map.Entry<QueryParameter, QueryParameterBinding> locatePositionBinding(int position) {
for ( Map.Entry<QueryParameter, QueryParameterBinding> entry : positionParameterBindingMap.entrySet() ) {
if ( entry.getKey().getPosition() != null && position == entry.getKey().getPosition() ) {
return entry;
}
}
return null;
}

Expand All @@ -184,28 +203,79 @@ public QueryParameterBinding getBinding(String name) {
}

public QueryParameterBinding getBinding(int position) {
final QueryParameterBinding binding = locateBinding( position );
if ( binding == null ) {
throw new IllegalArgumentException( "Unknown parameter position : " + position );
// locate cached binding by position (cached only after getBinding(int) called)
Map.Entry<QueryParameter, QueryParameterBinding> bindingEntry = locatePositionBinding( position );
if ( bindingEntry == null ) {
bindingEntry = locateBindingEntry( position );
// cache the bind position mapping
positionParameterBindingMap.put( bindingEntry.getKey(), bindingEntry.getValue() );
}

return binding;
if ( bindingEntry == null ) {
throw new IllegalArgumentException( "Unknown parameter position: " + position );
}
return bindingEntry.getValue();
}

public void verifyParametersBound(boolean reserveFirstParameter) {
for ( Map.Entry<QueryParameter, QueryParameterBinding> bindEntry : parameterBindingMap.entrySet() ) {
if ( !bindEntry.getValue().isBound() ) {
if ( bindEntry.getKey().getName() != null ) {
throw new QueryException( "Named parameter [" + bindEntry.getKey().getName() + "] not set" );
if ( bindEntry.getKey().getPosition() == null ) {
if ( !bindEntry.getValue().isBound() ) {
if ( bindEntry.getKey().getName() != null ) {
throw new QueryException( "Named parameter [" + bindEntry.getKey().getName() + "] not set" );
}
else {
throw new QueryException( "Parameter memento [" + bindEntry.getKey() + "] not set" );
}
}
else if ( bindEntry.getKey().getPosition() != null ) {
throw new QueryException( "Positional parameter [" + bindEntry.getKey().getPosition() + "] not set" );
}
}

final int positionalValueSpan = getPositionalValueSpan( reserveFirstParameter );
final int positionCounts = getPositionalParameterCount();

if ( positionCounts != positionalValueSpan ) {
if ( reserveFirstParameter && positionCounts - 1 != positionalValueSpan ) {
throw new QueryException(
"Expected positional parameter count: " +
( positionCounts - 1 ) +
", actually detected " + positionalValueSpan
);
}
else if ( !reserveFirstParameter ) {
throw new QueryException(
"Expected positional parameter count: " +
( positionCounts ) +
", actually detected " + positionalValueSpan
);
}
}
}

private int getPositionalValueSpan(boolean reserveFirstParameter) {
int positionalValueSpan = 0;
for ( QueryParameterBinding binding : positionParameterBindingMap.values() ) {
if ( binding.isBound() ) {
Type bindType = binding.getBindType();
if ( bindType != null ) {
Object object = binding.getBindValue();
positionalValueSpan += bindType.getColumnSpan( sessionFactory );
}
else {
throw new QueryException( "Parameter memento [" + bindEntry.getKey() + "] not set" );
positionalValueSpan += 1;
}
}
}
return positionalValueSpan;
}

private int getPositionalParameterCount() {
int count = 0;
for( QueryParameter queryParameter : parameterBindingMap.keySet() ) {
if ( queryParameter.getPosition() != null ) {
count++;
}
}
return count;
}

/**
Expand Down Expand Up @@ -263,11 +333,11 @@ private TreeMap<Integer, QueryParameterBinding> collectPositionalParameterBindin
if ( entry.getKey().getPosition() == null ) {
continue;
}

final int position = entry.getKey().getPosition();

// these should be contiguous
bindings.put( position, entry.getValue() );
// only add those which have been cached
if ( positionParameterBindingMap.containsKey( entry.getKey() ) ) {
// these should be contiguous
bindings.put( entry.getKey().getPosition(), entry.getValue() );
}
}

return bindings;
Expand Down

0 comments on commit c10c006

Please sign in to comment.