Skip to content

Commit

Permalink
[#602] Test and fix for NPE that appears after copying query builder …
Browse files Browse the repository at this point in the history
…using parameter multiple times in select clause. Fixes #602
  • Loading branch information
beikov committed Jul 19, 2018
1 parent 88f836c commit 0f5d09a
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 4 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@ Not yet released

* Add support for providing entity view optional parameters in spring-data repositories via `@OptionalParam`
* Introduced `EMBEDDING_VIEW` function as proper replacement for many `OUTER` function uses in entity views
* Smoothen support for embeddables in updatable entity views
* Improve performance by omitting null precedence emulation on MySQL for the default null precedence

### Bug fixes

None
* Fix for `NullPointerException` that happened during query builder copying when having a parameter multiple times in a select clause

### Backwards-incompatible changes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,9 +261,11 @@ private Integer determinePositionalOffset(String parameterName) {

public void unregisterParameterName(String parameterName, ClauseType clauseType) {
ParameterImpl<?> parameter = parameters.get(parameterName);
parameter.getClauseTypes().remove(clauseType);
if (parameter.getClauseTypes().isEmpty()) {
parameters.remove(parameterName);
if (parameter != null) {
parameter.getClauseTypes().remove(clauseType);
if (parameter.getClauseTypes().isEmpty()) {
parameters.remove(parameterName);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.blazebit.persistence.impl;

import com.blazebit.persistence.parser.expression.ArrayExpression;
import com.blazebit.persistence.parser.expression.ParameterExpression;
import com.blazebit.persistence.parser.expression.VisitorAdapter;

Expand All @@ -28,6 +29,7 @@ public class ParameterRegistrationVisitor extends VisitorAdapter {

private final ParameterManager parameterManager;
private ClauseType clauseType;
private ClauseType secondClauseType;

public ParameterRegistrationVisitor(ParameterManager parameterManager) {
this.parameterManager = parameterManager;
Expand All @@ -40,9 +42,22 @@ public void visit(ParameterExpression expression) {
throw new IllegalArgumentException("The parameter name '" + expression.getName() + "' is reserved - use a different name");
} else {
parameterManager.registerParameterName(expression.getName(), expression.isCollectionValued(), clauseType);
if (secondClauseType != null) {
parameterManager.registerParameterName(expression.getName(), expression.isCollectionValued(), secondClauseType);
}
}
}

@Override
public void visit(ArrayExpression expression) {
expression.getBase().accept(this);
// The index will always end up in the on clause
ClauseType oldClauseType = secondClauseType;
secondClauseType = ClauseType.JOIN;
expression.getIndex().accept(this);
secondClauseType = oldClauseType;
}

public void setClauseType(ClauseType clauseType) {
this.clauseType = clauseType;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright 2014 - 2018 Blazebit.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.blazebit.persistence.testsuite;

import com.blazebit.persistence.testsuite.entity.Document;
import org.junit.Test;

/**
* @author Christian Beikov
* @since 1.3.0
*/
public class QueryBuilderCopyTest extends AbstractCoreTest {

@Test
// Test for issue #602
public void testQueryCopying() {
// The key to reproducing the bug is having the parameter in the select clause multiple times
cbf.create(em, Long.class)
.from(Document.class)
.select("COALESCE(id,:param3)")
.select("COALESCE(id,:param3)")
.copy(String.class)
.select("name");
}
}

0 comments on commit 0f5d09a

Please sign in to comment.