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();