OPENJPA-1992: Throw exception if a JPQL query is missing the first positional parameter

git-svn-id: https://svn.apache.org/repos/asf/openjpa/trunk@1100787 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Michael Dick 2011-05-08 18:39:07 +00:00
parent 6fc7d55a09
commit 26aa776627
5 changed files with 46 additions and 6 deletions

View File

@ -334,6 +334,7 @@ public class ExpressionStoreQuery
QueryExpressions exps = assertQueryExpression();
ValidateGroupingExpressionVisitor.validate(q.getContext(), exps);
}
public void getRange(StoreQuery q, Object[] params, Range range) {
QueryExpressions exps = assertQueryExpression();
@ -490,7 +491,7 @@ public class ExpressionStoreQuery
public boolean isPacking(StoreQuery q) {
return false;
}
/**
* Throws an exception if select or having clauses contain
* non-aggregate, non-grouped paths.

View File

@ -45,7 +45,6 @@ import org.apache.openjpa.kernel.QueryOperations;
import org.apache.openjpa.kernel.ResultShape;
import org.apache.openjpa.kernel.StoreContext;
import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
import org.apache.openjpa.kernel.exps.Constant;
import org.apache.openjpa.kernel.exps.Context;
import org.apache.openjpa.kernel.exps.Expression;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
@ -311,7 +310,10 @@ public class JPQLExpressionBuilder
exps.accessPath = getAccessPath();
exps.hasInExpression = this.hasParameterizedInExpression;
// verify parameters are consistent.
validateParameters();
return exps;
}
@ -2465,5 +2467,23 @@ public class JPQLExpressionBuilder
return this.query;
}
}
// throws an exception if there are numeric parameters which do not start with 1.
private void validateParameters() {
if(parameterTypes == null || parameterTypes.isEmpty()) {
return;
}
Object firstKey = parameterTypes.keySet().iterator().next();
if (firstKey != null) { // paranoia
if (firstKey instanceof Number) {
if (!parameterTypes.keySet().contains(1)) {
throw new UserException(_loc.get("missing-positional-parameter", resolver.getQueryContext()
.getQueryString(), parameterTypes.keySet().toString()));
}
}
}
}
}

View File

@ -82,3 +82,4 @@ public class JPQLParser
return JPQLParser.LANG_JPQL;
}
}

View File

@ -87,3 +87,5 @@ cant-bulk-update-embeddable: Bulk update of embeddables: "{0}" is not allowed.
cant-groupby-embeddable: Grouping by embeddables: "{0}" is not allowed.
cant-groupby-key-value-embeddable: Grouping by embeddables: "{0}({1})" is not allowed.
no-constructor: NEW constructor operation could not resolve class named "{0}".
missing-positional-parameter: Query "{0}" did not contain positional parameter 1. \
JPQL positional parameters must start at 1. Detected parameters "{1}".

View File

@ -18,8 +18,14 @@
*/
package org.apache.openjpa.persistence.jpql.functions;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.EntityManager;
import org.apache.openjpa.kernel.jpql.JPQLExpressionBuilder;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.persistence.ArgumentException;
import org.apache.openjpa.persistence.common.apps.Address;
import org.apache.openjpa.persistence.common.apps.CompUser;
import org.apache.openjpa.persistence.common.apps.FemaleUser;
@ -127,10 +133,20 @@ public class TestSetParameter extends SingleEMFTestCase {
.executeUpdate();
em.getTransaction().commit();
assertEquals(1, count);
}
public void testMissingFirstPositionalParameter() {
EntityManager em = emf.createEntityManager();
String query = "UPDATE CompUser e set e.name= ?2, e.age = ?4 " + "WHERE e.userid = ?3";
try {
em.createQuery(query);
fail("Did not get UserException with invalid JPQL query");
} catch (ArgumentException ae) {
// expected
}
em.close();
}
public CompUser createUser(String name, String cName, int age,
boolean isMale) {
CompUser user = null;