You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openjpa.apache.org by pc...@apache.org on 2008/01/24 08:33:36 UTC
svn commit: r614812 - in /openjpa/trunk:
openjpa-kernel/src/main/java/org/apache/openjpa/conf/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/
openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/
openjpa-kernel/src/main/java/org/apache/...
Author: pcl
Date: Wed Jan 23 23:33:32 2008
New Revision: 614812
URL: http://svn.apache.org/viewvc?rev=614812&view=rev
Log:
OPENJPA-502
Modified:
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Resolver.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ParseException.java
openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java
openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/conf/Compatibility.java Wed Jan 23 23:33:32 2008
@@ -23,6 +23,29 @@
*/
public class Compatibility {
+ /**
+ * If a JPQL statement is not compliant with the JPA specification,
+ * fail to parse it.
+ *
+ * @since 1.1.0
+ */
+ public static final int JPQL_STRICT = 0;
+
+ /**
+ * If a JPQL statement is not compliant with the JPA specification,
+ * warn the first time that statement is parsed.
+ *
+ * @since 1.1.0
+ */
+ public static final int JPQL_WARN = 1;
+
+ /**
+ * Allow non-compliant extensions of JPQL.
+ *
+ * @since 1.1.0
+ */
+ public static final int JPQL_EXTENDED = 2;
+
private boolean _strictIdValues = false;
private boolean _hollowLookups = true;
private boolean _checkStore = false;
@@ -30,6 +53,7 @@
private boolean _closeOnCommit = true;
private boolean _quotedNumbers = false;
private boolean _nonOptimisticVersionCheck = false;
+ private int _jpql = JPQL_STRICT;
/**
* Whether to require exact identity value types when creating object
@@ -146,8 +170,7 @@
* in a datastore transaction. Version of OpenJPA prior to 0.4.1 always
* forced a version check.
*/
- public void setNonOptimisticVersionCheck
- (boolean nonOptimisticVersionCheck) {
+ public void setNonOptimisticVersionCheck(boolean nonOptimisticVersionCheck){
_nonOptimisticVersionCheck = nonOptimisticVersionCheck;
}
@@ -158,5 +181,38 @@
*/
public boolean getNonOptimisticVersionCheck() {
return _nonOptimisticVersionCheck;
+ }
+
+ /**
+ * Whether or not JPQL extensions are allowed. Defaults to
+ * {@link #JPQL_STRICT}.
+ *
+ * @since 1.1.0
+ * @see #JPQL_WARN
+ * @see #JPQL_STRICT
+ * @see #JPQL_EXTENDED
+ */
+ public int getJPQL() {
+ return _jpql;
+ }
+
+ /**
+ * Whether or not JPQL extensions are allowed. Possible values: "warn",
+ * "strict", "extended".
+ *
+ * @since 1.1.0
+ * @see #JPQL_WARN
+ * @see #JPQL_STRICT
+ * @see #JPQL_EXTENDED
+ */
+ public void setJPQL(String jpql) {
+ if ("warn".equals(jpql))
+ _jpql = JPQL_WARN;
+ else if ("strict".equals(jpql))
+ _jpql = JPQL_STRICT;
+ else if ("extended".equals(jpql))
+ _jpql = JPQL_EXTENDED;
+ else
+ throw new IllegalArgumentException(jpql);
}
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ExpressionStoreQuery.java Wed Jan 23 23:33:32 2008
@@ -119,6 +119,10 @@
public OpenJPAConfiguration getConfiguration() {
return ctx.getStoreContext().getConfiguration();
}
+
+ public QueryContext getQueryContext() {
+ return ctx;
+ }
};
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/StoreContext.java Wed Jan 23 23:33:32 2008
@@ -46,8 +46,7 @@
/**
* Return the broker for this context, if possible. Note that a broker
- * will be unavailable in remote contexts, and this method may throw
- * an exception to that effect.
+ * will be unavailable in remote contexts, and this method may return null.
*/
public Broker getBroker();
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Resolver.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Resolver.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Resolver.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/exps/Resolver.java Wed Jan 23 23:33:32 2008
@@ -19,6 +19,7 @@
package org.apache.openjpa.kernel.exps;
import org.apache.openjpa.conf.OpenJPAConfiguration;
+import org.apache.openjpa.kernel.QueryContext;
/**
* A Resolver is used to resolve listeners and class or entity names
@@ -51,4 +52,11 @@
* Return the OpenJPA configuration.
*/
public OpenJPAConfiguration getConfiguration ();
+
+ /**
+ * The {@link QueryContext} for which this resolver was created
+ *
+ * @since 1.1.0
+ */
+ public QueryContext getQueryContext();
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/JPQLExpressionBuilder.java Wed Jan 23 23:33:32 2008
@@ -34,6 +34,8 @@
import org.apache.openjpa.kernel.ExpressionStoreQuery;
import org.apache.openjpa.kernel.QueryContext;
import org.apache.openjpa.kernel.QueryOperations;
+import org.apache.openjpa.kernel.StoreContext;
+import org.apache.openjpa.kernel.BrokerFactory;
import org.apache.openjpa.kernel.exps.AbstractExpressionBuilder;
import org.apache.openjpa.kernel.exps.Expression;
import org.apache.openjpa.kernel.exps.ExpressionFactory;
@@ -44,12 +46,15 @@
import org.apache.openjpa.kernel.exps.Subquery;
import org.apache.openjpa.kernel.exps.Value;
import org.apache.openjpa.lib.util.Localizer;
+import org.apache.openjpa.lib.log.Log;
import org.apache.openjpa.meta.ClassMetaData;
import org.apache.openjpa.meta.FieldMetaData;
import org.apache.openjpa.meta.MetaDataRepository;
import org.apache.openjpa.meta.ValueMetaData;
import org.apache.openjpa.util.InternalException;
import org.apache.openjpa.util.UserException;
+import org.apache.openjpa.conf.Compatibility;
+import org.apache.openjpa.conf.OpenJPAConfiguration;
import serp.util.Numbers;
/**
@@ -1078,17 +1083,53 @@
return factory.getCurrentTimestamp();
case JJTSELECTEXTENSION:
+ assertQueryExtensions("SELECT");
return eval(onlyChild(node));
case JJTGROUPBYEXTENSION:
+ assertQueryExtensions("GROUP BY");
return eval(onlyChild(node));
case JJTORDERBYEXTENSION:
+ assertQueryExtensions("ORDER BY");
return eval(onlyChild(node));
default:
throw parseException(EX_FATAL, "bad-tree",
new Object[]{ node }, null);
+ }
+ }
+
+ private void assertQueryExtensions(String clause) {
+ OpenJPAConfiguration conf = resolver.getConfiguration();
+ switch(conf.getCompatibilityInstance().getJPQL()) {
+ case Compatibility.JPQL_WARN:
+ // check if we've already warned for this query-factory combo
+ StoreContext ctx = resolver.getQueryContext().getStoreContext();
+ String query = currentQuery();
+ if (ctx.getBroker() != null && query != null) {
+ String key = getClass().getName() + ":" + query;
+ BrokerFactory factory = ctx.getBroker().getBrokerFactory();
+ Object hasWarned = factory.getUserObject(key);
+ if (hasWarned != null)
+ break;
+ else
+ factory.putUserObject(key, Boolean.TRUE);
+ }
+ Log log = conf.getLog(OpenJPAConfiguration.LOG_QUERY);
+ if (log.isWarnEnabled())
+ log.warn(_loc.get("query-extensions-warning", clause,
+ currentQuery()));
+ break;
+ case Compatibility.JPQL_STRICT:
+ throw new ParseException(_loc.get("query-extensions-error",
+ clause, currentQuery()).getMessage());
+ case Compatibility.JPQL_EXTENDED:
+ break;
+ default:
+ throw new IllegalStateException(
+ "Compatibility.getJPQL() == "
+ + conf.getCompatibilityInstance().getJPQL());
}
}
Modified: openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ParseException.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ParseException.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ParseException.java (original)
+++ openjpa/trunk/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/jpql/ParseException.java Wed Jan 23 23:33:32 2008
@@ -65,6 +65,18 @@
}
/**
+ * String constructor. Constructing the exception in this
+ * manner makes the exception behave in the normal way - i.e., as
+ * documented in the class "Throwable". The fields "errorToken",
+ * "expectedTokenSequences", and "tokenImage" do not contain
+ * relevant information. The JavaCC generated code does not use
+ * these constructors.
+ */
+ public ParseException(String message) {
+ super(message);
+ }
+
+ /**
* This method has the standard behavior when this object has been
* created using the standard constructors. Otherwise, it uses
* "currentToken" and "expectedTokenSequences" to generate a parse
Modified: openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt (original)
+++ openjpa/trunk/openjpa-kernel/src/main/jjtree/org/apache/openjpa/kernel/jpql/JPQL.jjt Wed Jan 23 23:33:32 2008
@@ -64,7 +64,6 @@
public class JPQL
{
String jpql;
- boolean extensionsEnabled = true;
public JPQL (String jpql)
@@ -503,7 +502,7 @@
}
-void select_extension() #SELECTEXTENSION(extensionsEnabled) : { }
+void select_extension() #SELECTEXTENSION : { }
{
scalar_function()
}
@@ -627,7 +626,7 @@
}
-void groupby_extension() #GROUPBYEXTENSION(extensionsEnabled) : { }
+void groupby_extension() #GROUPBYEXTENSION : { }
{
scalar_function()
}
@@ -1098,7 +1097,7 @@
}
-void orderby_extension() #ORDERBYEXTENSION(extensionsEnabled) : { }
+void orderby_extension() #ORDERBYEXTENSION : { }
{
aggregate_select_expression()
}
Modified: openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties (original)
+++ openjpa/trunk/openjpa-kernel/src/main/resources/org/apache/openjpa/kernel/jpql/localizer.properties Wed Jan 23 23:33:32 2008
@@ -58,3 +58,11 @@
update-constant-value: Update expression "{0}" may only use literals \
or parameters as update values.
bad-parse: Encountered "{0}" at character {1}, but expected: {2}.
+query-extensions-warning: This JPQL query uses non-standard OpenJPA \
+ extensions in the {0} clause. JPQL string: "{1}". Query execution will \
+ proceed. The openjpa.Compatibility configuration setting is configured to \
+ log a warning the first time a given extended query is encountered.
+query-extensions-error: This JPQL query uses non-standard OpenJPA \
+ extensions in the {0} clause. JPQL string: "{1}". The \
+ openjpa.Compatibility configuration setting is configured to disallow \
+ JPQL extensions.
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/GroupingTestCase.java Wed Jan 23 23:33:32 2008
@@ -38,7 +38,8 @@
protected abstract void prepareQuery(Query q);
public void setUp() {
- super.setUp(AllFieldTypes.class, CLEAR_TABLES);
+ super.setUp(AllFieldTypes.class, CLEAR_TABLES,
+ "openjpa.Compatibility", "JPQL=warn");
AllFieldTypes pc1 = new AllFieldTypes();
AllFieldTypes pc2 = new AllFieldTypes();
Modified: openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java
URL: http://svn.apache.org/viewvc/openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java?rev=614812&r1=614811&r2=614812&view=diff
==============================================================================
--- openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java (original)
+++ openjpa/trunk/openjpa-persistence-jdbc/src/test/java/org/apache/openjpa/persistence/query/TestSubstring.java Wed Jan 23 23:33:32 2008
@@ -25,7 +25,8 @@
public class TestSubstring extends SingleEMTestCase {
public void setUp() {
- super.setUp(SimpleEntity.class, CLEAR_TABLES, "openjpa.Log", "SQL=TRACE");
+ super.setUp(SimpleEntity.class, CLEAR_TABLES,
+ "openjpa.Compatibility", "JPQL=extended");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();