From d00cf9d468a466d863c5fe977493bac7acd0aceb Mon Sep 17 00:00:00 2001 From: Fay Wang Date: Fri, 10 Apr 2009 22:57:00 +0000 Subject: [PATCH] OPENJPA-1024: support enum literal in case expression git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@764094 13f79535-47bb-0310-9956-ffa450edef68 --- .../kernel/exps/GeneralCaseExpression.java | 5 ++- .../kernel/exps/JDBCExpressionFactory.java | 4 +- .../apache/openjpa/jdbc/kernel/exps/Lit.java | 26 ++++++++++++- .../kernel/exps/SimpleCaseExpression.java | 2 +- .../TestJPQLScalarExpressions.java | 39 +++++++++++++++++-- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GeneralCaseExpression.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GeneralCaseExpression.java index 2841fb430..e130a4b3a 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GeneralCaseExpression.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/GeneralCaseExpression.java @@ -143,9 +143,10 @@ public class GeneralCaseExpression for (int i = 0; i < _exp.length; i++) { BinaryOpExpState bstate = (BinaryOpExpState) gstate.states[i]; ((WhenCondition) _exp[i]).getVal().calculateValue(sel, ctx, - bstate.state2, null, null); + bstate.state2, other, otherState); } - _val.calculateValue(sel, ctx, gstate.states[_exp.length], null, null); + _val.calculateValue(sel, ctx, gstate.states[_exp.length], other, + otherState); } public void groupBy(Select sel, ExpContext ctx, ExpState state) { diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java index 3cd49951e..38b6df69d 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/JDBCExpressionFactory.java @@ -447,8 +447,8 @@ public class JDBCExpressionFactory else value.append("0"); } else if (lit.getParseType() == Literal.TYPE_ENUM) { - value.append("'").append(((Enum) lit.getValue()).name()). - append("'"); + lit.setRaw(true); + return val; } else value.append(lit.getValue().toString()); lit.setValue(new Raw(value.toString())); diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java index 5b45fab39..e2dc8c620 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/Lit.java @@ -18,6 +18,7 @@ */ package org.apache.openjpa.jdbc.kernel.exps; +import org.apache.openjpa.jdbc.sql.Raw; import org.apache.openjpa.jdbc.sql.SQLBuffer; import org.apache.openjpa.jdbc.sql.Select; import org.apache.openjpa.kernel.Filters; @@ -34,6 +35,7 @@ public class Lit private Object _val; private int _ptype; + private boolean _isRaw; /** * Constructor. Supply literal value. @@ -66,6 +68,14 @@ public class Lit public Object getValue(Object[] params) { return getValue(); } + + public boolean isRaw() { + return _isRaw; + } + + public void setRaw(boolean isRaw) { + _isRaw = isRaw; + } public ExpState initialize(Select sel, ExpContext ctx, int flags) { return new LitExpState(); @@ -98,7 +108,21 @@ public class Lit if (lstate.otherLength > 1) sql.appendValue(((Object[]) lstate.sqlValue)[index], lstate.getColumn(index)); - else + else { + if (getParseType() == Literal.TYPE_ENUM && _isRaw) { + StringBuilder value = new StringBuilder(); + boolean isOrdinal = false; + if (lstate.sqlValue instanceof Integer) + isOrdinal = true; + if (!isOrdinal) + value.append("'"); + value.append(lstate.sqlValue); + if (!isOrdinal) + value.append("'"); + lstate.sqlValue = new Raw(value.toString()); + setValue(lstate.sqlValue); + } sql.appendValue(lstate.sqlValue, lstate.getColumn(index)); + } } } diff --git a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SimpleCaseExpression.java b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SimpleCaseExpression.java index 82a233447..4a9b07ea7 100644 --- a/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SimpleCaseExpression.java +++ b/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/exps/SimpleCaseExpression.java @@ -177,7 +177,7 @@ public class SimpleCaseExpression ((WhenScalar) _exp[i]).getVal1().calculateValue(sel, ctx, bstate.state1, null, null); ((WhenScalar) _exp[i]).getVal2().calculateValue(sel, ctx, - bstate.state2, null, null); + bstate.state2, other, otherState); } _val.calculateValue(sel, ctx, cstate.states[_exp.length+1], other, otherState); diff --git a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java index d6b10768f..14844af49 100644 --- a/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java +++ b/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/jpql/expressions/TestJPQLScalarExpressions.java @@ -175,7 +175,6 @@ public class TestJPQLScalarExpressions extends AbstractTestCase { " ELSE e.age + 0 " + " END AS cage " + " FROM CompUser e ORDER BY cage"; - List rs = em.createQuery(query).getResultList(); String update = "UPDATE CompUser e SET e.age = " + @@ -185,7 +184,6 @@ public class TestJPQLScalarExpressions extends AbstractTestCase { "END"; int result = em.createQuery(update).executeUpdate(); - assertEquals("the result is not 6", 6, result); String query2 = "SELECT e.name, e.age+1 as cage, " + @@ -208,13 +206,46 @@ public class TestJPQLScalarExpressions extends AbstractTestCase { " ELSE " + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT" + " END FROM CompUser e ORDER BY e.age"; - List rs3 = em.createQuery(query3).getResultList(); Object[] result3 = (Object[]) rs3.get(0); assertEquals("the name is not Jacob", "Jacob", result3[0]); assertEquals("the credit rating is not 'POOR'", "POOR", result3[1]); - endTx(em); + /* + // this jpql fail with NPE in Derby. It works with DB2 + String update2 = "update CompUser c set c.creditRating = " + + " CASE WHEN c.name ='Jacob' THEN " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" + + " WHEN c.name = 'Ugo' THEN " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.GOOD " + + " ELSE " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT " + + " END "; + */ + + String update2 = "update CompUser c set c.creditRating = " + + " CASE WHEN c.age > 30 THEN " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" + + " WHEN c.age < 15 THEN " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.GOOD " + + " ELSE " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT " + + " END "; + result = em.createQuery(update2).executeUpdate(); + assertEquals("the result is not 6", 6, result); + + String update3 = "update CompUser c set c.creditRating = " + + " CASE c.age WHEN 35 THEN " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" + + " WHEN 11 THEN " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.GOOD " + + " ELSE " + + "org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT " + + " END "; + result = em.createQuery(update3).executeUpdate(); + assertEquals("the result is not 6", 6, result); + + endTx(em); endEm(em); }