OPENJPA-978: make the third argument in substring function

optional.

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@753596 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Fay Wang 2009-03-14 03:28:14 +00:00
parent d8da810820
commit 2860368801
2 changed files with 35 additions and 9 deletions

View File

@ -1071,12 +1071,18 @@ public class JPQLExpressionBuilder
return factory.concat(val1, val2);
case JJTSUBSTRING:
val1 = getValue(child(node, 0, 3));
val2 = getValue(child(node, 1, 3));
val3 = getValue(child(node, 2, 3));
if (node.children.length == 3) {
val1 = getValue(child(node, 0, 3));
val2 = getValue(child(node, 1, 3));
val3 = getValue(child(node, 2, 3));
} else if (node.children.length == 2) {
val1 = getValue(child(node, 0, 2));
val2 = getValue(child(node, 1, 2));
}
setImplicitType(val1, TYPE_STRING);
setImplicitType(val2, Integer.TYPE);
setImplicitType(val3, Integer.TYPE);
if (node.children.length == 3)
setImplicitType(val3, Integer.TYPE);
// the semantics of the JPQL substring() function
// are that arg2 is the 1-based start index, and arg3 is
@ -1086,28 +1092,35 @@ public class JPQLExpressionBuilder
// arg2 is the end index): we perform the translation by
// adding one to the first argument, and then adding the
// first argument to the second argument to get the endIndex
Value start;
Value end;
if (val2 instanceof Literal && val3 instanceof Literal) {
Value start = null;
Value end = null;
if (val2 instanceof Literal &&
(val3 == null || val3 instanceof Literal)) {
// optimize SQL for the common case of two literals
long jpqlStart = ((Number) ((Literal) val2).getValue())
.longValue();
long length = ((Number) ((Literal) val3).getValue())
.longValue();
start = factory.newLiteral(new Long(jpqlStart - 1),
Literal.TYPE_NUMBER);
if (val3 != null) {
long length = ((Number) ((Literal) val3).getValue())
.longValue();
long endIndex = length + (jpqlStart - 1);
end = factory.newLiteral(new Long(endIndex),
Literal.TYPE_NUMBER);
}
} else {
start = factory.subtract(val2, factory.newLiteral
(Numbers.valueOf(1), Literal.TYPE_NUMBER));
if (val3 != null)
end = factory.add(val3,
(factory.subtract(val2, factory.newLiteral
(Numbers.valueOf(1), Literal.TYPE_NUMBER))));
}
if (val3 != null)
return factory.substring(val1, factory.newArgumentList(
start, end));
else
return factory.substring(val1, start);
case JJTLOCATE:
// as with SUBSTRING (above), the semantics for LOCATE differ

View File

@ -94,6 +94,19 @@ public class TestEJBQLFunction extends AbstractTestCase {
assertEquals("the users name is not AblahumSeet", "Ablahumeeth",
user.getName());
query = "UPDATE CompUser e SET e.name = " +
"CONCAT('XYZ', SUBSTRING(e.name, LOCATE('e', e.name))) " +
"WHERE e.name='Ablahumeeth'";
result = em.createQuery(query).executeUpdate();
assertEquals("the result is not 1", 1, result);
user = em.find(CompUser.class, userid1);
em.refresh(user);
assertNotNull("the user is null", user);
assertEquals("the users name is not Ablahumeeth", "XYZeeth",
user.getName());
endTx(em);
endEm(em);
}