mirror of https://github.com/apache/openjpa.git
OPENJPA-1024: support case expression in subquery
git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@764779 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
171fe56aa2
commit
0398c0e7dd
|
@ -28,6 +28,7 @@ import org.apache.openjpa.jdbc.sql.SQLBuffer;
|
|||
import org.apache.openjpa.jdbc.sql.Select;
|
||||
import org.apache.openjpa.kernel.Filters;
|
||||
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
|
||||
import org.apache.openjpa.kernel.exps.Value;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
|
||||
/**
|
||||
|
@ -42,6 +43,8 @@ public class GeneralCaseExpression
|
|||
private final Val _val;
|
||||
private ClassMetaData _meta = null;
|
||||
private Class _cast = null;
|
||||
private Value other = null;
|
||||
private ExpState otherState = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -158,7 +161,7 @@ public class GeneralCaseExpression
|
|||
}
|
||||
|
||||
private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
|
||||
calculateValue(sel, ctx, state, null, null);
|
||||
calculateValue(sel, ctx, state, (Val)other, otherState);
|
||||
SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
|
||||
appendTo(sel, ctx, state, buf, 0);
|
||||
return buf;
|
||||
|
@ -190,5 +193,20 @@ public class GeneralCaseExpression
|
|||
public void setMetaData(ClassMetaData meta) {
|
||||
_meta = meta;
|
||||
}
|
||||
public void setOtherPath(Value other) {
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
public Value getOtherPath() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOtherState(ExpState otherState) {
|
||||
this.otherState = otherState;
|
||||
}
|
||||
|
||||
public ExpState getOtherState() {
|
||||
return otherState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.apache.openjpa.jdbc.sql.SQLBuffer;
|
|||
import org.apache.openjpa.jdbc.sql.Select;
|
||||
import org.apache.openjpa.kernel.Filters;
|
||||
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
|
||||
import org.apache.openjpa.kernel.exps.Value;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
|
||||
/**
|
||||
|
@ -44,6 +45,8 @@ public class SimpleCaseExpression
|
|||
private final Val _val;
|
||||
private ClassMetaData _meta = null;
|
||||
private Class _cast = null;
|
||||
private Value other = null;
|
||||
private ExpState otherState = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -192,7 +195,7 @@ public class SimpleCaseExpression
|
|||
}
|
||||
|
||||
private SQLBuffer newSQLBuffer(Select sel, ExpContext ctx, ExpState state) {
|
||||
calculateValue(sel, ctx, state, null, null);
|
||||
calculateValue(sel, ctx, state, (Val)other, otherState);
|
||||
SQLBuffer buf = new SQLBuffer(ctx.store.getDBDictionary());
|
||||
appendTo(sel, ctx, state, buf, 0);
|
||||
return buf;
|
||||
|
@ -224,5 +227,20 @@ public class SimpleCaseExpression
|
|||
public void setMetaData(ClassMetaData meta) {
|
||||
_meta = meta;
|
||||
}
|
||||
public void setOtherPath(Value other) {
|
||||
this.other = other;
|
||||
}
|
||||
|
||||
public Value getOtherPath() {
|
||||
return other;
|
||||
}
|
||||
|
||||
public void setOtherState(ExpState otherState) {
|
||||
this.otherState = otherState;
|
||||
}
|
||||
|
||||
public ExpState getOtherState() {
|
||||
return otherState;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.apache.openjpa.kernel.Filters;
|
|||
import org.apache.openjpa.kernel.exps.ExpressionVisitor;
|
||||
import org.apache.openjpa.kernel.exps.QueryExpressions;
|
||||
import org.apache.openjpa.kernel.exps.Subquery;
|
||||
import org.apache.openjpa.kernel.exps.Value;
|
||||
import org.apache.openjpa.meta.ClassMetaData;
|
||||
|
||||
/**
|
||||
|
@ -149,6 +150,16 @@ class SubQ
|
|||
|
||||
public void calculateValue(Select sel, ExpContext ctx, ExpState state,
|
||||
Val other, ExpState otherState) {
|
||||
Value[] projs = _exps.projections;
|
||||
for (int i = 0; i < projs.length; i++) {
|
||||
if (projs[i] instanceof GeneralCaseExpression) {
|
||||
((GeneralCaseExpression)projs[i]).setOtherPath(other);
|
||||
((GeneralCaseExpression)projs[i]).setOtherState(otherState);
|
||||
} else if (projs[i] instanceof SimpleCaseExpression) {
|
||||
((SimpleCaseExpression)projs[i]).setOtherPath(other);
|
||||
((SimpleCaseExpression)projs[i]).setOtherState(otherState);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int length(Select sel, ExpContext ctx, ExpState state) {
|
||||
|
|
|
@ -157,6 +157,35 @@ public class TestJPQLScalarExpressions extends AbstractTestCase {
|
|||
result = (Object[]) rs.get(rs.size()-1);
|
||||
assertEquals(result[1], 1);
|
||||
|
||||
startTx(em);
|
||||
String update = "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 ";
|
||||
int updateCount = em.createQuery(update).executeUpdate();
|
||||
assertEquals("the result is not 6", 6, updateCount);
|
||||
|
||||
/*
|
||||
//Derby fails but DB2 worksh
|
||||
String update2 = "update CompUser c set c.creditRating = " +
|
||||
" (select " +
|
||||
" CASE c1.age WHEN 10 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" +
|
||||
" WHEN 19 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.GOOD " +
|
||||
" ELSE " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT " +
|
||||
" END " +
|
||||
" from CompUser c1" +
|
||||
" where c.userid = c1.userid)";
|
||||
updateCount = em.createQuery(update2).executeUpdate();
|
||||
assertEquals("the result is not 6", 6, updateCount);
|
||||
*/
|
||||
endTx(em);
|
||||
endEm(em);
|
||||
}
|
||||
|
||||
|
@ -231,9 +260,28 @@ public class TestJPQLScalarExpressions extends AbstractTestCase {
|
|||
" ELSE " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT " +
|
||||
" END ";
|
||||
result = em.createQuery(update2).executeUpdate();
|
||||
assertEquals("the result is not 6", 6, result);
|
||||
|
||||
int updateCount = em.createQuery(update2).executeUpdate();
|
||||
assertEquals("the result is not 6", 6, updateCount);
|
||||
|
||||
String query4 = "select e.name, e.creditRating from CompUser e " +
|
||||
"where e.creditRating = " +
|
||||
"(select " +
|
||||
"CASE WHEN e1.age = 11 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" +
|
||||
" WHEN e1.age = 35 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.GOOD" +
|
||||
" ELSE " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT" +
|
||||
" END " +
|
||||
"from CompUser e1" +
|
||||
" where e.userid = e1.userid) ORDER BY e.age";
|
||||
List rs4 = em.createQuery(query4).getResultList();
|
||||
Object[] result4 = (Object[]) rs4.get(0);
|
||||
assertEquals("the name is not Ugo", "Ugo", result4[0]);
|
||||
assertEquals("the credit rating is not 'EXCELLENT'", "EXCELLENT",
|
||||
((org.apache.openjpa.persistence.common.apps.CompUser.CreditRating)
|
||||
result4[1]).name());
|
||||
|
||||
String update3 = "update CompUser c set c.creditRating = " +
|
||||
" CASE c.age WHEN 35 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" +
|
||||
|
@ -245,7 +293,23 @@ public class TestJPQLScalarExpressions extends AbstractTestCase {
|
|||
result = em.createQuery(update3).executeUpdate();
|
||||
assertEquals("the result is not 6", 6, result);
|
||||
|
||||
endTx(em);
|
||||
// Derby fails but DB2 works
|
||||
/*
|
||||
String update4 = "update CompUser c set c.creditRating = " +
|
||||
" (select " +
|
||||
" CASE c1.age WHEN 10 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.POOR" +
|
||||
" WHEN 19 THEN " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.GOOD" +
|
||||
" ELSE " +
|
||||
"org.apache.openjpa.persistence.common.apps.CompUser$CreditRating.EXCELLENT" +
|
||||
" END " +
|
||||
" from CompUser c1" +
|
||||
" where c.userid = c1.userid)";
|
||||
updateCount = em.createQuery(update4).executeUpdate();
|
||||
assertEquals("the result is not 6", 6, updateCount);
|
||||
*/
|
||||
endTx(em);
|
||||
endEm(em);
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,17 @@ public class TestSubquery
|
|||
"select o.oid from Order o where o.customer.name in" +
|
||||
" (select CONCAT(o.customer.name, 'XX') from Order o" +
|
||||
" where o.amount > 10)",
|
||||
"select c from Customer c where c.creditRating =" +
|
||||
" (select " +
|
||||
" CASE WHEN o2.amount > 10 THEN " +
|
||||
"org.apache.openjpa.persistence.query.Customer$CreditRating.POOR" +
|
||||
" WHEN o2.amount = 10 THEN " +
|
||||
"org.apache.openjpa.persistence.query.Customer$CreditRating.GOOD " +
|
||||
" ELSE " +
|
||||
"org.apache.openjpa.persistence.query.Customer$CreditRating.EXCELLENT " +
|
||||
" END " +
|
||||
" from Order o2" +
|
||||
" where c.cid.id = o2.customer.cid.id)",
|
||||
};
|
||||
|
||||
static String[] updates = new String[] {
|
||||
|
|
Loading…
Reference in New Issue