Skip to content

Commit

Permalink
Fixes coalesce and case operators in multithreaded environments with …
Browse files Browse the repository at this point in the history
…different number of arguments

The bug is described in the issue eclipse-ee4j#2136

TestArgumentListFunctionExpressionConcurrency.java - adds tests that reproduce the bug.
ExpressionOperator.java - fixes getArgumentIndices by disabling the caching of the dynamically created argument indexes.
  • Loading branch information
Igor-Mukhin committed Sep 11, 2024
1 parent 1366628 commit a4b2894
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2618,7 +2618,7 @@ public void setArgumentIndices(int[] indices) {
}

/**
* Return the argumentIndices if set, otherwise initialize argumentIndices to the provided size
* Returns the argumentIndices if set, otherwise returns an array of indexes of the provided size.
*/
public int[] getArgumentIndices(int size) {
int[] indices = this.argumentIndices;
Expand All @@ -2630,7 +2630,11 @@ public int[] getArgumentIndices(int size) {
for (int i = 0; i < indices.length; i++) {
indices[i] = i;
}
this.argumentIndices = indices;

// NOTE: Why not cache the newly generated array of indexes like "this.argumentIndices = indices" here?
// The reason is that some operators have variable number of arguments like COALESCE and CASE WHEN.
// As instances of this class are shared between threads we cannot cache the array of indexes.

return indices;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ public void setOperator(ExpressionOperator theOperator) {
*/
@Override
public void printSQL(ExpressionSQLPrinter printer) {
ListExpressionOperator operator = (ListExpressionOperator) this.operator;

operator.setIsComplete(true);
operator.printCollection(this.children, printer);
ListExpressionOperator realOperator = (ListExpressionOperator) getPlatformOperator(printer.getPlatform());
operator.copyTo(realOperator);
realOperator.setIsComplete(true);
realOperator.printCollection(this.children, printer);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,12 @@ public void testConcurrentUseOfCoalesce() throws Exception {
runInParallel((em, i) -> {
String jpql;
if (i % 2 == 0) {
jpql = "SELECT p FROM JPQLEntity p WHERE p.string1 = coalesce(p.string2, p.string1, '" + cacheBuster(i) + "')";
} else {
jpql = "SELECT p FROM JPQLEntity p WHERE p.string1 = coalesce(p.string2, '" + cacheBuster(i) + "')";
} else {
jpql = "SELECT p FROM JPQLEntity p WHERE p.string1 = coalesce(p.string2, p.string1, '" + cacheBuster(i) + "')";
}
em.createQuery(jpql, JPQLEntity.class).getResultList();
System.out.println(Thread.currentThread().getName() + " - " + i % 2);
});
}

Expand Down

0 comments on commit a4b2894

Please sign in to comment.