Skip to content

Commit

Permalink
Fixed Blazebit#312 - Added inheritance mappings for entity views, all…
Browse files Browse the repository at this point in the history
…owed case when without else
  • Loading branch information
beikov committed Apr 24, 2017
1 parent 95c975f commit 60d2a7e
Show file tree
Hide file tree
Showing 115 changed files with 5,261 additions and 557 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ private static boolean isUnique(EntityMetamodel metamodel, SubqueryExpression ex
}

private static boolean isUnique(EntityMetamodel metamodel, GeneralCaseExpression expr) {
if (!isUnique(metamodel, expr.getDefaultExpr())) {
if (expr.getDefaultExpr() != null && !isUnique(metamodel, expr.getDefaultExpr())) {
return false;
}

Expand Down Expand Up @@ -254,7 +254,7 @@ private static boolean isNullable(EntityMetamodel metamodel, ArithmeticExpressio
}

private static boolean isNullable(EntityMetamodel metamodel, GeneralCaseExpression expr) {
if (isNullable(metamodel, expr.getDefaultExpr())) {
if (expr.getDefaultExpr() != null && isNullable(metamodel, expr.getDefaultExpr())) {
return true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,14 +296,16 @@ public Boolean visit(GeneralCaseExpression expression) {
setCollect(true);
collectExpressions(expressions, 0, i);
collectExpressions(expressions, i + 1, size);
expression.getDefaultExpr().accept(this);
if (expression.getDefaultExpr() != null) {
expression.getDefaultExpr().accept(this);
}
setCollect(oldCollect);

return true;
}
}

if (expression.getDefaultExpr().accept(this)) {
if (expression.getDefaultExpr() != null && expression.getDefaultExpr().accept(this)) {
collectExpressions(expressions, 0, size);
setCollect(oldCollect);
return true;
Expand All @@ -326,7 +328,9 @@ public Boolean visit(SimpleCaseExpression expression) {
if (expression.getCaseOperand().accept(this)) {
setCollect(true);
collectExpressions(expressions, 0, size);
expression.getDefaultExpr().accept(this);
if (expression.getDefaultExpr() != null) {
expression.getDefaultExpr().accept(this);
}
setCollect(oldCollect);

return true;
Expand All @@ -339,14 +343,16 @@ public Boolean visit(SimpleCaseExpression expression) {
expression.getCaseOperand().accept(this);
collectExpressions(expressions, 0, i);
collectExpressions(expressions, i + 1, size);
expression.getDefaultExpr().accept(this);
if (expression.getDefaultExpr() != null) {
expression.getDefaultExpr().accept(this);
}
setCollect(oldCollect);

return true;
}
}

if (expression.getDefaultExpr().accept(this)) {
if (expression.getDefaultExpr() != null && expression.getDefaultExpr().accept(this)) {
setCollect(true);
// Add previous expressions which are non-complex
expression.getCaseOperand().accept(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -472,13 +472,13 @@ comparison_operator : equality_comparison_operator # EqOrNeqPredicate
| '<=' # LePredicate
;

general_case_expression : caseTerminal=CASE when_clause (when_clause)* elseTerminal=ELSE scalar_expression endTerminal=END
general_case_expression : caseTerminal=CASE when_clause (when_clause)* (elseTerminal=ELSE scalar_expression)? endTerminal=END
;

when_clause : whenTerminal=WHEN conditional_expression thenTerminal=THEN scalar_expression
;

simple_case_expression : caseTerminal=CASE case_operand simple_when_clause (simple_when_clause)* elseTerminal=ELSE scalar_expression endTerminal=END
simple_case_expression : caseTerminal=CASE case_operand simple_when_clause (simple_when_clause)* (elseTerminal=ELSE scalar_expression)? endTerminal=END
;

simple_when_clause : whenTerminal=WHEN scalar_expression thenTerminal=THEN scalar_expression
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,13 @@ public void visit(GeneralCaseExpression expression) {
newPositions.addAll(pathPositions);
}

PathPosition position = currentPositions.get(j).copy();
pathPositions = new ArrayList<PathPosition>();
pathPositions.add(currentPosition = position);
expression.getDefaultExpr().accept(this);
newPositions.addAll(pathPositions);
if (expression.getDefaultExpr() != null) {
PathPosition position = currentPositions.get(j).copy();
pathPositions = new ArrayList<PathPosition>();
pathPositions.add(currentPosition = position);
expression.getDefaultExpr().accept(this);
newPositions.addAll(pathPositions);
}
}

currentPosition = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -629,32 +629,36 @@ private void handleCaseWhen(Expression caseOperand, List<WhenClauseExpression> w
ParameterRenderingMode oldParameterRenderingMode = setParameterRenderingMode(ParameterRenderingMode.PLACEHOLDER);
caseOperand.accept(this);
setParameterRenderingMode(oldParameterRenderingMode);
sb.append(" ");
sb.append(' ');
}

// TODO: when a type can be inferred by the results of the WHEN or ELSE clauses, we can set PLACEHOLDER, otherwise we have to render literals for parameters

int size = whenClauses.size();
for (int i = 0; i < size; i++) {
whenClauses.get(i).accept(this);
sb.append(" ");
sb.append(' ');
}
sb.append("ELSE ");
BooleanLiteralRenderingContext oldBooleanLiteralRenderingContext = setBooleanLiteralRenderingContext(BooleanLiteralRenderingContext.PLAIN);

final boolean requiresParenthesis = needsParenthesisForCaseResult(defaultExpr);
if (requiresParenthesis) {
sb.append('(');
}
if (defaultExpr != null) {
sb.append("ELSE ");
BooleanLiteralRenderingContext oldBooleanLiteralRenderingContext = setBooleanLiteralRenderingContext(BooleanLiteralRenderingContext.PLAIN);

final boolean requiresParenthesis = needsParenthesisForCaseResult(defaultExpr);
if (requiresParenthesis) {
sb.append('(');
}

defaultExpr.accept(this);
defaultExpr.accept(this);

if (requiresParenthesis) {
sb.append(')');
if (requiresParenthesis) {
sb.append(')');
}
setBooleanLiteralRenderingContext(oldBooleanLiteralRenderingContext);
sb.append(' ');
}

sb.append(" END");
setBooleanLiteralRenderingContext(oldBooleanLiteralRenderingContext);
sb.append("END");
}

protected boolean needsParenthesisForCaseResult(Expression expression) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,12 @@ public Boolean visit(GeneralCaseExpression expression) {
return true;
}
}
return expression.getDefaultExpr().accept(this);

if (expression.getDefaultExpr() != null) {
return expression.getDefaultExpr().accept(this);
}

return false;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ public Boolean visit(GeneralCaseExpression expression) {
onModifier(new ExpressionListModifier(expressions, i));
}
}
if (Boolean.TRUE == expression.getDefaultExpr().accept(this)) {
if (expression.getDefaultExpr() != null && Boolean.TRUE == expression.getDefaultExpr().accept(this)) {
onModifier(new GeneralCaseExpressionDefaultModifier(expression));
}
return Boolean.FALSE;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,9 @@ public Expression visit(GeneralCaseExpression expression) {
for (int i = 0; i < expression.getWhenClauses().size(); i++) {
expression.getWhenClauses().set(i, (WhenClauseExpression) expression.getWhenClauses().get(i).accept(this));
}
expression.setDefaultExpr(expression.getDefaultExpr().accept(this));
if (expression.getDefaultExpr() != null) {
expression.setDefaultExpr(expression.getDefaultExpr().accept(this));
}
return expression;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,9 @@ public Expression visit(GeneralCaseExpression expression) {
for (int i = 0; i < size; i++) {
expressions.set(i, (WhenClauseExpression) expressions.get(i).accept(this));
}
expression.setDefaultExpr(expression.getDefaultExpr().accept(this));
if (expression.getDefaultExpr() != null) {
expression.setDefaultExpr(expression.getDefaultExpr().accept(this));
}
return expression;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -684,7 +684,8 @@ public Expression visitGeneral_case_expression(JPQLSelectExpressionParser.Genera
for (JPQLSelectExpressionParser.When_clauseContext whenClause : ctx.when_clause()) {
whenClauses.add((WhenClauseExpression) whenClause.accept(this));
}
return new GeneralCaseExpression(whenClauses, ctx.scalar_expression().accept(this));
JPQLSelectExpressionParser.Scalar_expressionContext elseExpressionCtx = ctx.scalar_expression();
return new GeneralCaseExpression(whenClauses, elseExpressionCtx == null ? null : elseExpressionCtx.accept(this));
}

@Override
Expand All @@ -693,7 +694,8 @@ public Expression visitSimple_case_expression(JPQLSelectExpressionParser.Simple_
for (JPQLSelectExpressionParser.Simple_when_clauseContext whenClause : ctx.simple_when_clause()) {
whenClauses.add((WhenClauseExpression) whenClause.accept(this));
}
return new SimpleCaseExpression(ctx.case_operand().accept(this), whenClauses, ctx.scalar_expression().accept(this));
JPQLSelectExpressionParser.Scalar_expressionContext elseExpressionCtx = ctx.scalar_expression();
return new SimpleCaseExpression(ctx.case_operand().accept(this), whenClauses, elseExpressionCtx == null ? null : elseExpressionCtx.accept(this));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,9 @@ public void visit(GeneralCaseExpression expression) {
for (int i = 0; i < size; i++) {
expressions.get(i).accept(this);
}
expression.getDefaultExpr().accept(this);
if (expression.getDefaultExpr() != null) {
expression.getDefaultExpr().accept(this);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
import java.lang.annotation.Target;

/**
* Specifies that the class is is an entity view.
* Specifies that the class is an entity view.
*
* @author Christian Beikov
* @since 1.0.0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright 2014 - 2017 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.view;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Specifies that the entity view when queried should consider subtypes of the entity view.
*
* @author Christian Beikov
* @since 1.2.0
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface EntityViewInheritance {

/**
* The entity view subtypes that may be considered when querying.
* An empty value has the meaning of all (registered) subtypes.
*
* @return The entity view subtype classes
*/
Class<?>[] value() default {};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2014 - 2017 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.view;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Defines the inheritance selection for the entity view when a super type is queried.
*
* @author Christian Beikov
* @since 1.2.0
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface EntityViewInheritanceMapping {

/**
* The selection predicate which is used to test whether this entity view type should be used as target type for an entity.
*
* @return The selection predicate
*/
String value();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* Copyright 2014 - 2017 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.view;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Defines the subtype mappings for a subview attribute.
*
* @author Christian Beikov
* @since 1.2.0
*/
@Target({ ElementType.METHOD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
public @interface MappingInheritance {

/**
* Specifies that the base type is not considered in the inheritance subtype selection, but only it's subtypes.
*
* @return Whether the base type should be considered for inheritance subtype selection
*/
boolean onlySubtypes() default false;

/**
* The subtype mappings of this annotated attribute that should be considered for inheritance.
*
* @return The subtype mappings
*/
MappingInheritanceSubtype[] value();
}
Loading

0 comments on commit 60d2a7e

Please sign in to comment.