You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by bp...@apache.org on 2009/04/25 22:21:04 UTC

svn commit: r768597 [1/4] - in /db/derby/code/trunk/java: engine/org/apache/derby/ engine/org/apache/derby/catalog/ engine/org/apache/derby/iapi/sql/conn/ engine/org/apache/derby/iapi/sql/dictionary/ engine/org/apache/derby/iapi/sql/execute/ engine/org...

Author: bpendleton
Date: Sat Apr 25 20:21:03 2009
New Revision: 768597

URL: http://svn.apache.org/viewvc?rev=768597&view=rev
Log:
DERBY-2487: Enhance Derby with XPLAIN functionality.

This feature was contributed by Felix Beyer (beyer dot felix at gmx dot net).

This feature introduces an alternate handling of runtime statistics
information. Derby can now be configured so that it will capture the
statistics in a machine-readable form and will store them into a set of
simply-structured tables in a schema which is specified by the user. We
call this behavior "XPLAIN style", and we call the tables which are
used the "XPLAIN tables".

Having captured statistics about statement execution, you can then
analyze the statement behavior by querying these tables. For example, you
can determine how much time was taken, what resources were used, what
query plan was chosen, and so on.

This is the initial commit of this new functionality. Subsequent changes
will provide documentation, additional tests, fully-tested upgrade support.
As the community gains more experience with this feature, we will find more
enhancements to make, but the initial commit provides a working feature
with an initial set of basic regression tests.

Many thanks to the community for reviewing the changes through several
iterations of development.


Added:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINFactoryIF.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINVisitor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINable.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetTimingsDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINScanPropsDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINSortPropsDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementTimingsDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINTableDescriptor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/xplain/
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/xplain/XPLAINDefaultVisitor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/xplain/XPLAINFactory.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/xplain/XPLAINSystemTableVisitor.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/xplain/XPLAINUtil.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XplainStatisticsTest.java   (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/Changes10_6.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/SystemProcedures.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecutionFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RunTimeStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericExecutionFactory.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoRowsResultSetImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealAnyResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealBasicNoPutResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealCurrentOfStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealDeleteCascadeResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealDeleteResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealDeleteVTIResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealDistinctScalarAggregateStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealDistinctScanStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealGroupedAggregateStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealHashJoinStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealHashLeftOuterJoinStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealHashScanStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealHashTableStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealIndexRowToBaseRowStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealInsertResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealInsertVTIResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealJoinResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealLastIndexKeyScanStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealMaterializedResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealNestedLoopJoinStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealNestedLoopLeftOuterJoinStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealNoRowsResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealNormalizeResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealOnceResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealProjectRestrictStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealRowCountStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealRowResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealScalarAggregateStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealScrollInsensitiveResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealSetOpResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealSortStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealTableScanStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealUnionResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealUpdateResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealVTIStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RealWindowResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/ResultSetStatistics.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/rts/RunTimeStatisticsImpl.java
    db/derby/code/trunk/java/engine/org/apache/derby/modules.properties
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/upgradeTests/UpgradeRun.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/catalog/SystemProcedures.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/SystemProcedures.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/SystemProcedures.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/SystemProcedures.java Sat Apr 25 20:21:03 2009
@@ -26,6 +26,7 @@
 import java.security.Policy;
 import java.sql.Connection;
 import java.sql.DatabaseMetaData;
+import java.sql.Statement;
 import java.sql.PreparedStatement;
 import java.sql.ResultSet;
 import java.sql.SQLException;
@@ -50,10 +51,20 @@
 import org.apache.derby.impl.jdbc.Util;
 import org.apache.derby.impl.load.Export;
 import org.apache.derby.impl.load.Import;
+import org.apache.derby.impl.sql.catalog.XPLAINTableDescriptor;
+import org.apache.derby.impl.sql.catalog.XPLAINResultSetDescriptor;
+import org.apache.derby.impl.sql.catalog.XPLAINResultSetTimingsDescriptor;
+import org.apache.derby.impl.sql.catalog.XPLAINScanPropsDescriptor;
+import org.apache.derby.impl.sql.catalog.XPLAINSortPropsDescriptor;
+import org.apache.derby.impl.sql.catalog.XPLAINStatementDescriptor;
+import org.apache.derby.impl.sql.catalog.XPLAINStatementTimingsDescriptor;
 import org.apache.derby.impl.sql.execute.JarUtil;
 import org.apache.derby.jdbc.InternalDriver;
 import org.apache.derby.iapi.store.access.TransactionController;
+import org.apache.derby.iapi.sql.dictionary.CatalogRowFactory;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
 import org.apache.derby.iapi.sql.dictionary.DataDictionary;
+import org.apache.derby.iapi.sql.dictionary.DataDescriptorGenerator;
 import org.apache.derby.iapi.sql.dictionary.SchemaDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 
@@ -1889,4 +1900,141 @@
        if (statementCache != null)
            statementCache.ageOut();
     }
+  
+	 /**
+     * this procedure switches between the different xplain modes 
+     * @param mode either 0 for explain only, or 1 for explain & execute (default)
+     * @throws SQLException
+     */
+    public static void SYSCS_SET_XPLAIN_MODE(int mode)
+                throws SQLException, StandardException
+            {
+		ConnectionUtil.getCurrentLCC().setXplainOnlyMode(mode != 0 ? true : false);
+            }
+    /**
+     * This procedure returns the current status of the xplain mode.
+     *
+     * If the XPLAIN mode is non-zero, meaning that it is ON, then statements
+     * are being XPLAIN'd only, not executed.
+     *
+     * @return 0 if XPLAIN mode is off, non-zero if on.
+     * @throws SQLException
+     */
+    public static int SYSCS_GET_XPLAIN_MODE()
+                throws SQLException, StandardException
+           {
+                return ConnectionUtil.getCurrentLCC().getXplainOnlyMode()?1:0;
+           }
+    
+    /**
+     * This procedure sets the current xplain schema.
+     * If the schema is not set, runtime statistics are captured as a
+     * textual stream printout. If it is set, statisitcs information is
+     * stored in that schema in user tables.
+     * @param schemaName May be an empty string.
+     * @throws SQLException
+     */
+    public static void SYSCS_SET_XPLAIN_SCHEMA(String schemaName)
+                throws SQLException, StandardException
+    {
+        LanguageConnectionContext lcc       = ConnectionUtil.getCurrentLCC();
+        TransactionController     tc        = lcc.getTransactionExecute();
+
+        if (schemaName == null || schemaName.trim().length() == 0)
+        {
+            lcc.setXplainSchema(null);
+            return;
+        }
+
+        boolean statsSave = lcc.getRunTimeStatisticsMode();
+        lcc.setRunTimeStatisticsMode(false);
+        createXplainSchema(schemaName);
+        createXplainTable(lcc, schemaName,
+                new XPLAINStatementDescriptor());
+        createXplainTable(lcc, schemaName,
+                new XPLAINStatementTimingsDescriptor());
+        createXplainTable(lcc, schemaName,
+                new XPLAINResultSetDescriptor());
+        createXplainTable(lcc, schemaName,
+                new XPLAINResultSetTimingsDescriptor());
+        createXplainTable(lcc, schemaName,
+                new XPLAINScanPropsDescriptor());
+        createXplainTable(lcc, schemaName,
+                new XPLAINSortPropsDescriptor());
+        lcc.setRunTimeStatisticsMode(statsSave);
+        lcc.setXplainSchema(schemaName);
+    }
+    private static boolean hasSchema(Connection conn, String schemaName)
+        throws SQLException
+    {
+        ResultSet rs = conn.getMetaData().getSchemas();
+        boolean schemaFound = false;
+        while (rs.next() && !schemaFound)
+            schemaFound = schemaName.equals(rs.getString("TABLE_SCHEM"));
+        rs.close();
+        return schemaFound;
+    }
+    private static boolean hasTable(Connection conn, String schemaName,
+            String tableName)
+        throws SQLException
+    {
+        ResultSet rs = conn.getMetaData().getTables((String)null,
+                schemaName, tableName,  new String[] {"TABLE"});
+        boolean tableFound = rs.next();
+        rs.close();
+        return tableFound;
+    }
+    private static void createXplainSchema(String schemaName)
+        throws SQLException
+    {
+        String escapedSchema = IdUtil.normalToDelimited(schemaName);
+        Connection conn = getDefaultConn();
+        if (!hasSchema(conn, schemaName))
+        {
+            Statement s = conn.createStatement();
+            s.executeUpdate("CREATE SCHEMA " + escapedSchema);
+            s.close();
+        }
+        conn.close();
+    }
+    // Create the XPLAIN table if it doesn't already exist. Also, make a first
+    // order check that we'll be able to insert rows into the table, by
+    // preparing the INSERT statement for the table. The actual INSERT
+    // statment is saved, as simple string text, in the LCC, to be executed
+    // later when the runtime statistics are being collected.
+    //
+    private static void createXplainTable(
+            LanguageConnectionContext lcc,
+            String schemaName,
+            XPLAINTableDescriptor t)
+        throws SQLException
+    {
+        String []ddl = t.getTableDDL(schemaName);
+        Connection conn = getDefaultConn();
+        if (!hasTable(conn, schemaName, t.getCatalogName()))
+        {
+            Statement s = conn.createStatement();
+            for (int i = 0; i < ddl.length; i++)
+                s.executeUpdate(ddl[i]);
+            s.close();
+        }
+        String ins = t.getTableInsert();
+        conn.prepareStatement(ins).close();
+        conn.close();
+        lcc.setXplainStatement(t.getCatalogName(), ins);
+    }
+    /**
+     * This procedure returns the current set XPLAIN_SCHEMA
+     * @return schema name, may be blank if no schema currently set.
+     * @throws SQLException
+     */
+    public static String SYSCS_GET_XPLAIN_SCHEMA()
+                throws SQLException, StandardException
+    {
+        String sd = ConnectionUtil.getCurrentLCC().getXplainSchema();
+        if (sd == null)
+            return "";
+        return sd;
+    }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/conn/LanguageConnectionContext.java Sat Apr 25 20:21:03 2009
@@ -1200,4 +1200,37 @@
 	 */
     public  Object    getLastQueryTree();
 
+	
+    /**
+     * sets the XplainOnlyMode.
+     *
+     * If a connection is in XplainOnlyMode, then the statements are not
+     * actually being executed, but are just being compiled and the
+     * runtime statistics collected into the XPLAIN tables. This can be
+     * set on and off by calling SYSCS_SET_XPLAIN_MODE.
+     *
+     * @param onOrOff true if statements are to be XPLAINed only.
+     */
+    public void setXplainOnlyMode(boolean onOrOff);
+
+    /**
+     * gets the current set XplainOnlyMode
+     */
+    public boolean getXplainOnlyMode();
+
+    /**
+     * sets the XplainSchema
+     * @param schema the schema to use for storing XPLAIN'd statements
+     * null means don't store the xplain information
+     * non-null means persistent style, use the indicated schema
+     */
+    public void setXplainSchema(String schema);
+
+    /**
+     * gets the current set XplainSchema
+     * @return the Schema of Xplain, may be null.
+     */
+    public String getXplainSchema();
+    public void setXplainStatement(Object key, Object stmt);
+    public Object getXplainStatement(Object key);
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/dictionary/DataDictionary.java Sat Apr 25 20:21:03 2009
@@ -116,6 +116,9 @@
 	/** Derby 10.5 System Catalog version */
 	public static final int DD_VERSION_DERBY_10_5		= 170;
 
+	/** Derby 10.6 System Catalog version */
+	public static final int DD_VERSION_DERBY_10_6		= 180;
+
 	// general info
 	public	static	final	String	DATABASE_ID = "derby.databaseID";
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecutionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecutionFactory.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecutionFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/ExecutionFactory.java Sat Apr 25 20:21:03 2009
@@ -32,6 +32,7 @@
 import org.apache.derby.iapi.store.access.DynamicCompiledOpenConglomInfo;
 import org.apache.derby.iapi.store.access.Qualifier;
 import org.apache.derby.iapi.sql.dictionary.IndexRowGenerator;
+import org.apache.derby.iapi.sql.execute.xplain.XPLAINFactoryIF;
 import org.apache.derby.iapi.store.access.StaticCompiledOpenConglomInfo;
 import org.apache.derby.iapi.store.access.TransactionController;
 import java.util.Properties;
@@ -90,6 +91,20 @@
         throws StandardException;
 
 	/**
+	 * Get the XPLAINFactory from this ExecutionFactory.
+	 *
+	 * @return  The xplain factory associated with this
+	 *      ExecutionContext
+	 *
+	 * @exception StandardException     Thrown on error
+	 */
+	XPLAINFactoryIF getXPLAINFactory()
+                                throws StandardException;
+	
+	
+  	/**
+  	 * Get the ExecutionFactory from this ExecutionContext.
+  	 *
 		We want an execution context so that we can push it onto
 		the stack.  We could instead require the implementation
 		push it onto the stack for us, but this way we know

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RunTimeStatistics.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RunTimeStatistics.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RunTimeStatistics.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/RunTimeStatistics.java Sat Apr 25 20:21:03 2009
@@ -26,6 +26,8 @@
 import java.sql.Time;
 import java.sql.Timestamp;
 
+import org.apache.derby.iapi.sql.execute.xplain.XPLAINVisitor;
+
 /**
 	
   * A RunTimeStatistics object is a representation of the query execution plan and run
@@ -203,4 +205,11 @@
 	 * query or statement.
 	 */
 	public double getEstimatedRowCount();
+	
+	/**
+	 * Initiate a visit of the ResultSetStatistics tree from the top.
+	 * @param v the visitor that wishes to visit the tree.
+	 */
+	public void acceptFromTopResultSet(XPLAINVisitor v);
+
 }

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINFactoryIF.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINFactoryIF.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINFactoryIF.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINFactoryIF.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,36 @@
+package org.apache.derby.iapi.sql.execute.xplain;
+import org.apache.derby.iapi.error.StandardException;
+/**
+ * This is the factory interface of the XPLAINFactory facility. It extends the 
+ * possibilities and provides a convenient protocol to explain queries 
+ * on basis of the query execution plan. This plan manfifests in Derby in the 
+ * different ResultSets and their associated statistics. The introduction of 
+ * this factory interface makes it possible to switch to another implementation 
+ * or to easily extend the API.
+ *  
+ */
+public interface XPLAINFactoryIF {
+
+    /**
+    Module name for the monitor's module locating system.
+    */
+    String MODULE = "org.apache.derby.iapi.sql.execute.xplain.XPLAINFactoryIF";
+    
+    /**
+     * This method returns an appropriate visitor to traverse the 
+     * ResultSetStatistics. Depending on the current configuration, 
+     * the perfect visitor will be chosen, created and cached by this factory
+     * method. 
+     * @return a XPLAINVisitor to traverse the ResultSetStatistics
+     * @see XPLAINVisitor
+     */
+    public XPLAINVisitor getXPLAINVisitor() throws StandardException;
+    
+    /**
+     * This method gets called when the user switches off the explain facility.
+     * The factory destroys for example the cached visitor implementation(s) or 
+     * releases resources to save memory.
+     */
+    public void freeResources();
+    
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINFactoryIF.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINVisitor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINVisitor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINVisitor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINVisitor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,57 @@
+package org.apache.derby.iapi.sql.execute.xplain;
+
+import java.sql.SQLException;
+import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.sql.Activation;
+import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
+import org.apache.derby.impl.sql.execute.rts.ResultSetStatistics;
+/**
+ * Classes, which implement this interface have the ability to explain the
+ * gathered ResultSetStatistics. A Visitor pattern is used to traverse the 
+ * ResultSetStatistics tree and to extract the required information. Classes 
+ * implementing this interface are responsible about what they extract 
+ * and what will be done with the extracted information.
+ * This approach allows easy representaion extensions of the statistics, 
+ * e.g. an XML representation. 
+ *
+ */
+public interface XPLAINVisitor {
+
+    /**
+     * Call this method to reset the visitor for a new run over the 
+     * statistics. A default implementation should call this method
+     * automatically at first of a call of doXPLAIN(). 
+     */
+    public void reset();
+    
+    /**
+     * This method is the hook method which is called from the TopResultSet.
+     * It starts the explanation of the current ResultSetStatistics tree 
+     * and keeps the information during one explain run.
+     */
+    public void doXPLAIN(RunTimeStatistics rss, Activation activation)
+        throws StandardException;
+
+    /**
+     * This is the Visitor hook method, which gets called from each 
+     * ResultSetStatistics. It depends on the sub-class implementation of this
+     * interface, to describe the behaviour of the explanation facility. <br/>
+     * To be easily extendable with new explain representation methods, 
+     * just implement this interface and provide the new behaviour. 
+     * @param statistics the statistics, which want to get explained.
+     */
+    public void visit(ResultSetStatistics statistics);
+    
+    /**
+     * This method informs the visitor about the number of children. It has to 
+     * be called first! by the different explainable nodes before the visit 
+     * method of the visitor gets called. Each node knows how many children he has. 
+     * The visitor can use this information to resolve the relationship of the 
+     * current explained node to above nodes. Due to the top-down, pre-order, 
+     * depth-first traversal of the tree, this information can directly 
+     * be exploited.  
+     * @param noChildren the number of children of the current explained node.
+     */
+    public void setNumberOfChildren(int noChildren);
+    
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINVisitor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINable.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINable.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINable.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINable.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,31 @@
+package org.apache.derby.iapi.sql.execute.xplain;
+/**
+ * This interface has to be implemented by object structures, which want to
+ * get explained. The current implementation let the ResultSetStatistics 
+ * extend this Interface to be explainable.
+ *
+ */
+public interface XPLAINable
+{
+
+    /**
+     * This method gets called to let a visitor visit this XPLAINable object.
+     * The general contract is to implement pre-order, depth-first traversal 
+     * to produce a predictable traversal behaviour.  
+     */
+    public void accept(XPLAINVisitor visitor);
+
+    // The methods below return descriptive information about the particular
+    // result set. There are a few common implementations, and the various
+    // ResultSetStatistics sub-classes override these methods when they
+    // have more detailed information to provide. The visitor calls these
+    // methods during xplain tree visiting.
+
+    public String getRSXplainType();
+    public String getRSXplainDetails();
+    public Object getResultSetDescriptor(Object rsID, Object parentID,
+            Object scanID, Object sortID, Object stmtID, Object timingID);
+    public Object getResultSetTimingsDescriptor(Object rstID);
+    public Object getSortPropsDescriptor(Object spID);
+    public Object getScanPropsDescriptor(Object spID);
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/execute/xplain/XPLAINable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DD_Version.java Sat Apr 25 20:21:03 2009
@@ -154,6 +154,8 @@
 			return "10.4";
 		case DataDictionary.DD_VERSION_DERBY_10_5:
 			return "10.5";
+		case DataDictionary.DD_VERSION_DERBY_10_6:
+			return "10.6";
 		default:
 			return null;
 		}
@@ -399,6 +401,14 @@
                 bootingDictionary.getSystemUtilSchemaDescriptor().getUUID());
         }
 
+        if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_5)
+        {
+            // On ugrade from versions before 10.6, create system procedures
+            // added in 10.6.
+            bootingDictionary.create_10_6_system_procedures(tc,
+                    newlyCreatedRoutines);
+        }
+
         if (fromMajorVersionNumber <= DataDictionary.DD_VERSION_DERBY_10_1)
         {
             // On ugrade from versions before 10.2, create system procedures

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/DataDictionaryImpl.java Sat Apr 25 20:21:03 2009
@@ -10190,6 +10190,8 @@
         create_10_3_system_procedures(tc, newlyCreatedRoutines );
         // add 10.5 specific system procedures
         create_10_5_system_procedures(tc, newlyCreatedRoutines );
+        // add 10.6 specific system procedures
+        create_10_6_system_procedures(tc, newlyCreatedRoutines );
     }
 
     /**
@@ -11446,6 +11448,101 @@
     }
 
     /**
+     * Create the System procedures that are added to 10.6.
+     * 
+     * @param tc an instance of the TransactionController.
+     * @throws StandardException Standard exception policy.
+     */
+    void create_10_6_system_procedures(TransactionController tc,
+            HashSet newlyCreatedRoutines)
+    throws StandardException
+    {
+        // Create the procedures in the SYSCS_UTIL schema.
+        UUID  sysUtilUUID = getSystemUtilSchemaDescriptor().getUUID();
+        // void SYSCS_UTIL.SYSCS_SET_XPLAIN_MODE(smallint mode)
+        {
+            // procedure argument names
+            String[] arg_names = {"ENABLE"};
+
+            // procedure argument types
+            TypeDescriptor[] arg_types = {
+                TypeDescriptor.INTEGER,
+            };
+
+            createSystemProcedureOrFunction(
+                "SYSCS_SET_XPLAIN_MODE",
+                sysUtilUUID,
+                arg_names,
+                arg_types,
+                0,
+                0,
+                RoutineAliasInfo.CONTAINS_SQL,
+                false,
+                (TypeDescriptor) null,
+                newlyCreatedRoutines,
+                tc);
+        }
+        
+        // SMALLINT SYSCS_UTIL.SYSCS_GET_XPLAIN_MODE()
+        {
+
+            createSystemProcedureOrFunction(
+                "SYSCS_GET_XPLAIN_MODE",
+                sysUtilUUID,
+                null,
+                null,
+                0,
+                0,
+                RoutineAliasInfo.READS_SQL_DATA,
+                false,
+                TypeDescriptor.INTEGER,
+                newlyCreatedRoutines,
+                tc);
+        }
+        
+        
+        // void SYSCS_UTIL.SYSCS_SET_XPLAIN_SCHEMA(String schemaName)
+        {
+            // procedure argument names
+            String[] arg_names = {"SCHEMANAME"};
+
+            // procedure argument types
+            TypeDescriptor[] arg_types = {
+                CATALOG_TYPE_SYSTEM_IDENTIFIER,
+            };
+
+            createSystemProcedureOrFunction(
+                "SYSCS_SET_XPLAIN_SCHEMA",
+                sysUtilUUID,
+                arg_names,
+                arg_types,
+                0,
+                0,
+                RoutineAliasInfo.MODIFIES_SQL_DATA,
+                false,
+                (TypeDescriptor) null,
+                newlyCreatedRoutines,
+                tc);
+        }
+
+        // STRING SYSCS_UTIL.SYSCS_GET_XPLAIN_SCHEMA()
+        {
+            createSystemProcedureOrFunction(
+                "SYSCS_GET_XPLAIN_SCHEMA",
+                sysUtilUUID,
+                null,
+                null,
+                0,
+                0,
+                RoutineAliasInfo.READS_SQL_DATA,
+                false,
+                CATALOG_TYPE_SYSTEM_IDENTIFIER,
+                newlyCreatedRoutines,
+                tc);
+        }
+    }
+
+    /**
      * Create the System procedures that are added in 10.3.
      *
      * @param tc an instance of the TransactionController.

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,195 @@
+package org.apache.derby.impl.sql.catalog;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+import org.apache.derby.impl.sql.catalog.SystemColumnImpl;
+import java.sql.Types;
+
+public class XPLAINResultSetDescriptor extends XPLAINTableDescriptor 
+{
+
+    private UUID rs_id           ; // the result set UUID identifier
+    private String op_identifier ; // the operator code identifier
+    private String op_details     ;     // the operator details, operator-specific information
+    private Integer no_opens      ; // the number of open calls of this resultset 
+    private Integer no_index_updates; // the number of index updates, executed by this dml write operation
+    private String lock_granularity; // the lock granularity, either (T)able or (R)ow locking
+    private String lock_mode;  // the lock mode, either instant share, share or instant exclusive, exclusive 
+    private UUID parent_rs_id; // the parent UUID of this resultset, null if root (top) resultset
+    private Double est_row_count; // the estimated row count, forwarded by the optimizer
+    private Double est_cost; // the estimated costs, forwarded by the optimizer
+    private Integer affected_rows; // the affected rows, specific for insert/update/delete stmts
+    private String  deferred_rows; // the deferred rows, specific for insert/update/delete stmts
+    private Integer input_rows; // the number of input rows
+    private Integer seen_rows; // the seen rows from this operator 
+    private Integer seen_rows_right; // the seen right rows from this operator, only filled by a join operator, seen_rows has then the rows from the outer(left) partner of the join 
+    private Integer filtered_rows; // the filtered rows
+    private Integer returned_rows; // the returned rows
+    private Integer empty_right_rows; // the number of empty right rows 
+    private String index_key_optimization; // does this node use index key optimization
+    private UUID scan_rs_id; // the UUID of the scan info properties of this node, if this node is a scan node, otherwise null
+    private UUID sort_rs_id; // the UUID of the sort info properties of this node. if this node is a groupby or sort node, otherwise null
+    private UUID stmt_id; // the UUID of the statement, which this resultset belongs to
+    private UUID timing_id; // the UUID of the resultset timing information, if statistics timing was on, otherwise null
+    
+    public XPLAINResultSetDescriptor() {}
+    public XPLAINResultSetDescriptor
+    (
+             UUID rs_id,
+             String op_identifier,
+             String op_details,
+             Integer no_opens,
+             Integer no_index_updates,
+             String lock_mode,
+             String lock_granularity,
+             UUID parent_rs_id,
+             Double est_row_count,
+             Double est_cost,
+             Integer affected_rows,
+             String deferred_rows,
+             Integer input_rows,
+             Integer seen_rows,
+             Integer seen_rows_right,
+             Integer filtered_rows,
+             Integer returned_rows,
+             Integer empty_right_rows,
+             String index_key_optimization,
+             UUID scan_rs_id,
+             UUID sort_rs_id,
+             UUID stmt_id,
+             UUID timing_id
+    )
+    {
+
+        this.rs_id=  rs_id;
+        this.op_identifier = op_identifier;
+        this.op_details = op_details;
+        this.no_opens = no_opens;
+        this.no_index_updates = no_index_updates;
+        this.lock_granularity = lock_granularity;
+        this.lock_mode = lock_mode;
+        this.parent_rs_id = parent_rs_id;
+        this.est_row_count = est_row_count;
+        this.est_cost = est_cost;
+        this.affected_rows = affected_rows;
+        this.deferred_rows = deferred_rows;
+        this.input_rows = input_rows;
+        this.seen_rows = seen_rows;
+        this.seen_rows_right = seen_rows_right;
+        this.filtered_rows = filtered_rows;
+        this.returned_rows = returned_rows;
+        this.empty_right_rows = empty_right_rows;
+        this.index_key_optimization = index_key_optimization;
+        this.scan_rs_id = scan_rs_id;
+        this.sort_rs_id = sort_rs_id;
+        this.stmt_id = stmt_id;
+        this.timing_id = timing_id;
+        
+    }
+    public void setStatementParameters(PreparedStatement ps)
+        throws SQLException
+    {
+        ps.setString(1, rs_id.toString());
+        ps.setString(2, op_identifier);
+        ps.setString(3, op_details);
+        if (no_opens != null)
+            ps.setInt(4, no_opens.intValue());
+        else
+            ps.setNull(4, Types.INTEGER);
+        if (no_index_updates != null)
+            ps.setInt(5, no_index_updates.intValue());
+        else
+            ps.setNull(5, Types.INTEGER);
+        ps.setString(6, lock_mode);
+        ps.setString(7, lock_granularity);
+        ps.setString(8, (parent_rs_id != null ? parent_rs_id.toString():null));
+        if (est_row_count != null)
+            ps.setDouble(9, est_row_count.doubleValue());
+        else
+            ps.setNull(9, Types.DOUBLE);
+        if (est_cost != null)
+            ps.setDouble(10, est_cost.doubleValue());
+        else
+            ps.setNull(10, Types.DOUBLE);
+        if (affected_rows != null)
+            ps.setInt(11, affected_rows.intValue());
+        else
+            ps.setNull(11, Types.INTEGER);
+        ps.setString(12, deferred_rows);
+        if (input_rows != null)
+            ps.setInt(13, input_rows.intValue());
+        else
+            ps.setNull(13, Types.INTEGER);
+        if (seen_rows != null)
+            ps.setInt(14, seen_rows.intValue());
+        else
+            ps.setNull(14, Types.INTEGER);
+        if (seen_rows_right != null)
+            ps.setInt(15, seen_rows_right.intValue());
+        else
+            ps.setNull(15, Types.INTEGER);
+        if (filtered_rows != null)
+            ps.setInt(16, filtered_rows.intValue());
+        else
+            ps.setNull(16, Types.INTEGER);
+        if (returned_rows != null)
+            ps.setInt(17, returned_rows.intValue());
+        else
+            ps.setNull(17, Types.INTEGER);
+        if (empty_right_rows != null)
+            ps.setInt(18, empty_right_rows.intValue());
+        else
+            ps.setNull(18, Types.INTEGER);
+        ps.setString(19, index_key_optimization);
+        ps.setString(20, (scan_rs_id != null ? scan_rs_id.toString():null));
+        ps.setString(21, (sort_rs_id != null ? sort_rs_id.toString():null));
+        ps.setString(22, (stmt_id != null ? stmt_id.toString():null));
+        ps.setString(23, (timing_id != null ? timing_id.toString():null));
+    }
+    
+    public String getCatalogName() { return TABLENAME_STRING; }
+    static final String             TABLENAME_STRING = "SYSXPLAIN_RESULTSETS";
+
+    private static final String[][] indexColumnNames =
+    {
+        {"RS_ID"}
+    };
+
+    /**
+     * Builds a list of columns suitable for creating this Catalog.
+     *
+     * @return array of SystemColumn suitable for making this catalog.
+     */
+    public SystemColumn[] buildColumnList() {
+        
+        return new SystemColumn[] {
+            SystemColumnImpl.getUUIDColumn("RS_ID", false),
+            SystemColumnImpl.getColumn("OP_IDENTIFIER",Types.VARCHAR,false,30),
+            SystemColumnImpl.getColumn("OP_DETAILS", Types.VARCHAR, true, 256),
+            SystemColumnImpl.getColumn("NO_OPENS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_INDEX_UPDATES", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("LOCK_MODE", Types.CHAR, true, 2),
+            SystemColumnImpl.getColumn("LOCK_GRANULARITY", Types.CHAR, true, 1),
+            SystemColumnImpl.getUUIDColumn("PARENT_RS_ID", true),
+            SystemColumnImpl.getColumn("EST_ROW_COUNT", Types.DOUBLE, true),
+            SystemColumnImpl.getColumn("EST_COST", Types.DOUBLE, true),
+            SystemColumnImpl.getColumn("AFFECTED_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("DEFERRED_ROWS", Types.CHAR, true, 1),
+            SystemColumnImpl.getColumn("INPUT_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("SEEN_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("SEEN_ROWS_RIGHT", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("FILTERED_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("RETURNED_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("EMPTY_RIGHT_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("INDEX_KEY_OPT", Types.CHAR, true, 1),
+            SystemColumnImpl.getUUIDColumn("SCAN_RS_ID", true),
+            SystemColumnImpl.getUUIDColumn("SORT_RS_ID", true),
+            SystemColumnImpl.getUUIDColumn("STMT_ID", false),
+            SystemColumnImpl.getUUIDColumn("TIMING_ID", true),
+        };
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetTimingsDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetTimingsDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetTimingsDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetTimingsDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,133 @@
+package org.apache.derby.impl.sql.catalog;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+import org.apache.derby.impl.sql.catalog.SystemColumnImpl;
+import java.sql.Types;
+
+public class XPLAINResultSetTimingsDescriptor extends XPLAINTableDescriptor 
+{
+
+    private UUID timing_id; // the timuing UUID for the result set timing information
+    private Long constructor_time; // the time needed to create an object, through a call of the constructor
+    private Long open_time; // the time needed to process all open calls
+    private Long next_time; // the time needed to process all next calls
+    private Long close_time; // the time needed to close the resultset
+    private Long execute_time; // the time needed for overall execution
+    private Long avg_next_time_per_row; // the avarage time needed for a next call per row
+    private Long projection_time; // the time needed by a ProjectRestrictResultSet to do the projection
+    private Long restriction_time; // the time needed by a ProjectRestrictResultSet to do the restriction
+    private Long temp_cong_create_time; //  the timestamp of th creation of a temporary conglomerate
+    private Long temp_cong_fetch_time; // the time needed to do a fetch from this temporary conglomerate
+    
+
+    public XPLAINResultSetTimingsDescriptor() {}
+    public XPLAINResultSetTimingsDescriptor
+    (
+            UUID timing_id,
+            Long constructor_time,
+            Long open_time,
+            Long next_time,
+            Long close_time,
+            Long execute_time,
+            Long avg_next_time_per_row,
+            Long projection_time,
+            Long restriction_time,
+            Long temp_cong_create_time,
+            Long temp_cong_fetch_time
+    )
+    {
+        
+        this.timing_id = timing_id;
+        this.constructor_time = constructor_time;
+        this.open_time = open_time;
+        this.next_time = next_time;
+        this.close_time = close_time;
+        this.execute_time = execute_time;
+        this.avg_next_time_per_row = avg_next_time_per_row;
+        this.projection_time = projection_time;
+        this.restriction_time = restriction_time;
+        this.temp_cong_create_time = temp_cong_create_time;
+        this.temp_cong_fetch_time = temp_cong_fetch_time;
+    }
+
+    public void setStatementParameters(PreparedStatement ps)
+        throws SQLException
+    {
+        ps.setString(1, timing_id.toString());
+        if (constructor_time != null)
+            ps.setLong(2, constructor_time.longValue());
+        else
+            ps.setNull(2, Types.BIGINT);
+        if (open_time != null)
+            ps.setLong(3, open_time.longValue());
+        else
+            ps.setNull(3, Types.BIGINT);
+        if (next_time != null)
+            ps.setLong(4, next_time.longValue());
+        else
+            ps.setNull(4, Types.BIGINT);
+        if (close_time != null)
+            ps.setLong(5, close_time.longValue());
+        else
+            ps.setNull(5, Types.BIGINT);
+        if (execute_time != null)
+            ps.setLong(6, execute_time.longValue());
+        else
+            ps.setNull(6, Types.BIGINT);
+        if (avg_next_time_per_row != null)
+            ps.setLong(7, avg_next_time_per_row.longValue());
+        else
+            ps.setNull(7, Types.BIGINT);
+        if (projection_time != null)
+            ps.setLong(8, projection_time.longValue());
+        else
+            ps.setNull(8, Types.BIGINT);
+        if (restriction_time != null)
+            ps.setLong(9, restriction_time.longValue());
+        else
+            ps.setNull(9, Types.BIGINT);
+        if (temp_cong_create_time != null)
+            ps.setLong(10, temp_cong_create_time.longValue());
+        else
+            ps.setNull(10, Types.BIGINT);
+        if (temp_cong_fetch_time != null)
+            ps.setLong(11, temp_cong_fetch_time.longValue());
+        else
+            ps.setNull(11, Types.BIGINT);
+    }
+
+    public String getCatalogName() { return TABLENAME_STRING; }
+    static final String             TABLENAME_STRING = "SYSXPLAIN_RESULTSET_TIMINGS";
+
+    private static final String[][] indexColumnNames =
+    {
+        {"TIMING_ID"}
+    };
+
+    /**
+     * Builds a list of columns suitable for creating this Catalog.
+     *
+     * @return array of SystemColumn suitable for making this catalog.
+     */
+    public SystemColumn[] buildColumnList() {
+        
+        return new SystemColumn[] {
+            SystemColumnImpl.getUUIDColumn("TIMING_ID", false),
+            SystemColumnImpl.getColumn("CONSTRUCTOR_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("OPEN_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("NEXT_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("CLOSE_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("EXECUTE_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("AVG_NEXT_TIME_PER_ROW", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("PROJECTION_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("RESTRICTION_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("TEMP_CONG_CREATE_TIME", Types.BIGINT, true),
+            SystemColumnImpl.getColumn("TEMP_CONG_FETCH_TIME", Types.BIGINT, true),
+        };
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINResultSetTimingsDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINScanPropsDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINScanPropsDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINScanPropsDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINScanPropsDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,199 @@
+package org.apache.derby.impl.sql.catalog;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+import org.apache.derby.impl.sql.catalog.SystemColumnImpl;
+import java.sql.Types;
+
+public class XPLAINScanPropsDescriptor extends XPLAINTableDescriptor 
+{
+
+    private UUID scan_rs_id; // the UUID of this scan info tuple
+    private String scan_object_name; // the name of the scanned object
+    private String scan_object_type; // the object type, either index, constraint or table
+    private String scan_type; // the type of the scan: heap, btree or sort
+    private String isolation_level; // the isolation level
+    private Integer no_visited_pages; // the number of visited pages during this scan
+    private Integer no_visited_rows; // the number of visited rows during this scan
+    private Integer no_qualified_rows; // the number of qualified rows, during the scan
+    private Integer no_visited_deleted_rows; // the number of visited rows, marked for delete
+    private Integer no_fetched_columns; // the number of fetched columns of this scan from the object
+    private String bitset_of_fetched_columns; // the bitset of the fetched columns
+    private Integer btree_height; // the btree height, if this is a btree scan
+    private Integer fetch_size; // the fetch size, for bulk scans
+    private String start_position; // the start positioner info, internal encoding
+    private String stop_position; // the stop positioner info, internal encoding
+    private String scan_qualifiers; // the scan qualifiers, in internal encoding (conjunctive normal form)
+    private String next_qualifiers; // the next qualifiers, in internal encoding
+    private String hash_key_column_numbers; // the hash key column numbers
+    private Integer hash_table_size; // the hash table size of the constructed hash table during the scan
+    
+    public XPLAINScanPropsDescriptor() {}
+    public XPLAINScanPropsDescriptor 
+    (
+             UUID scan_rs_id,
+             String scan_object_name,
+             String scan_object_type,
+             String scan_type,
+             String isolation_level,
+             Integer no_visited_pages,
+             Integer no_visited_rows,
+             Integer no_qualified_rows,
+             Integer no_visited_deleted_rows,
+             Integer no_fetched_columns,
+             String bitset_of_fetched_columns,
+             Integer btree_height,
+             Integer fetch_size,
+             String start_position,
+             String stop_position,
+             String scan_qualifiers,
+             String next_qualifiers,
+             String hash_key_column_numbers,
+             Integer hash_table_size
+    )
+    {
+        
+        this.scan_rs_id = scan_rs_id;
+        this.scan_object_name = scan_object_name;
+        this.scan_object_type = scan_object_type;
+        this.scan_type = scan_type;
+        this.isolation_level = isolation_level;
+        this.no_visited_pages = no_visited_pages;
+        this.no_visited_rows  = no_visited_rows;
+        this.no_qualified_rows = no_qualified_rows;
+        this.no_visited_deleted_rows = no_visited_deleted_rows;
+        this.no_fetched_columns = no_fetched_columns;
+        this.bitset_of_fetched_columns = bitset_of_fetched_columns;
+        this.btree_height = btree_height;
+        this.fetch_size = fetch_size;
+        this.start_position = start_position;
+        this.stop_position = stop_position;
+        this.scan_qualifiers = scan_qualifiers;
+        this.next_qualifiers = next_qualifiers;
+        this.hash_key_column_numbers = hash_key_column_numbers;
+        this.hash_table_size = hash_table_size;
+    }
+    public void setStatementParameters(PreparedStatement ps)
+        throws SQLException
+    {
+        ps.setString(1, scan_rs_id.toString());
+        ps.setString(2, scan_object_name);
+        ps.setString(3, scan_object_type);
+        ps.setString(4, scan_type);
+        ps.setString(5, isolation_level);
+        if (no_visited_pages != null)
+            ps.setInt(6, no_visited_pages.intValue());
+        else
+            ps.setNull(6, Types.INTEGER);
+        if (no_visited_rows != null)
+            ps.setInt(7, no_visited_rows.intValue());
+        else
+            ps.setNull(7, Types.INTEGER);
+        if (no_qualified_rows != null)
+            ps.setInt(8, no_qualified_rows.intValue());
+        else
+            ps.setNull(8, Types.INTEGER);
+        if (no_visited_deleted_rows != null)
+            ps.setInt(9, no_visited_deleted_rows.intValue());
+        else
+            ps.setNull(9, Types.INTEGER);
+        if (no_fetched_columns != null)
+            ps.setInt(10, no_fetched_columns.intValue());
+        else
+            ps.setNull(10, Types.INTEGER);
+        ps.setString(11, bitset_of_fetched_columns);
+        if (btree_height != null)
+            ps.setInt(12, btree_height.intValue());
+        else
+            ps.setNull(12, Types.INTEGER);
+        if (fetch_size != null)
+            ps.setInt(13, fetch_size.intValue());
+        else
+            ps.setNull(13, Types.INTEGER);
+        ps.setString(14, start_position);
+        ps.setString(15, stop_position);
+        ps.setString(16, scan_qualifiers);
+        ps.setString(17, next_qualifiers);
+        ps.setString(18, hash_key_column_numbers);
+        if (hash_table_size != null)
+            ps.setInt(19, hash_table_size.intValue());
+        else
+            ps.setNull(19, Types.INTEGER);
+    }
+
+    public void setScan_type(String scan_type) {
+        this.scan_type = scan_type;
+    }
+
+    public void setNo_visited_pages(Integer no_visited_pages) {
+        this.no_visited_pages = no_visited_pages;
+    }
+
+    public void setNo_visited_rows(Integer no_visited_rows) {
+        this.no_visited_rows = no_visited_rows;
+    }
+
+    public void setNo_qualified_rows(Integer no_qualified_rows) {
+        this.no_qualified_rows = no_qualified_rows;
+    }
+
+    public void setNo_fetched_columns(Integer no_fetched_columns) {
+        this.no_fetched_columns = no_fetched_columns;
+    }
+
+    public void setNo_visited_deleted_rows(Integer no_visited_deleted_rows) {
+        this.no_visited_deleted_rows = no_visited_deleted_rows;
+    }
+
+    public void setBtree_height(Integer btree_height) {
+        this.btree_height = btree_height;
+    }
+
+    public void setBitset_of_fetched_columns(String bitset_of_fetched_columns) {
+        this.bitset_of_fetched_columns = bitset_of_fetched_columns;
+    }
+
+
+    public String getCatalogName() { return TABLENAME_STRING; }
+    static final   String  TABLENAME_STRING = "SYSXPLAIN_SCAN_PROPS";
+    
+    private static final String[][] indexColumnNames =
+    {
+        {"SCAN_RS_ID"}
+    };
+
+
+    /**
+     * Builds a list of columns suitable for creating this Catalog.
+     *
+     * @return array of SystemColumn suitable for making this catalog.
+     */
+    public SystemColumn[] buildColumnList() {
+        
+        return new SystemColumn[] {
+            SystemColumnImpl.getUUIDColumn("SCAN_RS_ID", false),
+            SystemColumnImpl.getIdentifierColumn("SCAN_OBJECT_NAME", false),
+            SystemColumnImpl.getIndicatorColumn("SCAN_OBJECT_TYPE"),
+            SystemColumnImpl.getColumn("SCAN_TYPE", Types.CHAR, false, 8),
+            SystemColumnImpl.getColumn("ISOLATION_LEVEL", Types.CHAR, true, 3),
+            SystemColumnImpl.getColumn("NO_VISITED_PAGES", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_VISITED_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_QUALIFIED_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_VISITED_DELETED_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_FETCHED_COLUMNS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("BITSET_OF_FETCHED_COLUMNS", Types.VARCHAR, true, 256),
+            SystemColumnImpl.getColumn("BTREE_HEIGHT", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("FETCH_SIZE", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("START_POSITION", Types.VARCHAR, true, 512),
+            SystemColumnImpl.getColumn("STOP_POSITION", Types.VARCHAR, true, 512),
+            SystemColumnImpl.getColumn("SCAN_QUALIFIERS", Types.VARCHAR, true, 512),
+            SystemColumnImpl.getColumn("NEXT_QUALIFIERS", Types.VARCHAR, true, 512),
+            SystemColumnImpl.getColumn("HASH_KEY_COLUMN_NUMBERS", Types.VARCHAR, true, 512),
+            SystemColumnImpl.getColumn("HASH_TABLE_SIZE", Types.INTEGER, true),
+        };
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINScanPropsDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINSortPropsDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINSortPropsDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINSortPropsDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINSortPropsDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,125 @@
+package org.apache.derby.impl.sql.catalog;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+import org.apache.derby.impl.sql.catalog.SystemColumnImpl;
+import java.sql.Types;
+/**
+ * This class describes a Tuple for the XPLAIN_SORT_PROPS System Table.
+ *
+ */
+public class XPLAINSortPropsDescriptor extends XPLAINTableDescriptor 
+{
+
+    private UUID sort_rs_id;  // the sort props UUID
+    private String sort_type; // the sort type: internal or external
+    private Integer no_input_rows; // the number of input rows of this sort
+    private Integer no_output_rows; // the number of output rows of this sort
+    private Integer no_merge_runs; // the number of merge sort runs
+    private String merge_run_details; // merge run details, internal encoding
+    private String eliminate_dups; // eliminate duplicates during sort
+    private String in_sort_order; // is already in sorted order
+    private String distinct_aggregate; // has distinct aggregates
+    
+    public XPLAINSortPropsDescriptor() {}
+    public XPLAINSortPropsDescriptor
+    (
+             UUID sort_rs_id,
+             String sort_type,
+             Integer no_input_rows,
+             Integer no_output_rows,
+             Integer no_merge_runs,
+             String merge_run_details,
+             String eliminate_dups,
+             String in_sort_order,
+             String distinct_aggregate
+    )
+    {
+
+        this.sort_rs_id = sort_rs_id;
+        this.sort_type = sort_type;
+        this.no_input_rows = no_input_rows;
+        this.no_output_rows = no_output_rows;
+        this.no_merge_runs = no_merge_runs;
+        this.merge_run_details = merge_run_details;
+        this.eliminate_dups = eliminate_dups;
+        this.in_sort_order = in_sort_order;
+        this.distinct_aggregate = distinct_aggregate;
+        
+    }
+    public void setStatementParameters(PreparedStatement ps)
+        throws SQLException
+    {
+        ps.setString(1, sort_rs_id.toString());
+        ps.setString(2, sort_type);
+        if (no_input_rows != null)
+            ps.setInt(3, no_input_rows.intValue());
+        else
+            ps.setNull(3, Types.INTEGER);
+        if (no_output_rows != null)
+            ps.setInt(4, no_output_rows.intValue());
+        else
+            ps.setNull(4, Types.INTEGER);
+        if (no_merge_runs != null)
+            ps.setInt(5, no_merge_runs.intValue());
+        else
+            ps.setNull(5, Types.INTEGER);
+        ps.setString(6, merge_run_details);
+        ps.setString(7, eliminate_dups);
+        ps.setString(8, in_sort_order);
+        ps.setString(9, distinct_aggregate);
+    }
+    
+    public void setSort_type(String sort_type) {
+        this.sort_type = sort_type;
+    }
+
+    public void setNo_input_rows(Integer no_input_rows) {
+        this.no_input_rows = no_input_rows;
+    }
+
+    public void setNo_output_rows(Integer no_output_rows) {
+        this.no_output_rows = no_output_rows;
+    }
+
+    public void setNo_merge_runs(Integer no_merge_runs) {
+        this.no_merge_runs = no_merge_runs;
+    }
+
+    public void setMerge_run_details(String merge_run_details) {
+        this.merge_run_details = merge_run_details;
+    }
+
+
+    public String getCatalogName() { return TABLENAME_STRING; }
+    static  final   String  TABLENAME_STRING = "SYSXPLAIN_SORT_PROPS";
+
+    private static final String[][] indexColumnNames =
+    {
+        {"SORT_RS_ID"}
+    };
+
+    /**
+     * Builds a list of columns suitable for creating this Catalog.
+     *
+     * @return array of SystemColumn suitable for making this catalog.
+     */
+    public SystemColumn[] buildColumnList() {
+        return new SystemColumn[] {
+            SystemColumnImpl.getUUIDColumn("SORT_RS_ID", false),
+            SystemColumnImpl.getColumn("SORT_TYPE", Types.CHAR, true, 2),
+            SystemColumnImpl.getColumn("NO_INPUT_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_OUTPUT_ROWS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("NO_MERGE_RUNS", Types.INTEGER, true),
+            SystemColumnImpl.getColumn("MERGE_RUN_DETAILS", Types.VARCHAR, true, 256),
+            SystemColumnImpl.getColumn("ELIMINATE_DUPLICATES", Types.CHAR, true, 1),
+            SystemColumnImpl.getColumn("IN_SORT_ORDER", Types.CHAR, true, 1),
+            SystemColumnImpl.getColumn("DISTINCT_AGGREGATE", Types.CHAR, true, 1),
+
+        };
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINSortPropsDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,117 @@
+package org.apache.derby.impl.sql.catalog;
+
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+import java.sql.Timestamp;
+
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+import org.apache.derby.impl.sql.catalog.SystemColumnImpl;
+import org.apache.derby.iapi.types.TypeId;
+import java.sql.Types;
+
+public class XPLAINStatementDescriptor extends XPLAINTableDescriptor 
+{
+    
+    // implementation
+    private UUID stmt_id;           // the statement UUID
+    private String stmt_name;       // the statement name, if available
+    private String stmt_type;       // the statement type, e.g. select,insert, update, etc. 
+    private String stmt_text;       // the statement text 
+    private String jvm_id;          // the virtual machine identifier, only the code
+    private String os_id;           // the operating system identifier, from the os.home vm system variable
+    private String xplain_mode;     // the explain mode, either (F)ull explain or explain (O)nly
+    private Timestamp xplain_time;  // the explain timestamp, useful if statistics timing was off
+    private String thread_id;       // the explaining thread identifier      
+    private String xa_id;           // the transaction identifier
+    private String session_id;      // the session identifier (instance)
+    private String db_name;         // the database name
+    private String drda_id;         // the drda identifier
+    private UUID timing_id;         // the UUID of the associated timing tuple
+    
+    public XPLAINStatementDescriptor() {}
+    public XPLAINStatementDescriptor (
+            UUID stmt_id,
+            String stmt_name,
+            String stmt_type,
+            String stmt_text,
+            String jvm_id,
+            String os_id,
+            String xplain_mode,
+            Timestamp xplain_time,
+            String thread_id,
+            String xa_id,
+            String session_id,
+            String db_name,
+            String drda_id,
+            UUID timing_id
+    ){
+        
+        this.stmt_id     =  stmt_id;
+        this.stmt_name   =  stmt_name;
+        this.stmt_type   =  stmt_type;
+        this.stmt_text   = stmt_text;
+        this.jvm_id      = jvm_id;
+        this.os_id       = os_id;
+        this.xplain_mode = xplain_mode;
+        this.xplain_time = xplain_time;
+        this.thread_id   = thread_id;
+        this.xa_id       = xa_id;
+        this.session_id  = session_id;
+        this.db_name     = db_name;
+        this.drda_id     = drda_id;
+        this.timing_id   = timing_id;
+       
+    }
+    public void setStatementParameters(PreparedStatement ps)
+        throws SQLException
+    {
+        ps.setString(1, stmt_id.toString());
+        ps.setString(2, stmt_name);
+        ps.setString(3, stmt_type);
+        ps.setString(4, stmt_text);
+        ps.setString(5, jvm_id);
+        ps.setString(6, os_id);
+        ps.setString(7, xplain_mode);
+        ps.setTimestamp(8, xplain_time);
+        ps.setString(9, thread_id);
+        ps.setString(10, xa_id);
+        ps.setString(11, session_id);
+        ps.setString(12, db_name);
+        ps.setString(13, drda_id);
+        ps.setString(14, (timing_id != null ? timing_id.toString():null));
+    }
+    
+    public String getCatalogName() { return TABLENAME_STRING; }
+    static final String             TABLENAME_STRING = "SYSXPLAIN_STATEMENTS";
+
+    private static final String[][] indexColumnNames =
+    {
+        {"STMT_ID"}
+    };
+
+    /**
+     * Builds a list of columns suitable for creating this Catalog.
+     *
+     * @return array of SystemColumn suitable for making this catalog.
+     */
+    public SystemColumn[] buildColumnList() {
+        return new SystemColumn[] {
+            SystemColumnImpl.getUUIDColumn("STMT_ID", false),
+            SystemColumnImpl.getIdentifierColumn("STMT_NAME", true),
+            SystemColumnImpl.getColumn("STMT_TYPE", Types.CHAR, false, 3),
+            SystemColumnImpl.getColumn("STMT_TEXT", Types.VARCHAR, false, TypeId.VARCHAR_MAXWIDTH),
+            SystemColumnImpl.getColumn("JVM_ID", Types.CHAR, false, 30),
+            SystemColumnImpl.getColumn("OS_IDENTIFIER", Types.CHAR, false, 30),
+            SystemColumnImpl.getColumn("XPLAIN_MODE", Types.CHAR, true, 1),
+            SystemColumnImpl.getColumn("XPLAIN_TIME", Types.TIMESTAMP, true),
+            SystemColumnImpl.getColumn("XPLAIN_THREAD_ID", Types.CHAR, false, 32),
+            SystemColumnImpl.getColumn("TRANSACTION_ID", Types.CHAR, false, 32),
+            SystemColumnImpl.getColumn("SESSION_ID", Types.CHAR, false, 32),
+            SystemColumnImpl.getIdentifierColumn("DATABASE_NAME", false),
+            SystemColumnImpl.getColumn("DRDA_ID", Types.CHAR, true, 32),
+            SystemColumnImpl.getUUIDColumn("TIMING_ID", true),
+        };
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementTimingsDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementTimingsDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementTimingsDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementTimingsDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,119 @@
+package org.apache.derby.impl.sql.catalog;
+
+import java.sql.Timestamp;
+import java.sql.PreparedStatement;
+import java.sql.SQLException;
+
+import org.apache.derby.catalog.UUID;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+import org.apache.derby.impl.sql.catalog.SystemColumnImpl;
+import java.sql.Types;
+
+public class XPLAINStatementTimingsDescriptor extends XPLAINTableDescriptor 
+{
+
+    private UUID timing_id;  // the Timing UUID, which is saved in the xplain_Statements table, if statistics timing is switched on
+    private Long parse_time; // the time needed for parsing the stmt text 
+    private Long bind_time;  // the time needed for binding the node tree
+    private Long optimize_time; // time needed for optimizing the node tree
+    private Long generate_time; // time needed for class generation
+    private Long compile_time; // time needed for parse+bind+optimize+generate
+    private Long execute_time; // time needed for execution of class 
+    private Timestamp begin_comp_time; // the begin compilation timestamp
+    private Timestamp end_comp_time;   // the end   compilation timestamp
+    private Timestamp begin_exe_time;  // the begin execution timestamp
+    private Timestamp end_exe_time;    // the end   execution timestamp
+    
+    public XPLAINStatementTimingsDescriptor() {}
+    public XPLAINStatementTimingsDescriptor
+    (
+            UUID timing_id,
+            Long parse_time,
+            Long bind_time,
+            Long optimize_time,
+            Long generate_time,
+            Long compile_time,
+            Long execute_time,
+            Timestamp begin_comp_time,
+            Timestamp end_comp_time,
+            Timestamp begin_exe_time,
+            Timestamp end_exe_time
+    )
+    {
+        this.timing_id       = timing_id;
+        this.parse_time      = parse_time;
+        this.bind_time       = bind_time;
+        this.optimize_time   = optimize_time;
+        this.generate_time   = generate_time;
+        this.compile_time    = compile_time;
+        this.execute_time    = execute_time;
+        this.begin_comp_time = begin_comp_time;
+        this.end_comp_time   = end_comp_time;
+        this.begin_exe_time  = begin_exe_time;
+        this.end_exe_time    = end_exe_time;
+        
+    }
+    public void setStatementParameters(PreparedStatement ps)
+        throws SQLException
+    {
+        ps.setString(1, timing_id.toString());
+        if (parse_time != null)
+            ps.setLong(2, parse_time.longValue());
+        else
+            ps.setNull(2, Types.BIGINT);
+        if (bind_time != null)
+            ps.setLong(3, bind_time.longValue());
+        else
+            ps.setNull(3, Types.BIGINT);
+        if (optimize_time != null)
+            ps.setLong(4, optimize_time.longValue());
+        else
+            ps.setNull(4, Types.BIGINT);
+        if (generate_time != null)
+            ps.setLong(5, generate_time.longValue());
+        else
+            ps.setNull(5, Types.BIGINT);
+        if (compile_time != null)
+            ps.setLong(6, compile_time.longValue());
+        else
+            ps.setNull(6, Types.BIGINT);
+        if (execute_time != null)
+            ps.setLong(7, execute_time.longValue());
+        else
+            ps.setNull(7, Types.BIGINT);
+        ps.setTimestamp(8, begin_comp_time);
+        ps.setTimestamp(9, end_comp_time);
+        ps.setTimestamp(10, begin_exe_time);
+        ps.setTimestamp(11, end_exe_time);
+    }
+    
+    public String getCatalogName() { return TABLENAME_STRING; }
+    static final String             TABLENAME_STRING = "SYSXPLAIN_STATEMENT_TIMINGS";
+
+    private static final String[][] indexColumnNames =
+    {
+        {"TIMING_ID"}
+    };
+
+    /**
+     * Builds a list of columns suitable for creating this Catalog.
+     *
+     * @return array of SystemColumn suitable for making this catalog.
+     */
+    public SystemColumn[] buildColumnList() {
+        return new SystemColumn[] {
+            SystemColumnImpl.getUUIDColumn("TIMING_ID", false),
+            SystemColumnImpl.getColumn("PARSE_TIME", Types.BIGINT, false),
+            SystemColumnImpl.getColumn("BIND_TIME", Types.BIGINT, false),
+            SystemColumnImpl.getColumn("OPTIMIZE_TIME", Types.BIGINT, false),
+            SystemColumnImpl.getColumn("GENERATE_TIME", Types.BIGINT, false),
+            SystemColumnImpl.getColumn("COMPILE_TIME", Types.BIGINT, false),
+            SystemColumnImpl.getColumn("EXECUTE_TIME", Types.BIGINT, false),
+            SystemColumnImpl.getColumn("BEGIN_COMP_TIME", Types.TIMESTAMP, false),
+            SystemColumnImpl.getColumn("END_COMP_TIME", Types.TIMESTAMP, false),
+            SystemColumnImpl.getColumn("BEGIN_EXE_TIME", Types.TIMESTAMP, false),
+            SystemColumnImpl.getColumn("END_EXE_TIME", Types.TIMESTAMP, false),
+        };
+    }
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINStatementTimingsDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINTableDescriptor.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINTableDescriptor.java?rev=768597&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINTableDescriptor.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINTableDescriptor.java Sat Apr 25 20:21:03 2009
@@ -0,0 +1,61 @@
+package org.apache.derby.impl.sql.catalog;
+
+import org.apache.derby.iapi.util.IdUtil;
+import org.apache.derby.iapi.sql.dictionary.SystemColumn;
+
+public abstract class XPLAINTableDescriptor
+{
+    public abstract String getCatalogName();
+    protected abstract SystemColumn []buildColumnList();
+
+    private String tableInsertStmt;
+
+    public String[]getTableDDL(String schemaName)
+    {
+        String escapedSchema = IdUtil.normalToDelimited(schemaName);
+        String escapedTableName = IdUtil.normalToDelimited(getCatalogName());
+        SystemColumn []cols = buildColumnList();
+        StringBuffer buf = new StringBuffer();
+        StringBuffer insBuf = new StringBuffer();
+        StringBuffer valsBuf = new StringBuffer();
+        for (int c = 0; c < cols.length; c++)
+        {
+            if (c == 0)
+            {
+                buf.append("(");
+                insBuf.append("(");
+                valsBuf.append("(");
+            }
+            else
+            {
+                buf.append(",");
+                insBuf.append(",");
+                valsBuf.append(",");
+            }
+            buf.append(cols[c].getName());
+            insBuf.append(cols[c].getName());
+            valsBuf.append("?");
+            buf.append(" ");
+            buf.append(cols[c].getType().getCatalogType().getSQLstring());
+        }
+        buf.append(")");
+        insBuf.append(")");
+        valsBuf.append(")");
+        String query = 
+            "create table " + escapedSchema + "." + escapedTableName +
+            buf.toString();
+
+        // FIXME -- need to create the index, too.
+
+        tableInsertStmt =
+            "insert into " + escapedSchema + "." + escapedTableName +
+            insBuf.toString() + " values " + valsBuf.toString();
+
+        return new String[]{query};
+    }
+    public String getTableInsert()
+    {
+        return tableInsertStmt;
+    }
+}
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/XPLAINTableDescriptor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/conn/GenericLanguageConnectionContext.java Sat Apr 25 20:21:03 2009
@@ -117,6 +117,26 @@
 	private boolean runTimeStatisticsSetting ;
 	private boolean statisticsTiming;
 
+	/**
+	 * If xplainOnlyMode is set (via SYSCS_SET_XPLAIN_MODE), then the
+	 * connection does not actually execute statements, but only
+	 * compiles them, and emits the query plan information into the
+	 * XPLAIN tables.
+	 */
+	private boolean xplainOnlyMode = false;
+    
+	/** the current xplain schema. Is usually NULL. Can be set via
+	 * SYSCS_SET_XPLAIN_SCHEMA, in which case it species the schema into
+	 * which XPLAIN information should be stored in user tables.
+	 */
+	private String xplain_schema = null;
+	/**
+	 * For each XPLAIN table, this map stores a SQL INSERT statement which
+	 * can be prepared and used to insert rows into the table during the
+	 * capturing of statistics data into the user XPLAIN tables.
+	 */
+	private Map xplain_statements = new HashMap();
+	
 	//all the temporary tables declared for this connection
 	private ArrayList allDeclaredGlobalTempTables;
 	//The currentSavepointLevel is used to provide the rollback behavior of temporary tables.
@@ -3453,4 +3473,32 @@
 			getInitialDefaultSchemaDescriptor());
 	}
 
+
+	/** @see LanguageConnectionContext#getXplainOnlyMode() */
+	public boolean getXplainOnlyMode() {
+		return xplainOnlyMode;
+	}
+    
+	/** @see LanguageConnectionContext#setXplainOnlyMode(boolean) */
+	public void setXplainOnlyMode(boolean onOrOff) {
+		xplainOnlyMode = onOrOff;
+	}
+    
+	/** @see LanguageConnectionContext#getXplainSchema() */
+	public String getXplainSchema() {
+		return xplain_schema;
+	}
+    
+	/** @see LanguageConnectionContext#setXplainSchema(String) */
+	public void setXplainSchema(String s) {
+		xplain_schema = s;
+	}
+	public void setXplainStatement(Object key, Object stmt)
+	{
+		xplain_statements.put(key, stmt);
+	}
+	public Object getXplainStatement(Object key)
+	{
+		return xplain_statements.get(key);
+	}
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/BasicNoPutResultSetImpl.java Sat Apr 25 20:21:03 2009
@@ -241,8 +241,12 @@
 		attachStatementContext();
 
 		try {
-
-			openCore();
+			LanguageConnectionContext lcc = getLanguageConnectionContext();
+			if(lcc.getRunTimeStatisticsMode() && lcc.getXplainOnlyMode()) {
+				// do nothing
+			} else {
+				openCore();
+			}
 
 		} catch (StandardException se) {
 			activation.checkStatementValidity();
@@ -444,7 +448,14 @@
 	 */
 	public final ExecRow	getNextRow() throws StandardException 
 	{
-	    if ( ! isOpen ) {
+		LanguageConnectionContext lcc = getLanguageConnectionContext();
+		if(lcc.getRunTimeStatisticsMode() && lcc.getXplainOnlyMode()){
+			// return null to indicate no results available and 
+			// to bypass the execution
+			return null;
+		}
+		
+		if ( ! isOpen ) {
 			throw StandardException.newException(SQLState.LANG_RESULT_SET_NOT_OPEN, NEXT);
 		}
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericExecutionFactory.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericExecutionFactory.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericExecutionFactory.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericExecutionFactory.java Sat Apr 25 20:21:03 2009
@@ -40,6 +40,7 @@
 import org.apache.derby.iapi.sql.execute.ExecutionFactory;
 import org.apache.derby.iapi.sql.execute.ResultSetFactory;
 import org.apache.derby.iapi.sql.execute.ResultSetStatisticsFactory;
+import org.apache.derby.iapi.sql.execute.xplain.XPLAINFactoryIF;
 import org.apache.derby.iapi.sql.execute.ScanQualifier;
 import org.apache.derby.iapi.sql.Activation;
 import org.apache.derby.iapi.sql.ResultColumnDescriptor;
@@ -365,4 +366,29 @@
 	//
 	private ResultSetFactory rsFactory;
     private GenericConstantActionFactory	genericConstantActionFactory;
+
+private XPLAINFactoryIF xplainFactory; 
+ 
+ 
+   /**
+    * Get the XPLAINFactory from this ExecutionContext.
+    *
+    * @return  The XPLAINFactory associated with this
+    *      ExecutionContext
+    *
+    * @exception StandardException     Thrown on error
+    */
+   public XPLAINFactoryIF getXPLAINFactory()
+                   throws StandardException {
+       if (xplainFactory == null) {
+           xplainFactory = (XPLAINFactoryIF)
+               Monitor.bootServiceModule(
+                                   false,
+                                   this,
+                                   XPLAINFactoryIF.MODULE,
+                                   (Properties) null);
+       }
+       return xplainFactory;
+   }
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java?rev=768597&r1=768596&r2=768597&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/NoPutResultSetImpl.java Sat Apr 25 20:21:03 2009
@@ -33,6 +33,10 @@
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.execute.ExecIndexRow;
 import org.apache.derby.iapi.sql.execute.ExecRow;
+import org.apache.derby.iapi.sql.execute.ExecutionFactory;
+import org.apache.derby.iapi.sql.execute.ResultSetStatisticsFactory;
+import org.apache.derby.iapi.sql.execute.RunTimeStatistics;
+import org.apache.derby.iapi.sql.execute.xplain.XPLAINVisitor;
 import org.apache.derby.iapi.sql.execute.NoPutResultSet;
 import org.apache.derby.iapi.sql.execute.TargetResultSet;
 import org.apache.derby.iapi.store.access.Qualifier;
@@ -143,26 +147,28 @@
 			** time to dump out the information.
 			*/
 			LanguageConnectionContext lcc = getLanguageConnectionContext();
-			if (lcc.getRunTimeStatisticsMode())
-			{
-				endExecutionTime = getCurrentTimeMillis();
-                
-				lcc.setRunTimeStatisticsObject(
-					lcc.getLanguageConnectionFactory().getExecutionFactory().getResultSetStatisticsFactory().getRunTimeStatistics(activation, this, subqueryTrackingArray));
-
-				HeaderPrintWriter istream = lcc.getLogQueryPlan() ? Monitor.getStream() : null;
-				if (istream != null)
-				{
-					istream.printlnWithHeader(LanguageConnectionContext.xidStr + 
-											  lcc.getTransactionExecute().getTransactionIdString() +
-											  "), " +
-											  LanguageConnectionContext.lccStr +
-											  lcc.getInstanceNumber() +
-											  "), " +
-											  lcc.getRunTimeStatisticsObject().getStatementText() + " ******* " +
-											  lcc.getRunTimeStatisticsObject().getStatementExecutionPlanText());
-				}
-			}
+			
+                // only if statistics is switched on, collect & derive them
+                if (lcc.getRunTimeStatisticsMode())
+				{   
+                    endExecutionTime = getCurrentTimeMillis();
+
+                    // get the ResultSetStatisticsFactory, which gathers RuntimeStatistics
+                    ExecutionFactory ef = lcc.getLanguageConnectionFactory().getExecutionFactory();
+                    ResultSetStatisticsFactory rssf;
+                    rssf = ef.getResultSetStatisticsFactory();
+  
+                    // get the RuntimeStatisticsImpl object which is the wrapper for all 
+                    // gathered statistics about all the different resultsets
+                    RunTimeStatistics rsImpl = rssf.getRunTimeStatistics(activation, this, subqueryTrackingArray); 
+  
+                    // save the RTW (wrapper)object in the lcc
+                    lcc.setRunTimeStatisticsObject(rsImpl);
+                    
+                    // now explain gathered statistics, using an appropriate visitor
+                    XPLAINVisitor visitor = ef.getXPLAINFactory().getXPLAINVisitor();
+                    visitor.doXPLAIN(rsImpl,activation);
+  				}
 
 			int staLength = (subqueryTrackingArray == null) ? 0 :
 								subqueryTrackingArray.length;