[teiid-commits] teiid SVN: r2492 - in branches/7.1.x: cache-jbosscache/src/main/java/org/teiid/cache/jboss and 11 other directories.

teiid-commits at lists.jboss.org teiid-commits at lists.jboss.org
Thu Aug 26 11:29:49 EDT 2010


Author: shawkins
Date: 2010-08-26 11:29:47 -0400 (Thu, 26 Aug 2010)
New Revision: 2492

Added:
   branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/hint-option.xml
   branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/results.xml
Removed:
   branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/cachehint.xml
   branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/resultset.xml
Modified:
   branches/7.1.x/build/kits/jboss-container/teiid-releasenotes.html
   branches/7.1.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/ClusterableCacheFactory.java
   branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/matviews.xml
   branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/main.xml
   branches/7.1.x/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
   branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCache.java
   branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCacheFactory.java
   branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
   branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
   branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
   branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java
   branches/7.1.x/engine/src/main/java/org/teiid/query/util/CommandContext.java
   branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties
   branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java
   branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
   branches/7.1.x/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
Log:
TEIID-1213 adding procedure result caching

Modified: branches/7.1.x/build/kits/jboss-container/teiid-releasenotes.html
===================================================================
--- branches/7.1.x/build/kits/jboss-container/teiid-releasenotes.html	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/build/kits/jboss-container/teiid-releasenotes.html	2010-08-26 15:29:47 UTC (rev 2492)
@@ -26,6 +26,7 @@
 </UL>
 <H2><A NAME="Highlights"></A>Highlights</H2>
 <UL>
+	<LI><B>Procedure Result Caching</B> - virtual procedure definitions may use a cache hint to cache results in the result set cache.
 	<LI><B>Improved Plan Caching</B> - plans used by internal materialization and stored procedure plans will be automatically cached in the prepared plan cache.  Improvements were also made to reduce the memory footprint of the plans.
     <LI><B>Refined Load Balancing and Fail Over</B> - clients can use use the statement "SET NEWINSTANCE TRUE" to allow their connection to select a new server instance.  See the Client Developer's Guide for more information. 
 </UL>

Modified: branches/7.1.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/ClusterableCacheFactory.java
===================================================================
--- branches/7.1.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/ClusterableCacheFactory.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/cache-jbosscache/src/main/java/org/teiid/cache/jboss/ClusterableCacheFactory.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -45,7 +45,7 @@
 		if (this.delegate == null) {
 			Object cacheManager = getClusteredCache();
 			if (cacheManager == null) {
-				this.delegate = new DefaultCacheFactory();
+				this.delegate = new DefaultCacheFactory(config);
 			}
 			else {
 				try {

Deleted: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/cachehint.xml
===================================================================
--- branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/cachehint.xml	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/cachehint.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -1,88 +0,0 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
-<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
-%CustomDTD;
-]>
-<chapter id="cache-hint">
-   	<title>Cache Hint</title>
-   	<para>A cache hint can be used to:</para>
-   	<itemizedlist>
-   		<listitem><para>Indicate that a user query is eligible for result set caching.
-   		</para></listitem>
-   		<listitem><para>Set the result set query cache entry memory preference or time to live. 
-   		</para></listitem>
-   		<listitem><para>Set the materialized view memory preference, time to live, or updatablity.
-   		</para></listitem>
-   	</itemizedlist>
-   	<para><synopsis>/*+ cache[([pref_mem] [ttl:n] [updatable])] */</synopsis>
-   	<itemizedlist>
-   		<listitem><para><emphasis>pref_mem</emphasis> - if present indicates that the cached results should prefer to remain in memory.  They are not however required to be memory only.
-   		</para></listitem>
-   		<listitem><para><emphasis>ttl:n</emphasis> - if present n indicates the time to live value in milliseconds.
-   		</para></listitem>
-   		<listitem><para><emphasis>updatable</emphasis> - if present indicates that the cached results can be updated.
-   		</para></listitem>
- 	</itemizedlist>
-   	</para>
-   	<section>
-   		<title>ResultSet Cache Query</title>
-   		<para>The most basic form of the cache hint, <code>/*+ cache */</code>, is sufficient to inform the engine that the results of the non-update command should be cached.</para>  
-   		<example>
-   			<title>PreparedStatement ResultSet Caching</title>
-   			<programlisting>...
-PreparedStatement ps = connection.prepareStatement("/*+ cache */ select col from t where col2 = ?");
-ps.setInt(1, 5);
-ps.execute();
-...</programlisting>
-			<para>While no options are specified with the cache hint, it still informs the engine to use ResultSet caching.</para>
-   		</example>
-   		<para>The pref_mem and ttl options may also be used for ResultSet cache queries, however updatable only has an effect on materialized view tables.</para> 
-   		<example>
-   			<title>Advanced ResultSet Caching</title>
-   			<programlisting>/*+ cache(pref_mem ttl:60000 */ select col from t</programlisting>
-   			<para>In this example the memory preference has been enabled and the time to live is set to 60000 milliseconds or 1 minute.  
-   			The ttl for an entry is actually treated as it's maximum age and the entry may be purged sooner if the maximum number of cache entries has been reached.</para>
-   		</example>
-   		<para>See the <link linkend="resultset">ResultSet Caching Chapter</link> for more.</para>
-   	</section>
-   	<section>
-   		<title>Materialized Views</title>
-   		<para>The cache hint, when used in the context of an internal materialized view transformation query, provides the ability to fine tune the materializated table.  
-   		The hint is not used for materialization targeted at an external source. See the <link linkend="resultset">Materialized View Chapter</link> for more on materialized views.</para>
-   		<para>The pref_mem option also applies to internal materialized views.  Internal table index pages already have a memory preference, so the perf_mem option indicates that the data pages should prefer memory as well.</para>
-   		<section>
-	   		<title>TTL Snapshot Refresh</title>
-	 		<para>When the ttl is specified in the cache hint, a full refresh of the materialized view will be triggered automatically after the specified time interval.  
-	 		The refresh is equivalent to <code>CALL SYS.refreshMatView('view name', false)</code>, but performed asynchronously so that user queries do not block on the load.
-	 		</para>
-	 		<section>
-	 			<title>Limitations</title>
-	 			<itemizedlist>
-			   		<listitem><para>The automatic ttl refresh is not intended for complex loading scenarios, as nested materialized views will be used by the refresh query.
-			   		</para></listitem>
-			   		<listitem><para>The automatic ttl refresh is performed lazily, that is it is only trigger by using the table after the ttl has expired.  
-			   		For infrequently used tables with long load times, this means that data may be used well past the intended ttl. 
-			   		</para></listitem>
-			  	</itemizedlist>
-	 		</section>
- 		</section>
- 		<section>
- 			<title>Updatable</title>
- 			<para>When the updatable option is specified, the materialized view may be targeted by the system function <code>refreshMatViewRow</code>.  
- 			The refreshMatViewRow function updates a single row of an internal materialized with the supplied key value.  
- 			The refresh query does use nested caches, so this refresh method should be used with caution.  
- 			</para>
- 			<para>When the updatable option is not specified, accessing the materialized view table is more efficient because modifications do not need to be considered.  
- 			Therefore, only specify the updatable option if row based incremental updates are needed.  Even when performing row updates, full snapshot refreshes may be needed to ensure consistency.</para>
- 		</section>
-   	</section>
-   	<section>
-   		<title>Limitations</title>
-   	<itemizedlist>
-   		<listitem><para>The form of the query hint must be matched exactly for the hint to have affect.  
-   		For a user query if the hint is not specified correctly, e.g. /*+ cach(pref_mem) */, it will not be used by the engine nor will 
-   		there be an informational log.  As a workaround, the query plan may be checked though (see the Client Developers Guide) to see if the user command
-   		in the plan has retained the proper hint.
-   		</para></listitem>
-  	</itemizedlist>
-   	</section>
-</chapter>
\ No newline at end of file

Copied: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/hint-option.xml (from rev 2478, branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/cachehint.xml)
===================================================================
--- branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/hint-option.xml	                        (rev 0)
+++ branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/hint-option.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -0,0 +1,60 @@
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
+%CustomDTD;
+]>
+<chapter id="cache-hint-options">
+    <title>Hints and Options</title>
+	<section id="cache-hint">
+		<title>Cache Hint</title>
+	   	<para>A query cache hint can be used to:</para>
+	   	<itemizedlist>
+	   		<listitem><para>Indicate that a user query is eligible for result set caching and set the cache entry memory preference or time to live.
+	   		</para></listitem>
+	   		<listitem><para>Set the materialized view memory preference, time to live, or updatablity.
+	   		</para></listitem>
+	   		<listitem><para>Indicate that a virtual procedure should be cachable and set the cache entry memory preference or time to live.
+	   		</para></listitem>
+	   	</itemizedlist>
+	   	<para><synopsis>/*+ cache[([pref_mem] [ttl:n] [updatable])] */ sql ...</synopsis>
+	   	<itemizedlist>
+	   		<listitem><para>The cache hint should appear at the beginning of the SQL.  It will not have any affect on INSERT/UPDATE/DELETE statements or virtual update procedure definitions.</para></listitem>
+	   		<listitem><para><emphasis>pref_mem</emphasis> - if present indicates that the cached results should prefer to remain in memory.  They are not however required to be memory only.
+	   		</para></listitem>
+	   		<listitem><para><emphasis>ttl:n</emphasis> - if present n indicates the time to live value in milliseconds.
+	   		</para></listitem>
+	   		<listitem><para><emphasis>updatable</emphasis> - if present indicates that the cached results can be updated.  This is currently only applicable to materialized views.
+	   		</para></listitem>
+	 	</itemizedlist>
+	   	</para>
+	   	   	<section>
+   		<title>Limitations</title>
+	   	<itemizedlist>
+	   		<listitem><para>The form of the query hint must be matched exactly for the hint to have affect.  
+	   		For a user query if the hint is not specified correctly, e.g. <code>/*+ cach(pref_mem) */</code>, it will not be used by the engine nor will 
+	   		there be an informational log.  As a workaround, the query plan may be checked though (see the Client Developers Guide) to see if the user command
+	   		in the plan has retained the proper hint.
+	   		</para></listitem>
+	  	</itemizedlist>
+	   	</section>
+   	</section>
+   	<section id="nocache">
+   		<title>OPTION NOCACHE</title>
+   		<para>Individual queries may override the use of cached results by
+			specifying <code>OPTION NOCACHE</code> on the query.  0 or more fully qualified view or procedure names may be specified to exclude using their cached results.  
+			If no names are specified, cached results will not be used transitively.
+		</para>
+		<example>
+			<title>Full NOCACHE</title>
+			<programlisting>SELECT * from vg1, vg2, vg3 WHERE … OPTION NOCACHE</programlisting>
+			<para>No cached results will be used at all.</para>
+		</example>
+		<example>
+			<title>Specific NOCACHE</title>
+			<programlisting>SELECT * from vg1, vg2, vg3 WHERE … OPTION NOCACHE vg1, vg3</programlisting>
+			<para>Only the vg1 and vg3 caches will be skipped, vg2 or any cached results nested under vg1 and vg3 will be used.</para>
+		</example>
+		<para><code>OPTION NOCACHE</code> may be specified in procedure or view definitions.  In that way, transformations can
+			specify to always use real-time data obtained directly from sources.
+			</para>
+   	</section>
+</chapter>
\ No newline at end of file


Property changes on: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/hint-option.xml
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Modified: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/matviews.xml
===================================================================
--- branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/matviews.xml	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/matviews.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -27,35 +27,14 @@
 			</listitem>
 			<listitem>
 				<para>User ability to override use of materialized view cache for
-					specific queries through OPTION NO CACHE</para>
+					specific queries through <code>OPTION NOCACHE</code></para>
 			</listitem>
 		</itemizedlist>
 	</section>
 	<section>
 		<title>User Interaction</title>
-		<para>When client applications issue queries against a Relational
-			table or view that has been defined as a materialized view, the
-			Teiid query engine automatically routes that query to obtain the
-			results from the cache database.</para>
-		<para>Individual queries may override the use of materialized views by
-			specifying OPTION NOCACHE on the query.  This parameter may specify
-			one or more virtual groups to override (separated by commas, spaces
-			optional).  If no virtual groups are specified, materialized views tables will not be used transitively. 
-		</para>
-		<example>
-			<title>Full NOCACHE</title>
-			<programlisting>SELECT * from vg1, vg2, vg3 WHERE … OPTION NOCACHE</programlisting>
-		</example>
-		<example>
-			<title>Specific NOCACHE</title>
-			<programlisting>SELECT * from vg1, vg2, vg3 WHERE … OPTION NOCACHE vg1, vg3</programlisting>
-			<para>Only the vg1 and vg3 caches will be skipped vg2 or any materialized views nested under vg1 and vg3 will be used.</para>
-		</example>
-		<para>Option NOCACHE may be specified in virtual
-			group transformation queries.  In that way, transformations can
-			specify to always use real-time data obtained directly from a source.
-			 The use of caching and non-caching can be mixed in transformation
-			definitions, just as with user queries.</para>
+		<para>Similar to cached procedures, materialized view tables are used automatically when a query accesses the corresponding view.  
+		Usage of the cached results may be bypassed with an <code>OPTION NOCACHE</code> clause.  See the <link linkend="nocache">OPTION NOCACHE</link> section for more on its usage.</para>
 	</section>
 	<section>
 		<title>Materialized View Definition</title>
@@ -77,6 +56,9 @@
 			</listitem>
 		</itemizedlist>
 		</para>
+		<note><para>Materialized view tables are always scoped to the VDB.  If a materialized view definition directly or transitively contains a non-deterministic 
+		function call, such as random or hasRole, the resulting table will contain only the initially evaluated values.  In most instances you should consider 
+		nesting a materialized view without the deterministic results that is joined with relevant non-deterministic values in a parent view.</para></note>
 	</section>
 	<section>
 		<title>External Materialization</title>
@@ -112,6 +94,7 @@
 		<para>Internal materialization creates Teiid temporary tables to hold the materialized table.  While these tables are not fully durable, they perform 
 		well in most circumstances and the data is present at each Teiid instance which removes the single point of failure and network overhead of an external database. 
 		Internal materialization also provides more built-in facilities for refreshing and monitoring.</para>
+		<para>The cache hint, when used in the context of an internal materialized view transformation query, provides the ability to fine tune the materializated table.  The pref_mem option also applies to internal materialized views.  Internal table index pages already have a memory preference, so the perf_mem option indicates that the data pages should prefer memory as well.</para>
 		<section>
 			<title>Loading And Refreshing</title>
 			<para>An internal materialized view table is initially in an invalid state (there is no data).  The first user query will trigger an implicit loading of the data.  
@@ -128,27 +111,47 @@
 			subsequent refreshes performed with <code>refreshMatView</code> will use dependent materialized view tables if they exist.  Only one load may occur at a time.  If a load is already in progress when
 			the <code>SYS.refreshMatView</code> procedure is called, it will return -1 immediately rather than preempting the current load.
 			</para>
-			<para>The <link linkend="cache-hint">cache hint</link> may be used to automatically trigger a full snapshot refresh after a specified time to live.
-			<example>
-				<title>Auto-refresh Transformation Query</title>
-				<programlisting>/*+ cache(ttl:3600000) */ select t.col, t1.col from t, t1 where t.id = t1.id</programlisting>
-			</example>
-			</para>
-			<para>In advanced use-cases the <link linkend="cache-hint">cache hint</link> may also be used to mark an internal materialized view as updatable.
-			An updatable internal materialized view may use the <code>SYS.refreshMatViewRow</code> procedure to update a single row in the materialized table.
-			To be updatable the materialized view must have a single column primary key.  Composite keys are not yet supported by <code>SYS.refreshMatViewRow</code>.
-			<example>
-				<title>Updatable Scenario</title>
-				<para>Transofrmation Query: <programlisting>/*+ cache(updatable) */ select t.col, t1.col from t, t1 where t.id = t1.id</programlisting></para>
-				<para>Update: <programlisting>CALL SYS.updateMatViewRow(viewname=>'schema.matview', key=>5)</programlisting></para>
-				<para>Given that the schema.matview defines interger column col as it's primary key, the update will check the live source(s) for the row values.  
-				If it exists, the materialized view table row will be updated.  If it does not exist the correpsonding row will be deleted.</para>
-			</example>
-			The update query will not use dependent materialized view tables, so care should be taken to ensure that getting a single 
-			row from this transformation query performs well.  This may require the use of depedent join hints.
-			When the updatable option is not specified, accessing the materialized view table is more efficient because modifications do not need to be considered.  
- 			Therefore, only specify the updatable option if row based incremental updates are needed.  Even when performing row updates, full snapshot refreshes may be needed to ensure consistency.
-			</para>
+			<section>
+		   		<title>TTL Snapshot Refresh</title>
+		   		<para>The <link linkend="cache-hint">cache hint</link> may be used to automatically trigger a full snapshot refresh after a specified time to live.  
+		   		The refresh is equivalent to <code>CALL SYS.refreshMatView('view name', false)</code>, but performed asynchronously so that user queries do not block on the load.</para>
+				<example>
+					<title>Auto-refresh Transformation Query</title>
+					<programlisting>/*+ cache(ttl:3600000) */ select t.col, t1.col from t, t1 where t.id = t1.id</programlisting>
+					<para>The resulting materialized view will be reloaded every hour (3600000 milliseconds).</para>
+				</example>
+		 		<section>
+		 			<title>Limitations</title>
+		 			<itemizedlist>
+				   		<listitem><para>The automatic ttl refresh is not intended for complex loading scenarios, as nested materialized views will be used by the refresh query.
+				   		</para></listitem>
+				   		<listitem><para>The automatic ttl refresh is performed lazily, that is it is only trigger by using the table after the ttl has expired.  
+				   		For infrequently used tables with long load times, this means that data may be used well past the intended ttl. 
+				   		</para></listitem>
+				  	</itemizedlist>
+		 		</section>
+	 		</section>
+	 		<section>
+	 			<title>Updatable</title>
+	 			<para>In advanced use-cases the <link linkend="cache-hint">cache hint</link> may also be used to mark an internal materialized view as updatable.
+				An updatable internal materialized view may use the <code>SYS.refreshMatViewRow</code> procedure to update a single row in the materialized table.
+				If the source row exists, the materialized view table row will be updated.  If the source row does not exist, the correpsonding materialized row will be deleted.
+				To be updatable the materialized view must have a single column primary key.  Composite keys are not yet supported by <code>SYS.refreshMatViewRow</code>.
+				<example>
+					<title>Updatable Transformation Query</title>
+					<para>Transofrmation Query: <programlisting>/*+ cache(updatable) */ select t.col, t1.col from t, t1 where t.id = t1.id</programlisting></para>
+					<para>Update SQL: <programlisting>CALL SYS.updateMatViewRow(viewname=>'schema.matview', key=>5)</programlisting></para>
+					<para>Given that the schema.matview defines an interger column col as it's primary key, the update will check the live source(s) for the row values.</para>
+				</example>
+				The update query will not use dependent materialized view tables, so care should be taken to ensure that getting a single 
+				row from this transformation query performs well.  See the Reference Guide for information on controlling dependent joins, which may be applicable to increasing the performance of retrieving a single row.
+			    The refresh query does use nested caches, so this refresh method should be used with caution.
+			    </para>
+			    <para>
+				When the updatable option is not specified, accessing the materialized view table is more efficient because modifications do not need to be considered.  
+	 			Therefore, only specify the updatable option if row based incremental updates are needed.  Even when performing row updates, full snapshot refreshes may be needed to ensure consistency.
+				</para>
+	 		</section>
 		</section>
 		<section>
 			<title>Limitations</title>
@@ -157,4 +160,4 @@
 			</itemizedlist>
 		</section>
 	</section>
-</chapter>
\ No newline at end of file
+</chapter>

Copied: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/results.xml (from rev 2478, branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/resultset.xml)
===================================================================
--- branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/results.xml	                        (rev 0)
+++ branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/results.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -0,0 +1,138 @@
+<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
+<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
+%CustomDTD;
+]>
+<chapter id="results">
+	<title>Results Caching</title>
+	<para>Teiid provides the capability to cache the results of
+		specific user queries and virtual procedure calls.  This caching technique
+		can yield significant performance gains if users of the system submit
+		the same queries or execute the same procedures often.</para>
+	<section>
+		<title>Support Summary</title>
+		<itemizedlist>
+			<listitem>
+				<para>Caching of user query results including XML document model results.</para>
+			</listitem>
+			<listitem>
+				<para>Caching of virtual procedure results.</para>
+			</listitem>
+			<listitem>
+				<para>Scoping of results is automatically determined to be VDB/user (replicated) or session level.</para>
+			</listitem>
+			<listitem>
+				<para>Configurable number of cache entries and time to live.</para>
+			</listitem>
+			<listitem>
+				<para>Administrative clearing.</para>
+			</listitem>
+		</itemizedlist>
+	</section>
+	<section>
+		<title>User Interaction</title>
+		<section>
+	   		<title>User Query Cache</title>
+	   				<para>User query result set caching will cache result sets based on an exact match
+			of the incoming SQL string and PreparedStatement parameter values if present. Caching only applies to SELECT, set query, and stored procedure execution
+			statements; it does not apply to SELECT INTO statements, or INSERT,
+			UPDATE, or DELETE statements.</para>
+			<para>End users or client applications explicitly state whether to use
+				result set caching.  This can be done by setting the
+				JDBC ResultSetCacheMode execution property to true (default false) or by adding a <link linkend="cache-hint">cache hint</link> to the query.  
+				Note that if either of these mechanisms are used, Teiid must also have result set caching enabled (the default is enabled).</para>
+	   		<para>The most basic form of the cache hint, <code>/*+ cache */</code>, is sufficient to inform the engine that the results of the non-update command should be cached.</para>  
+	   		<example>
+	   			<title>PreparedStatement ResultSet Caching</title>
+	   			<programlisting>...
+PreparedStatement ps = connection.prepareStatement("/*+ cache */ select col from t where col2 = ?");
+ps.setInt(1, 5);
+ps.execute();
+...</programlisting>
+				<para>The results will be cached with the default ttl and use the SQL string and the parameter value as part of the cache key.</para>
+	   		</example>
+	   		<para>The pref_mem and ttl options of the cache hint may also be used for result set cache queries.
+	   		If a cache hint is not specified, then the default time to live of the result set caching configuration will be used.
+			</para> 
+	   		<example>
+	   			<title>Advanced ResultSet Caching</title>
+	   			<programlisting>/*+ cache(pref_mem ttl:60000 */ select col from t</programlisting>
+	   			<para>In this example the memory preference has been enabled and the time to live is set to 60000 milliseconds or 1 minute.  
+	   			The ttl for an entry is actually treated as it's maximum age and the entry may be purged sooner if the maximum number of cache entries has been reached.</para>
+	   		</example>
+			<note><para>Each query is re-checked for authorization using the current user’s permissions, 
+			regardless of whether or not the results have been cached.</para></note>
+		</section>
+   	    <section>
+			<title>Procedure Result Cache</title>
+			<para>Similar to materialized views, cached virtual procedure results are used automatically when a matching set of parameter values is detected for the same procedure execution.  
+			Usage of the cached results may be bypassed with an <code>OPTION NOCACHE</code> clause.  See the <link linkend="nocache">OPTION NOCACHE</link> section for more on its usage.</para>
+		</section>
+	</section>
+	<section>
+		<title>Cached Virtual Procedure Definition</title>
+		<para>To indicate that a virtual procedure (only definable by Teiid Designer) should be cached, it's definition should include a <link linkend="cache-hint">cache hint</link>.
+		<example>
+	   		<title>Procedure Caching</title>
+	   		<programlisting>/*+ cache */ CREATE VIRTUAL PROCEDURE
+BEGIN
+	...
+END</programlisting>
+			<para>Results will be cached with the default ttl.</para>
+	   	</example>
+	    The pref_mem and ttl options of the cache hint may also be used for procedure caching.
+		</para>
+		<para>Procedure results cache keys include the input parameter values.  
+		To prevent one procedure from filling the cache, at most 256 cache keys may be created per procedure per VDB.</para>
+		<para>A cached procedure will always produce all of its results prior to allowing those results to be consumed and placed in the cache.  
+		This differs from normal procedure execution which in some situations allows the returned results to be consumed in a streaming manner.</para>
+	</section>
+	<section>
+		<title>Cache Configuration</title>
+		<para>By default result set caching is enabled with 1024 maximum entries with a maximum entry age of 2 hours.  
+		There are actually 2 caches configured with these settings.  One cache holds results that are specific to sessions and is local to each Teiid instance.
+    	The other cache holds VDB scoped results and can be replicated.  
+    	See the &jboss-beans; config file or the Console's "Runtime Engine Properties" for tuning the configuration.  
+    	The user may also override the default maximum entry age via the <link linkend="cache-hint">cache hint</link>.
+    	</para>
+		<para>Result set caching is not limited to memory.  There is no explicit limit on the size of the results that can be cached.  
+		Cached results are primarily stored in the BufferManager and are subject to it's configuration - including the restriction of maximum buffer space.
+		</para>
+		<note><para>While the result data is not held in memory, cache keys - including parameter values - may be held in memory.  
+		Thus the cache should not be given an unlimited maximum size.</para></note>
+	</section>
+	<section>
+		<title>Cache Administration</title>
+		<para>The result set cache can be cleared through the AdminAPI using the <code>clearCache</code> method.  
+		The expected cache key is "QUERY_SERVICE_RESULT_SET_CACHE".</para>
+		<example>
+			<title>Clearing the ResultSet Cache in AdminShell</title>
+			<programlisting>connectAsAdmin()
+clearCache("QUERY_SERVICE_RESULT_SET_CACHE")
+...</programlisting>
+		</example>
+		<para>See the Admin Guide for more on using the AdminAPI and AdminShell.</para>
+	</section>
+	<section>
+		<title>Limitations</title>
+		<itemizedlist>
+			<listitem>
+				<para>Non-XML document model results, BLOBs, CLOBs, and OBJECT typed values cannot be cached.</para>
+			</listitem>
+			<listitem>
+				<para>XML, BLOB, CLOB, and OBJECT type cannot be used as part of the cache key for prepared statement of procedure cache keys.</para>
+			</listitem>
+			<listitem>
+				<para>The exact SQL string, including the cache hint if present, must match the cached entry for the results to be reused.  
+				This allows cache usage to skip parsing and resolving for faster responses.</para>
+			</listitem>
+			<listitem>
+				<para>Result set caching is not transactional.  Transactions depend on (and
+					enforce) consistency of data, and cached data is not guaranteed
+					to be consistent with the data store’s data.</para>
+			</listitem>
+			<listitem>
+				<para>Clearing the results cache clears all cache entries for all VDBs.</para>
+			</listitem>
+		</itemizedlist>
+	</section>
+</chapter>
\ No newline at end of file


Property changes on: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/results.xml
___________________________________________________________________
Name: svn:mime-type
   + text/plain

Deleted: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/resultset.xml
===================================================================
--- branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/resultset.xml	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/content/resultset.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -1,93 +0,0 @@
-<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd" [
-<!ENTITY % CustomDTD SYSTEM "../../../../../../docbook/custom.dtd">
-%CustomDTD;
-]>
-<chapter id="resultset">
-	<title>Result Set Caching</title>
-	<para>Teiid provides the capability to cache the results of
-		specific user queries.  When the
-		exact same user query is submitted to Teiid, the
-		cached results will be returned.  This caching technique
-		can yield significant performance gains if users of the system submit
-		the same queries often.</para>
-	<para>Result set caching will cache result sets based on an exact match
-		of the incoming SQL string and PreparedStatement parameter values if present. Caching only applies to SELECT, set query, and stored procedure execution
-		statements; it does not apply to SELECT INTO statements, or INSERT,
-		UPDATE, or DELETE statements.</para>
-	<section>
-		<title>Support Summary</title>
-		<itemizedlist>
-			<listitem>
-				<para>Caching of user query results.</para>
-			</listitem>
-			<listitem>
-				<para>Scoping of results is automatically determined to be either VDB (replicated) or session level.</para>
-			</listitem>
-			<listitem>
-				<para>Caching of XML document model results.</para>
-			</listitem>
-			<listitem>
-				<para>Configurable number of cache entries and time to live.</para>
-			</listitem>
-			<listitem>
-				<para>Administrative clearing.</para>
-			</listitem>
-		</itemizedlist>
-	</section>
-	<section>
-		<title>User Interaction</title>
-		<para>End users or client applications explicitly state whether to use
-			result set caching.  This can be done by setting the
-			JDBC ResultSetCacheMode execution property to true (default false) or by adding a <link linkend="cache-hint">cache hint</link> to the query.  
-			Note that if either of these mechanisms are used, Teiid must also have result set caching enabled (the default is enabled).</para>
-		<para>
-		To control the preference of individual results to remain in memory or the time to live see the <link linkend="cache-hint">cache hint</link>.
-		If a cache hint is not specified, then the default time to live of the result set caching configuration will be used.
-		</para>
-		<note><para>Each query is re-checked for authorization using the current user’s permissions, 
-		regardless of whether or not the results have been cached.</para></note>
-	</section>
-	<section>
-		<title>Cache Configuration</title>
-		<para>By default result set caching is enabled with 1024 maximum entries with a maximum entry age of 2 hours.  
-		There are actually 2 caches configured with these settings.  One cache holds results that are specific to sessions and is local to each Teiid instance.
-    	The other cache holds VDB scoped results and can be replicated.  
-    	See the &jboss-beans; config file or the Console's "Runtime Engine Properties" for tuning the configuration.  
-    	The user may also override the default maximum entry age via the <link linkend="cache-hint">cache hint</link>.</para>
-		<para>Result set caching is not limited to memory.  There is no explicit limit on the size of the results that can be cached.  
-		Cached results are primarily stored in the BufferManager and are subject to it's configuration - including the restriction of maximum buffer space.
-		</para>
-	</section>
-	<section>
-		<title>Cache Administration</title>
-		<para>The result set cache can be cleared through the AdminAPI using the <code>clearCache</code> method.  
-		The expected cache key is "QUERY_SERVICE_RESULT_SET_CACHE".</para>
-		<example>
-			<title>Clearing the ResultSet Cache in AdminShell</title>
-			<programlisting>connectAsAdmin()
-clearCache("QUERY_SERVICE_RESULT_SET_CACHE")
-...</programlisting>
-		</example>
-		<para>See the Admin Guide for more on using the AdminAPI and AdminShell.</para>
-	</section>
-	<section>
-		<title>Limitations</title>
-		<itemizedlist>
-			<listitem>
-				<para>Non-XML document model results, BLOBs, and CLOBs cannot be cached.</para>
-			</listitem>
-			<listitem>
-				<para>The exact SQL string, including the cache hint if present, must match the cached entry for the results to be reused.  
-				This allows cache usage to skip parsing and resolving for faster responses.</para>
-			</listitem>
-			<listitem>
-				<para>Result set caching is not transactional.  Transactions depend on (and
-					enforce) consistency of data, and cached data is not guaranteed
-					to be consistent with the data store’s data.</para>
-			</listitem>
-			<listitem>
-				<para>Clearing the result set cache clears all cache entries for all VDBs.</para>
-			</listitem>
-		</itemizedlist>
-	</section>
-</chapter>
\ No newline at end of file

Modified: branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/main.xml
===================================================================
--- branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/main.xml	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/documentation/caching-guide/src/main/docbook/en-US/main.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -47,8 +47,8 @@
   </bookinfo>
   <toc />
   <xi:include href="content/overview.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-  <xi:include href="content/resultset.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="content/results.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
+  <xi:include href="content/matviews.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
   <xi:include href="content/codetable.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-  <xi:include href="content/matviews.xml" xmlns:xi="http://www.w3.org/2001/XInclude" />
-  <xi:include href="content/cachehint.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> 
+  <xi:include href="content/hint-option.xml" xmlns:xi="http://www.w3.org/2001/XInclude" /> 
 </book>
\ No newline at end of file

Modified: branches/7.1.x/documentation/reference/src/main/docbook/en-US/content/sql_support.xml
===================================================================
--- branches/7.1.x/documentation/reference/src/main/docbook/en-US/content/sql_support.xml	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/documentation/reference/src/main/docbook/en-US/content/sql_support.xml	2010-08-26 15:29:47 UTC (rev 2492)
@@ -1126,9 +1126,10 @@
           <para>OPTION NOCACHE</para>
         </listitem>
       </itemizedlist>
-      <para>Previous versions of Teiid accepted the PLANONLY, DEBUG, and SHOWPLAN option arguments.  These are no longer accepted in the OPTION clause.
+      <para>All tables specified in the OPTION clause should be fully qualified.</para>
+      <note><para>Previous versions of Teiid accepted the PLANONLY, DEBUG, and SHOWPLAN option arguments.  These are no longer accepted in the OPTION clause.
       Please see the Client Developers Guide for replacements to those options.
-      </para>
+      </para></note>
     </section>
   </section>
   <section id="set_operations">

Modified: branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCache.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCache.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCache.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -139,7 +139,11 @@
 		if (ttl < 0) {
 			return Long.MAX_VALUE;
 		}
-		return System.currentTimeMillis() + ttl;
+		long result = System.currentTimeMillis() + ttl;
+		if (result < ttl) {
+			result = Long.MAX_VALUE;
+		}
+		return result;
 	}
 	
 	public V put(K key, V value, Long timeToLive) {

Modified: branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCacheFactory.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCacheFactory.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/cache/DefaultCacheFactory.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -34,8 +34,12 @@
 	private volatile boolean destroyed = false;
 	
 	public DefaultCacheFactory() {
-		this.cacheRoot = new DefaultCache("Teiid"); //$NON-NLS-1$
+		this(CacheConfiguration.DEFAULT);
 	}
+		
+	public DefaultCacheFactory(CacheConfiguration config) {
+		this.cacheRoot = new DefaultCache("Teiid", config.getMaxEntries(), config.getMaxAgeInSeconds()*1000); //$NON-NLS-1$
+	}
 	
 	@Override
 	public void destroy() {

Modified: branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/CachedResults.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -88,6 +88,10 @@
 		this.hint = command.getCacheHint();
 	}
 	
+	public void setHint(CacheHint hint) {
+		this.hint = hint;
+	}
+	
 	public CacheHint getHint() {
 		return hint;
 	}

Modified: branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/DQPCore.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -339,7 +339,7 @@
 	    request.initialize(requestMsg, bufferManager,
 				dataTierMgr, transactionService, state.sessionTables,
 				workContext, this.useEntitlements, this.prepPlanCache);
-		
+		request.setResultSetCacheEnabled(this.rsCache != null);
         ResultsFuture<ResultsMessage> resultsFuture = new ResultsFuture<ResultsMessage>();
         RequestWorkItem workItem = new RequestWorkItem(this, requestMsg, request, resultsFuture.getResultsReceiver(), requestID, workContext);
     	logMMCommand(workItem, Event.NEW, null); 
@@ -657,7 +657,7 @@
         this.processWorkerPool = new ThreadReuseExecutor(DQPConfiguration.PROCESS_PLAN_QUEUE_NAME, config.getMaxThreads());
         
         dataTierMgr = new TempTableDataManager(new DataTierManagerImpl(this,
-                                            this.bufferService), this.bufferManager, this.processWorkerPool); 
+                                            this.bufferService), this.bufferManager, this.processWorkerPool, this.rsCache); 
 	}
 	
 	public void setBufferService(BufferService service) {

Modified: branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/Request.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/Request.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -131,6 +131,7 @@
     protected boolean useEntitlements;
 	private TempTableStore globalTables;
 	private SessionAwareCache<PreparedPlan> planCache;
+	private boolean resultSetCacheEnabled = true;
 
     void initialize(RequestMessage requestMsg,
                               BufferManager bufferManager,
@@ -161,6 +162,10 @@
 		this.metadata = metadata;
 		this.multiSourceModels = multiSourceModels;
 	}
+	
+	public void setResultSetCacheEnabled(boolean resultSetCacheEnabled) {
+		this.resultSetCacheEnabled = resultSetCacheEnabled;
+	}
     
 	/**
 	 * if the metadata has not been supplied via setMetadata, this method will create the appropriate state
@@ -260,6 +265,7 @@
         context.setMetadata(this.metadata);
         context.setBufferManager(this.bufferManager);
         context.setPreparedPlanCache(planCache);
+        context.setResultSetCacheEnabled(this.resultSetCacheEnabled);
     }
 
     protected void checkReferences(List<Reference> references) throws QueryValidatorException {

Modified: branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/dqp/internal/process/SessionAwareCache.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -35,6 +35,7 @@
 import org.teiid.cache.DefaultCacheFactory;
 import org.teiid.cache.CacheConfiguration.Policy;
 import org.teiid.common.buffer.BufferManager;
+import org.teiid.core.types.DataTypeManager;
 import org.teiid.core.util.EquivalenceUtil;
 import org.teiid.core.util.HashCodeUtil;
 import org.teiid.query.function.metadata.FunctionMethod;
@@ -46,7 +47,7 @@
  * This class is used to cache session aware objects
  */
 public class SessionAwareCache<T> {
-	public static final int DEFAULT_MAX_SIZE_TOTAL = 250;
+	public static final int DEFAULT_MAX_SIZE_TOTAL = 512;
 
 	private Cache<CacheID, T> localCache;
 	private Cache<CacheID, T> distributedCache;
@@ -58,7 +59,7 @@
 	private BufferManager bufferManager;
 	
 	public SessionAwareCache(){
-		this(new DefaultCacheFactory(), Cache.Type.RESULTSET, new CacheConfiguration(Policy.LRU, 60, DEFAULT_MAX_SIZE_TOTAL));
+		this(DEFAULT_MAX_SIZE_TOTAL);
 	}
 	
 	SessionAwareCache(int maxSize){
@@ -188,16 +189,28 @@
 			this.sessionId = sessionId;
 		}
 		
+		/**
+		 * Set the raw (non-Constant) parameter values.
+		 * @param parameters
+		 * @return
+		 */
 		public boolean setParameters(List<?> parameters) {
 			if (parameters !=  null && !parameters.isEmpty()) {
 				this.parameters = new ArrayList<Serializable>();
 				for (Object obj:parameters) {
-					if (obj instanceof Serializable && obj instanceof Comparable<?>) {
-						this.parameters.add((Serializable)obj);
+					if (obj == null) {
+						this.parameters.add(null);
+						continue;
 					}
-					else{
+					if (!(obj instanceof Serializable)) {
 						return false;
 					}
+					
+					Class<?> type = DataTypeManager.determineDataTypeClass(obj);
+					if (DataTypeManager.isLOB(type) || type == DataTypeManager.DefaultDataClasses.OBJECT) {
+						return false;
+					}
+					this.parameters.add((Serializable)obj);
 				}
 			}
 			return true;

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/optimizer/relational/RelationalPlanner.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -483,6 +483,22 @@
 			}
 		}
 		if (c != null) {
+			if (c.getCacheHint() != null) {
+				if (container instanceof StoredProcedure) {
+					boolean noCache = isNoCacheGroup(metadata, ((StoredProcedure) container).getProcedureID(), option);
+					if (!noCache) {
+						if (container.areResultsCachable() && Query.areResultsCachable(container.getProcedureParameters().keySet()) && context.isResultSetCacheEnabled()) {
+							container.getGroup().setGlobalTable(true);
+							container.setCacheHint(c.getCacheHint());
+							recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW, "SimpleQueryResolver.procedure_cache_used", container.getGroup()); //$NON-NLS-1$
+							return;
+						}
+						recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.MEDIUM, "SimpleQueryResolver.procedure_cache_not_usable", container.getGroup()); //$NON-NLS-1$
+					} else {
+						recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW, "SimpleQueryResolver.procedure_cache_not_used", container.getGroup()); //$NON-NLS-1$
+					}
+				}
+			}
 			//skip the rewrite here, we'll do that in the optimizer
 			//so that we know what the determinism level is.
 			addNestedCommand(sourceNode, container.getGroup(), container, c, false);
@@ -925,14 +941,14 @@
         		//not use cache
         		qnode = metadata.getVirtualPlan(metadataID);
         		//TODO: update the table for defaultMat
-        		recordMaterializationTableAnnotation(analysisRecord, QueryPlugin.Util.getString("SimpleQueryResolver.materialized_table_not_used", virtualGroup, matTableName)); //$NON-NLS-1$
+        		recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW, "SimpleQueryResolver.materialized_table_not_used", virtualGroup, matTableName); //$NON-NLS-1$
         	}else{
         		qnode = new QueryNode(groupName, null);
         		Query query = createMatViewQuery(matMetadataId, matTableName, Arrays.asList(new AllSymbol()), isImplicitGlobal);
         		query.setCacheHint(hint);
         		qnode.setCommand(query);
                 cacheString = "matview"; //$NON-NLS-1$
-                recordMaterializationTableAnnotation(analysisRecord, QueryPlugin.Util.getString("SimpleQueryResolver.Query_was_redirected_to_Mat_table", virtualGroup, matTableName)); //$NON-NLS-1$
+                recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW, "SimpleQueryResolver.Query_was_redirected_to_Mat_table", virtualGroup, matTableName); //$NON-NLS-1$
         	}
         } else {
             // Not a materialized view - query the primary transformation
@@ -981,13 +997,13 @@
 					Command c = getCommand(table, metadata.getVirtualPlan(table.getMetadataID()), SQLConstants.Reserved.SELECT, metadata, analysisRecord);
 					CacheHint hint = c.getCacheHint();
 					if (hint != null) {
-						recordMaterializationTableAnnotation(analysisRecord, QueryPlugin.Util.getString("SimpleQueryResolver.cache_hint_used", table, matTableName, hint)); //$NON-NLS-1$
+						recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW, "SimpleQueryResolver.cache_hint_used", table, matTableName, id.getCacheHint()); //$NON-NLS-1$
 					}
 					id.setCacheHint(hint);
 				}
 			}
 		} else if (id.getCacheHint() != null) {
-			recordMaterializationTableAnnotation(analysisRecord, QueryPlugin.Util.getString("SimpleQueryResolver.cache_hint_used", table, matTableName, id.getCacheHint())); //$NON-NLS-1$
+			recordAnnotation(analysisRecord, Annotation.MATERIALIZED_VIEW, Priority.LOW, "SimpleQueryResolver.cache_hint_used", table, matTableName, id.getCacheHint()); //$NON-NLS-1$
 		}
 		return id;
 	}
@@ -1042,15 +1058,14 @@
         return false;
     }
     
-    private static void recordMaterializationTableAnnotation(AnalysisRecord analysis,
-                                                      String msg) {
-        if ( analysis.recordAnnotations() ) {
-            Annotation annotation = new Annotation(Annotation.MATERIALIZED_VIEW, 
-                                                         msg, 
-                                                         null, 
-                                                         Priority.LOW);
-            analysis.addAnnotation(annotation);
-        }
+    private static void recordAnnotation(AnalysisRecord analysis, String type, Priority priority, String msgKey, Object... parts) {
+    	if (analysis.recordAnnotations()) {
+    		Annotation annotation = new Annotation(type, 
+                    QueryPlugin.Util.getString(msgKey, parts), 
+                    null, 
+                    priority);
+    		analysis.addAnnotation(annotation);
+    	}
     }
 
 }
\ No newline at end of file

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/tempdata/TempTableDataManager.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -24,6 +24,7 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.LinkedList;
 import java.util.List;
 import java.util.concurrent.Callable;
 import java.util.concurrent.Executor;
@@ -36,12 +37,16 @@
 import org.teiid.api.exception.query.QueryValidatorException;
 import org.teiid.common.buffer.BlockedException;
 import org.teiid.common.buffer.BufferManager;
+import org.teiid.common.buffer.TupleBuffer;
 import org.teiid.common.buffer.TupleSource;
 import org.teiid.core.CoreConstants;
 import org.teiid.core.TeiidComponentException;
 import org.teiid.core.TeiidProcessingException;
 import org.teiid.core.types.DataTypeManager;
 import org.teiid.core.util.StringUtil;
+import org.teiid.dqp.internal.process.CachedResults;
+import org.teiid.dqp.internal.process.SessionAwareCache;
+import org.teiid.dqp.internal.process.SessionAwareCache.CacheID;
 import org.teiid.language.SQLConstants.Reserved;
 import org.teiid.logging.LogConstants;
 import org.teiid.logging.LogManager;
@@ -52,6 +57,7 @@
 import org.teiid.query.metadata.QueryMetadataInterface;
 import org.teiid.query.metadata.TempMetadataID;
 import org.teiid.query.optimizer.relational.RelationalPlanner;
+import org.teiid.query.parser.ParseInfo;
 import org.teiid.query.processor.BatchCollector;
 import org.teiid.query.processor.CollectionTupleSource;
 import org.teiid.query.processor.ProcessorDataManager;
@@ -65,8 +71,10 @@
 import org.teiid.query.sql.lang.Delete;
 import org.teiid.query.sql.lang.Drop;
 import org.teiid.query.sql.lang.Insert;
+import org.teiid.query.sql.lang.Option;
 import org.teiid.query.sql.lang.ProcedureContainer;
 import org.teiid.query.sql.lang.Query;
+import org.teiid.query.sql.lang.SPParameter;
 import org.teiid.query.sql.lang.StoredProcedure;
 import org.teiid.query.sql.lang.Update;
 import org.teiid.query.sql.navigator.PostOrderNavigator;
@@ -93,7 +101,7 @@
 	
 	private ProcessorDataManager processorDataManager;
     private BufferManager bufferManager;
-    
+	private SessionAwareCache<CachedResults> cache;
     private Executor executor;
 
     public TempTableDataManager(ProcessorDataManager processorDataManager, BufferManager bufferManager) {
@@ -102,7 +110,7 @@
 			public void execute(Runnable command) {
 				command.run();
 			}
-	    });
+	    }, new SessionAwareCache<CachedResults>());
     }
 
     /**
@@ -110,11 +118,13 @@
      * and will pass most calls through to transparently.  Only when a request is registered for
      * a temp group will this proxy do it's thing.
      * @param processorDataManager the real ProcessorDataManager that this object is a proxy to
+     * @param cache 
      */    
-    public TempTableDataManager(ProcessorDataManager processorDataManager, BufferManager bufferManager, Executor executor){
+    public TempTableDataManager(ProcessorDataManager processorDataManager, BufferManager bufferManager, Executor executor, SessionAwareCache<CachedResults> cache){
         this.processorDataManager = processorDataManager;
         this.bufferManager = bufferManager;
         this.executor = executor;
+        this.cache = cache;
     }
 
 	public TupleSource registerRequest(
@@ -141,11 +151,49 @@
             return registerQuery(context, contextStore, query);
         }
         if (command instanceof ProcedureContainer) {
-        	
-        	if (command instanceof StoredProcedure && CoreConstants.SYSTEM_MODEL.equals(modelName)) {
-        		TupleSource result = handleSystemProcedures(context, command);
-        		if (result != null) {
-        			return result;
+        	if (command instanceof StoredProcedure) {
+        		StoredProcedure proc = (StoredProcedure)command;
+        		if (CoreConstants.SYSTEM_MODEL.equals(modelName)) {
+	        		TupleSource result = handleSystemProcedures(context, proc);
+	        		if (result != null) {
+	        			return result;
+	        		}
+        		} else if (proc.getGroup().isGlobalTable()) {
+        			String fullName = context.getMetadata().getFullName(proc.getProcedureID());
+        			LinkedList<Object> vals = new LinkedList<Object>();
+        			for (SPParameter param : proc.getInputParameters()) {
+        				vals.add(((Constant)param.getExpression()).getValue());
+					}
+        			//collapse the hash to single byte for the key to restrict the possible results to 256
+        			int hash = vals.hashCode();
+        			hash |= (hash >>> 16);
+        			hash |= (hash >>> 8);
+        			hash &= 0x000000ff;
+        			CacheID cid = new CacheID(new ParseInfo(), fullName + hash, context.getVdbName(), 
+        					context.getVdbVersion(), context.getConnectionID(), context.getUserName());
+        			cid.setParameters(vals);
+    		    	CachedResults results = cache.get(cid);
+    		    	if (results != null) {
+    		    		TupleBuffer buffer = results.getResults();
+    		    		return buffer.createIndexedTupleSource();
+    		    	}
+        			CacheHint hint = proc.getCacheHint();
+        			proc.setCacheHint(null);
+        			Option option = new Option();
+        			option.setNoCache(true);
+        			option.addNoCacheGroup(fullName);
+        			proc.setOption(option);
+        			int determinismLevel = context.resetDeterminismLevel();
+        			QueryProcessor qp = context.getQueryProcessorFactory().createQueryProcessor(proc.toString(), fullName.toUpperCase(), context);
+        			qp.setNonBlocking(true);
+        			BatchCollector bc = qp.createBatchCollector();
+        			TupleBuffer tb = bc.collectTuples();
+        			CachedResults cr = new CachedResults();
+        			cr.setResults(tb);
+        			cr.setHint(hint);
+        			cache.put(cid, context.getDeterminismLevel(), cr, hint != null?hint.getTtl():null);
+        			context.setDeterminismLevel(determinismLevel);
+        			return tb.createIndexedTupleSource();
         		}
         	}
         	
@@ -200,14 +248,13 @@
         return null;
     }
 
-	private TupleSource handleSystemProcedures(CommandContext context, Command command)
+	private TupleSource handleSystemProcedures(CommandContext context, StoredProcedure proc)
 			throws TeiidComponentException, QueryMetadataException,
 			QueryProcessingException, QueryResolverException,
 			QueryValidatorException, TeiidProcessingException,
 			ExpressionEvaluationException {
 		QueryMetadataInterface metadata = context.getMetadata();
 		TempTableStore globalStore = context.getGlobalTableStore();
-		StoredProcedure proc = (StoredProcedure)command;
 		if (StringUtil.endsWithIgnoreCase(proc.getProcedureCallableName(), REFRESHMATVIEW)) {
 			Object groupID = validateMatView(metadata, proc);
 			String matViewName = metadata.getFullName(groupID);
@@ -361,10 +408,11 @@
 		}
 		int rowCount = -1;
 		try {
+			String fullName = metadata.getFullName(group.getMetadataID());
 			//TODO: order by primary key nulls first - then have an insert ordered optimization
 			//TODO: use the getCommand logic in RelationalPlanner to reuse commands for this.
 			String transformation = metadata.getVirtualPlan(group.getMetadataID()).getQuery();
-			QueryProcessor qp = context.getQueryProcessorFactory().createQueryProcessor(transformation, group.getCanonicalName(), context);
+			QueryProcessor qp = context.getQueryProcessorFactory().createQueryProcessor(transformation, fullName, context);
 			qp.setNonBlocking(true);
 			TupleSource ts = new BatchCollector.BatchProducerTupleSource(qp);
 			//TODO: if this insert fails, it's unnecessary to do the undo processing

Modified: branches/7.1.x/engine/src/main/java/org/teiid/query/util/CommandContext.java
===================================================================
--- branches/7.1.x/engine/src/main/java/org/teiid/query/util/CommandContext.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/java/org/teiid/query/util/CommandContext.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -108,6 +108,9 @@
 	    private TempTableStore globalTables;
 	    
 	    private SessionAwareCache<PreparedPlan> planCache;
+	    
+	    private boolean resultSetCacheEnabled = true;
+	    
 	}
 	
 	private GlobalState globalState = new GlobalState();
@@ -499,5 +502,13 @@
     	CacheID id = new CacheID(new ParseInfo(), key, getVdbName(), getVdbVersion(), getConnectionID(), getUserName());
     	this.globalState.planCache.put(id, determinismLevel, plan, null);
     }
+    
+    public boolean isResultSetCacheEnabled() {
+		return globalState.resultSetCacheEnabled;
+	}
+    
+    public void setResultSetCacheEnabled(boolean resultSetCacheEnabled) {
+		this.globalState.resultSetCacheEnabled = resultSetCacheEnabled;
+	}
 	
 }

Modified: branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties
===================================================================
--- branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/main/resources/org/teiid/query/i18n.properties	2010-08-26 15:29:47 UTC (rev 2492)
@@ -864,6 +864,9 @@
 ResolveVariablesVisitor.reserved_word_for_temporary_used=Cursor names cannot begin with "#" as that indicates the name of a temporary table: {0}.
 SimpleQueryResolver.materialized_table_not_used=The query against {0} did not use materialization table {1} due to the use of OPTION NOCACHE.
 SimpleQueryResolver.cache_hint_used=Loading materialized view {1} for view {0} using cache hint {2}.
+SimpleQueryResolver.procedure_cache_used=Procedure caching will be used for {0}.
+SimpleQueryResolver.procedure_cache_not_usable=Procedure caching will not be used for {0} since the result set cache is disabled or the results/parameters cannot be cached.
+SimpleQueryResolver.procedure_cache_not_used=Procedure caching will not be used for {0} due to the use of OPTION NOCACHE.
 ValidationVisitor.input_variable_data_type_not_match=The expression "{0}" assigned to input variable "{1}" is of type "{2}" which cannot be implicitly converted to the expected type "{3}".
 ValidationVisitor.input_variable_can_not_in_function=Input variable "{0}" cannot be an argument of a function in the criteria.
 ValidationVisitor.groupby_subquery=Expressions used in a GROUP BY cannot be constant and must not contain subqueries: "{0}".

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestMaterialization.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -101,5 +101,18 @@
 		execute("SELECT * from vgroup4 where x is null", Arrays.asList((String)null));
 		assertEquals(2, hdm.getCommandHistory().size());
 	}
+	
+	@Test public void testProcedureCache() throws Exception {
+		execute("call sp1('one')", Arrays.asList("one"));
+		assertEquals(1, hdm.getCommandHistory().size());
+		execute("call sp1('one')", Arrays.asList("one"));
+		assertEquals(1, hdm.getCommandHistory().size());
+		execute("call sp1('one') option nocache sp.sp1", Arrays.asList("one"));
+		assertEquals(2, hdm.getCommandHistory().size());
+		execute("call sp1(null)");
+		assertEquals(3, hdm.getCommandHistory().size());
+		execute("call sp1(null)");
+		assertEquals(3, hdm.getCommandHistory().size());
+	}
     
 }

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/processor/TestProcessor.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -257,6 +257,7 @@
             for (int i = 0; i < 100; i++) {
             	try {
             		id = collector.collectTuples();
+            		break;
             	} catch (BlockedException e) {
             		
             	}

Modified: branches/7.1.x/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java
===================================================================
--- branches/7.1.x/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2010-08-25 17:56:09 UTC (rev 2491)
+++ branches/7.1.x/engine/src/test/java/org/teiid/query/unittest/RealMetadataFactory.java	2010-08-26 15:29:47 UTC (rev 2492)
@@ -358,6 +358,14 @@
         createElements(vGroup4,
                                       new String[] { "x" }, //$NON-NLS-1$
                                       new String[] { DataTypeManager.DefaultDataTypes.STRING});
+        
+        Schema sp = createVirtualModel("sp", metadataStore); //$NON-NLS-1$
+        ColumnSet<Procedure> rs = createResultSet("sp1.vsprs1", new String[] { "StringKey" }, new String[] { DataTypeManager.DefaultDataTypes.STRING }); //$NON-NLS-1$ //$NON-NLS-2$
+        ProcedureParameter param = createParameter("param1", ParameterInfo.IN, DataTypeManager.DefaultDataTypes.STRING); //$NON-NLS-1$
+        param.setNullType(NullType.Nullable);
+        QueryNode sp1qn = new QueryNode("sp1", "/*+ cache */ CREATE VIRTUAL PROCEDURE BEGIN SELECT x as StringKey from matsrc where x = param1; END"); //$NON-NLS-1$ //$NON-NLS-2$
+        Procedure vsp5 = createVirtualProcedure("sp1", sp, Arrays.asList(param), sp1qn); //$NON-NLS-1$
+        vsp5.setResultSet(rs);
 
         return createTransformationMetadata(metadataStore, "");
     }



More information about the teiid-commits mailing list