Skip to content

Commit

Permalink
jakartaee/persistence#440 - add support for 'nulls first' and 'nulls …
Browse files Browse the repository at this point in the history
…last' in queries

Signed-off-by: Tomáš Kraus <tomas.kraus@oracle.com>
  • Loading branch information
Tomas-Kraus authored and lukasj committed Oct 17, 2023
1 parent 2b5bf90 commit c899623
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -168,47 +168,32 @@ public CompoundSelection<Object[]> array(Selection<?>... selections){
return new CompoundSelectionImpl(ClassConstants.AOBJECT, selections, true);
}

/**
* Create an ordering by the ascending value of the expression.
*
* @param x
* expression used to define the ordering
* @return ascending ordering corresponding to the expression
*/
@Override
public Order asc(Expression<?> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new OrderImpl(x);
public Order asc(Expression<?> expression) {
return asc(expression, Nulls.NONE);
}

// TODO-API-3.2
// TODO-API-3.2 - Nulls added to OrderImpl and ObjectLevelReadQuery in CriteriaQueryImpl, but no tests exist
@Override
public Order asc(Expression<?> expression, Nulls nullPrecedence) {
throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet");
if (((InternalSelection)expression).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new OrderImpl(expression, true, nullPrecedence);
}

/**
* Create an ordering by the descending value of the expression.
*
* @param x
* expression used to define the ordering
* @return descending ordering corresponding to the expression
*/
@Override
public Order desc(Expression<?> x){
if (((InternalSelection)x).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
OrderImpl order = new OrderImpl(x, false);
return order;
public Order desc(Expression<?> expression){
return desc(expression, Nulls.NONE);
}

// TODO-API-3.2
// TODO-API-3.2 - Nulls added to OrderImpl and ObjectLevelReadQuery in CriteriaQueryImpl, but no tests exist
@Override
public Order desc(Expression<?> expression, Nulls nullPrecedence) {
throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet");
if (((InternalSelection)expression).getCurrentNode() == null){
throw new IllegalArgumentException(ExceptionLocalization.buildMessage("OPERATOR_EXPRESSION_IS_CONJUNCTION"));
}
return new OrderImpl(expression, false, nullPrecedence);
}

// aggregate functions:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -723,11 +723,15 @@ public DatabaseQuery translate() {
if (this.orderBy != null && !this.orderBy.isEmpty()) {
for (Order order : this.orderBy) {
OrderImpl orderImpl = (OrderImpl) order;
org.eclipse.persistence.expressions.Expression orderExp = ((ExpressionImpl) orderImpl.getExpression()).getCurrentNode();
if (orderImpl.isAscending()) {
orderExp = orderExp.ascending();
} else {
orderExp = orderExp.descending();
org.eclipse.persistence.expressions.Expression orderExp = ((ExpressionImpl<?>) orderImpl.getExpression()).getCurrentNode();
orderExp = orderImpl.isAscending() ? orderExp.ascending() : orderExp.descending();
switch (orderImpl.getNullPrecedence()) {
case FIRST:
orderExp = orderExp.nullsFirst();
break;
case LAST:
orderExp = orderExp.nullsLast();
break;
}
query.addOrdering(orderExp);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@

// Contributors:
// Gordon Yorke - Initial development
//
// 08/31/2023: Tomas Kraus
// - New Jakarta Persistence 3.2 Features
package org.eclipse.persistence.internal.jpa.querydef;

import java.io.Serializable;
Expand All @@ -21,18 +22,26 @@
import jakarta.persistence.criteria.Nulls;
import jakarta.persistence.criteria.Order;

/**
* An object that defines an ordering over the query results.
*/
public class OrderImpl implements Order, Serializable{

protected Expression expression;
protected boolean isAscending;
protected Nulls nullPrecedence;

public OrderImpl(Expression expression){
this(expression, true);
}

public OrderImpl(Expression expression, boolean isAscending){
/**
* Creates an instance of ordering over the query results definition.
*
* @param expression the query expression
* @param isAscending whether ascending ordering is in effect
* @param nullPrecedence the precedence of {@code null} values within query result sets
*/
public OrderImpl(Expression expression, boolean isAscending, Nulls nullPrecedence) {
this.expression = expression;
this.isAscending = isAscending;
this.nullPrecedence = nullPrecedence;
}

@Override
Expand All @@ -48,12 +57,12 @@ public boolean isAscending() {
// TODO-API-3.2
@Override
public Nulls getNullPrecedence() {
throw new UnsupportedOperationException("Jakarta Persistence 3.2 API was not implemented yet");
return nullPrecedence;
}

@Override
public Order reverse() {
return new OrderImpl(this.expression, false);
return new OrderImpl(expression, !isAscending, nullPrecedence);
}

public void findRootAndParameters(CommonAbstractCriteriaImpl query) {
Expand Down

0 comments on commit c899623

Please sign in to comment.