openjpa-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ppod...@apache.org
Subject svn commit: r693646 - in /openjpa/branches/sql-cache: openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/ openjpa-kernel/src/main/java/org/apache/openjpa/kernel/ openjpa-persistence/src/main/java/org/apache/openjpa/persistence/
Date Tue, 09 Sep 2008 22:50:26 GMT
Author: ppoddar
Date: Tue Sep  9 15:50:25 2008
New Revision: 693646

URL: http://svn.apache.org/viewvc?rev=693646&view=rev
Log:
Support invalidation and switch SQL parameter marker parsing through hints

Modified:
    openjpa/branches/sql-cache/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
    openjpa/branches/sql-cache/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java
    openjpa/branches/sql-cache/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java

Modified: openjpa/branches/sql-cache/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
URL: http://svn.apache.org/viewvc/openjpa/branches/sql-cache/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java?rev=693646&r1=693645&r2=693646&view=diff
==============================================================================
--- openjpa/branches/sql-cache/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
(original)
+++ openjpa/branches/sql-cache/openjpa-jdbc/src/main/java/org/apache/openjpa/jdbc/kernel/SQLStoreQuery.java
Tue Sep  9 15:50:25 2008
@@ -44,6 +44,7 @@
 import org.apache.openjpa.jdbc.sql.SQLExceptions;
 import org.apache.openjpa.kernel.AbstractStoreQuery;
 import org.apache.openjpa.kernel.QueryContext;
+import org.apache.openjpa.kernel.QueryHints;
 import org.apache.openjpa.kernel.StoreQuery;
 import org.apache.openjpa.lib.rop.RangeResultObjectProvider;
 import org.apache.openjpa.lib.rop.ResultObjectProvider;
@@ -419,7 +420,10 @@
         public LinkedMap getParameterTypes(StoreQuery q) {
         	int count = -1;
         	try {
-        		count = countParamMarker(q.getContext().getQueryString());
+        		boolean simple = q.getContext().getFetchConfiguration()
+        			.getHint(QueryHints.HINT_PARAM_MARKER_IN_QUERY) == null;
+        		count = countParamMarker(q.getContext().getQueryString(), 
+        			simple);
         	} catch (IOException e) {
         		
         	}
@@ -430,18 +434,38 @@
             return map;
         }
         
-    	private static int countParamMarker(String sql) throws IOException {
+        /**
+         * Parse given SQL for parameter marker <code>?</code>. How to parse

+         * is controlled by the second boolean argument. The <em>simple</em>
+         * parse assumes that the given SQL string does not contain any
+         * <code>?</code> other than the parameter markers, which is usually
+         * the case and saves considerable computation time as revealed during
+         * profiling. 
+         * If the user query is using <code>?</code> character within the query
+         * itself then the user must instruct more complex parsing to be used
+         * by setting a {@link QueryHints#HINT_PARAM_MARKER_IN_QUERY hint}.
+         */
+    	private static int countParamMarker(String sql, boolean simple) 
+    		throws IOException {
     		if (sql.indexOf("?") == -1)
     			return 0;
-
-    		StreamTokenizer tok = new StreamTokenizer(new StringReader(sql));
-    		tok.resetSyntax();
-    		tok.quoteChar('\'');
-    		tok.wordChars('?', '?');
-    		int count = 0;
-    		for (int ttype; (ttype = tok.nextToken()) != StreamTokenizer.TT_EOF;) {
+			int count = 0;
+    		if (simple) {
+    			int index = -1;
+    			while ((index = sql.indexOf("?", index + 1)) != -1)
+    				count++;
+    			return count;
+    		} else {
+    			StreamTokenizer tok = new StreamTokenizer(
+    				new StringReader(sql));
+    			tok.resetSyntax();
+    			tok.quoteChar('\'');
+    			tok.wordChars('?', '?');
+    			for (int ttype; (ttype = tok.nextToken()) != 
+    				StreamTokenizer.TT_EOF;) {
     			if (ttype == StreamTokenizer.TT_WORD && "?".equals(tok.sval))
     				count++;
+    			}
     		}
         	return count;
     	}

Modified: openjpa/branches/sql-cache/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java
URL: http://svn.apache.org/viewvc/openjpa/branches/sql-cache/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java?rev=693646&r1=693645&r2=693646&view=diff
==============================================================================
--- openjpa/branches/sql-cache/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java
(original)
+++ openjpa/branches/sql-cache/openjpa-kernel/src/main/java/org/apache/openjpa/kernel/QueryHints.java
Tue Sep  9 15:50:25 2008
@@ -28,4 +28,29 @@
      */
     public static final String HINT_RESULT_COUNT =
         "openjpa.hint.OptimizeResultCount";
+    
+    /**
+     * Hints to signal that the JPQL/SQL query string contains a parameter
+     * marker <code>?</code> character. By default, the query string is parsed
+     * to count number of parameters assuming that all <code>?</code> characters
+     * designate a bind parameter. This assumption makes the parse faster.
+     */
+    public static final String HINT_PARAM_MARKER_IN_QUERY =
+    	"openjpa.hint.ParameterMarkerInQuery";
+    
+    /**
+     * A directive to invalidate any prepared SQL that might have been cached
+     * against a JPQL query. The target SQL corresponding to a JPQL depends on
+     * several context parameters such as fetch configuration, lock mode etc.
+     * If a query is executed repeatedly and hence its SQL is cached for faster
+     * execution then if any of the contextual parameters change across query
+     * execution then the user must supply this hint to invalidate the cached
+     * SQL query. 
+     * The alternative to monitor any such change for automatic invalidation 
+     * has a constant performance penalty for the frequent use case where a 
+     * query is repeatedly executed in different persistent context with the 
+     * same fetch plan or locking.  
+     */
+    public static final String HINT_INVALIDATE_PREPARED_QUERY =
+    	"openjpa.hint.InvalidatePreparedQuery";
 }

Modified: openjpa/branches/sql-cache/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
URL: http://svn.apache.org/viewvc/openjpa/branches/sql-cache/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java?rev=693646&r1=693645&r2=693646&view=diff
==============================================================================
--- openjpa/branches/sql-cache/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
(original)
+++ openjpa/branches/sql-cache/openjpa-persistence/src/main/java/org/apache/openjpa/persistence/QueryImpl.java
Tue Sep  9 15:50:25 2008
@@ -28,7 +28,6 @@
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.Set;
 
 import javax.persistence.FlushModeType;
 import javax.persistence.Query;
@@ -39,6 +38,7 @@
 import org.apache.openjpa.kernel.DelegatingQuery;
 import org.apache.openjpa.kernel.DelegatingResultList;
 import org.apache.openjpa.kernel.Filters;
+import org.apache.openjpa.kernel.QueryHints;
 import org.apache.openjpa.kernel.QueryLanguages;
 import org.apache.openjpa.kernel.QueryOperations;
 import org.apache.openjpa.kernel.exps.AggregateListener;
@@ -327,8 +327,6 @@
 				if (value instanceof String)
 					value = Boolean.valueOf((String) value);
 				setSubclasses(((Boolean) value).booleanValue());
-			} else if ("InvalidateCache".equals(k)) {
-				invalidate();
 			} else if ("FilterListener".equals(k))
 				addFilterListener(Filters.hintToFilterListener(value, _query
 						.getBroker().getClassLoader()));
@@ -361,8 +359,10 @@
 						throw new ArgumentException(_loc.get(
 								"bad-query-hint-value", key, value), null,
 								null, false);
-				}
-				_query.getFetchConfiguration().setHint(key, value);
+				} else if (QueryHints.HINT_INVALIDATE_PREPARED_QUERY.equals(key)) {
+					invalidatePreparedQueryCache();
+				} else 
+					_query.getFetchConfiguration().setHint(key, value);
 			} else
 				throw new ArgumentException(_loc.get("bad-query-hint", key),
 						null, null, false);
@@ -588,7 +588,10 @@
 		return cached;
 	}
 	
-	public boolean invalidate() {
+	/**
+	 * Remove this query from PreparedQueryCache. 
+	 */
+	public boolean invalidatePreparedQueryCache() {
 		Map cache = _em.getConfiguration().getPreparedQueryCacheInstance();
 		return cache != null && cache.remove(_id) != null;
 	}



Mime
View raw message