OPENJPA-2861 fix Raw handling

Raw did loose the internal type. Once 'interned' to Raw the type was always String.class.
And this broke quite a few return type situations in quite a nasty way.
This commit is contained in:
Mark Struberg 2021-04-06 22:30:10 +02:00
parent 5fd5de9fb8
commit 0fc957a02b
4 changed files with 25 additions and 39 deletions

View File

@ -26,7 +26,6 @@ import org.apache.openjpa.jdbc.meta.Discriminator;
import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy; import org.apache.openjpa.jdbc.meta.strats.NoneDiscriminatorStrategy;
import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy; import org.apache.openjpa.jdbc.meta.strats.VerticalClassStrategy;
import org.apache.openjpa.jdbc.sql.DBDictionary; import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.jdbc.sql.Raw;
import org.apache.openjpa.kernel.exps.AggregateListener; import org.apache.openjpa.kernel.exps.AggregateListener;
import org.apache.openjpa.kernel.exps.Arguments; import org.apache.openjpa.kernel.exps.Arguments;
import org.apache.openjpa.kernel.exps.Expression; import org.apache.openjpa.kernel.exps.Expression;
@ -578,24 +577,7 @@ public class JDBCExpressionFactory
private Value getLiteralRawString(Value val) { private Value getLiteralRawString(Value val) {
if (val instanceof Lit) { if (val instanceof Lit) {
Lit lit = (Lit) val; Lit lit = (Lit) val;
StringBuilder value = new StringBuilder();
int pType = lit.getParseType();
if (pType == Literal.TYPE_SQ_STRING ||
pType == Literal.TYPE_STRING)
value.append("'").append(lit.getValue().toString()).append("'");
else if (pType == Literal.TYPE_BOOLEAN) {
Boolean boolVal = (Boolean)lit.getValue();
if (_isBooleanLiteralAsNumeric)
value.append(boolVal ? "1" : "0");
else
value.append(boolVal ? "true" : "false");
} else if (pType == Literal.TYPE_ENUM) {
lit.setRaw(true); lit.setRaw(true);
return val;
} else
value.append(lit.getValue().toString());
lit.setValue(new Raw(value.toString()));
return lit;
} }
return val; return val;
} }

View File

@ -39,7 +39,6 @@ public class Lit
private Object _val; private Object _val;
private int _ptype; private int _ptype;
private boolean _isRaw; private boolean _isRaw;
private Object _rawVal;
/** /**
* Constructor. Supply literal value. * Constructor. Supply literal value.
@ -54,9 +53,10 @@ public class Lit
@Override @Override
public Class getType() { public Class getType() {
if (_isRaw && _rawVal != null) if (_val == null) {
return Raw.class; return Object.class;
return (_val == null) ? Object.class : _val.getClass(); }
return _val.getClass();
} }
@Override @Override
@ -92,10 +92,6 @@ public class Lit
_isRaw = isRaw; _isRaw = isRaw;
} }
public Object getRawValue() {
return _rawVal;
}
@Override @Override
public ExpState initialize(Select sel, ExpContext ctx, int flags) { public ExpState initialize(Select sel, ExpContext ctx, int flags) {
return new LitExpState(); return new LitExpState();
@ -112,8 +108,7 @@ public class Lit
} }
@Override @Override
public void calculateValue(Select sel, ExpContext ctx, ExpState state, public void calculateValue(Select sel, ExpContext ctx, ExpState state, Val other, ExpState otherState) {
Val other, ExpState otherState) {
super.calculateValue(sel, ctx, state, other, otherState); super.calculateValue(sel, ctx, state, other, otherState);
LitExpState lstate = (LitExpState) state; LitExpState lstate = (LitExpState) state;
if (other != null) { if (other != null) {
@ -124,8 +119,7 @@ public class Lit
} }
@Override @Override
public void appendTo(Select sel, ExpContext ctx, ExpState state, public void appendTo(Select sel, ExpContext ctx, ExpState state, SQLBuffer sql, int index) {
SQLBuffer sql, int index) {
LitExpState lstate = (LitExpState) state; LitExpState lstate = (LitExpState) state;
if (lstate.otherLength > 1) { if (lstate.otherLength > 1) {
sql.appendValue(((Object[]) lstate.sqlValue)[index], lstate.getColumn(index)); sql.appendValue(((Object[]) lstate.sqlValue)[index], lstate.getColumn(index));
@ -133,7 +127,21 @@ public class Lit
return; return;
} else if (_isRaw) { } else if (_isRaw) {
int parseType = getParseType(); int parseType = getParseType();
if (parseType == Literal.TYPE_ENUM) { if (parseType == Literal.TYPE_SQ_STRING || parseType == Literal.TYPE_STRING) {
lstate.sqlValue = new Raw("'" + _val.toString() + "'");
} else if (parseType == Literal.TYPE_BOOLEAN) {
Boolean boolVal = (Boolean)_val;
Object dbRepresentation = ctx.store.getDBDictionary().getBooleanRepresentation().getRepresentation(boolVal);
if (dbRepresentation instanceof String) {
lstate.sqlValue = new Raw("'" + dbRepresentation.toString() + "'");
} else if (dbRepresentation instanceof Boolean ||
dbRepresentation instanceof Integer) {
lstate.sqlValue = new Raw(dbRepresentation.toString());
} else {
// continue without Raw
lstate.sqlValue = _val;
}
} else if (parseType == Literal.TYPE_ENUM) {
StringBuilder value = new StringBuilder(); StringBuilder value = new StringBuilder();
boolean isOrdinal = false; boolean isOrdinal = false;
if (lstate.sqlValue instanceof Integer) if (lstate.sqlValue instanceof Integer)
@ -144,18 +152,16 @@ public class Lit
if (!isOrdinal) if (!isOrdinal)
value.append("'"); value.append("'");
lstate.sqlValue = new Raw(value.toString()); lstate.sqlValue = new Raw(value.toString());
_rawVal = lstate.sqlValue;
} else if (parseType == Literal.TYPE_DATE || parseType == Literal.TYPE_TIME || } else if (parseType == Literal.TYPE_DATE || parseType == Literal.TYPE_TIME ||
parseType == Literal.TYPE_TIMESTAMP) { parseType == Literal.TYPE_TIMESTAMP) {
lstate.sqlValue = new Raw(_val.toString()); lstate.sqlValue = new Raw(_val.toString());
_rawVal = lstate.sqlValue; } else if (parseType == Literal.TYPE_NUMBER) {
lstate.sqlValue = new Raw(_val.toString());
} else { } else {
lstate.sqlValue = new Raw(_val instanceof String ? "'"+_val+"'" : _val.toString()); lstate.sqlValue = new Raw(_val instanceof String ? "'"+_val+"'" : _val.toString());
_rawVal = lstate.sqlValue;
} }
} }
Object useLiteral = ctx.fetch.getHint(QueryHints.HINT_USE_LITERAL_IN_SQL); Object useLiteral = ctx.fetch.getHint(QueryHints.HINT_USE_LITERAL_IN_SQL);
// useLiteral = true;
boolean useParamToken = useLiteral != null ? !(Boolean)useLiteral : true; boolean useParamToken = useLiteral != null ? !(Boolean)useLiteral : true;
sql.appendValue(lstate.sqlValue, lstate.getColumn(index), null, useParamToken); sql.appendValue(lstate.sqlValue, lstate.getColumn(index), null, useParamToken);
} }

View File

@ -111,12 +111,10 @@ public class TestAggregateFunctions extends SingleEMFTestCase {
em.persist(ae2); em.persist(ae2);
em.getTransaction().commit(); em.getTransaction().commit();
/*X
em.getTransaction().begin(); em.getTransaction().begin();
final TypedQuery<Long> q2 = em.createQuery("select SUM(ae.intVal) from AggEntity AS ae", Long.class); final TypedQuery<Long> q2 = em.createQuery("select SUM(ae.intVal) from AggEntity AS ae", Long.class);
final Long sum = q2.getSingleResult(); final Long sum = q2.getSingleResult();
assertEquals(2L, (long) sum); assertEquals(2L, (long) sum);
*/
final TypedQuery<Long> q = em.createQuery("select SUM(CASE ae.stringVal WHEN 'bare' THEN 1 ELSE 0 END) from AggEntity AS ae", Long.class); final TypedQuery<Long> q = em.createQuery("select SUM(CASE ae.stringVal WHEN 'bare' THEN 1 ELSE 0 END) from AggEntity AS ae", Long.class);
final Long sumC = q.getSingleResult(); final Long sumC = q.getSingleResult();

View File

@ -319,7 +319,7 @@ public class TestJPQLScalarExpressions extends AbstractTestCase {
List rs3 = em.createQuery(query3).getResultList(); List rs3 = em.createQuery(query3).getResultList();
Object[] result3 = (Object[]) rs3.get(0); Object[] result3 = (Object[]) rs3.get(0);
assertEquals("the name is not Jacob", "Jacob", result3[0]); assertEquals("the name is not Jacob", "Jacob", result3[0]);
assertEquals("the credit rating is not 'POOR'", "POOR", result3[1]); assertEquals("the credit rating is not 'POOR'", CompUser.CreditRating.POOR, result3[1]);
String update2 = "update CompUser c set c.creditRating = " + String update2 = "update CompUser c set c.creditRating = " +
" CASE WHEN c.name ='Jacob' THEN " + " CASE WHEN c.name ='Jacob' THEN " +