db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rhille...@apache.org
Subject svn commit: r1500056 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/ engine/org/apache/derby/vti/ testing/org/apache/derbyTesting/functionTests/tests/lang/
Date Fri, 05 Jul 2013 16:17:17 GMT
Author: rhillegas
Date: Fri Jul  5 16:17:17 2013
New Revision: 1500056

URL: http://svn.apache.org/r1500056
Log:
DERBY-6211: Add basic tests for xml-based optimizer tracing; tests passed cleanly on derby-6211-09-aa-addTests.diff.

Added:
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RSMDWrapper.java
  (with props)
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLOptimizerTraceTest.java
  (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerTracer.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLOptTrace.java
    db/derby/code/trunk/java/engine/org/apache/derby/vti/XmlVTI.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerTracer.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerTracer.java?rev=1500056&r1=1500055&r2=1500056&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerTracer.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerTracer.java
Fri Jul  5 16:17:17 2013
@@ -21,7 +21,10 @@
 
 package org.apache.derby.impl.sql.compile;
 
+import java.io.IOException;
 import java.io.PrintWriter;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.sql.SQLException;
 import org.apache.derby.iapi.db.OptimizerTrace;
 import org.apache.derby.iapi.reference.SQLState;
@@ -132,31 +135,45 @@ public	class   OptimizerTracer  implemen
      * <li><b>fileName</b> - Where to write the optimizer trace. If omitted,
the trace is written to System.out.</li>
      * </ul>
      */
-    public  void    unloadTool( String... configurationParameters )
+    public  void    unloadTool( final String... configurationParameters )
         throws SQLException
     {
         try {
-            OptTrace    tracer = OptimizerTrace.getOptimizerTracer();
-            boolean     needsClosing = false;
+            final   OptTrace    tracer = OptimizerTrace.getOptimizerTracer();
 
-            PrintWriter pw;
-            if (
-                (configurationParameters != null) &&
-                (configurationParameters.length > 0)
-                )
-            {
-                pw = new PrintWriter( configurationParameters[ 0 ] );
-                needsClosing = true;
-            }
-            else { pw = new PrintWriter( System.out ); }
+            AccessController.doPrivileged
+                (
+                 new PrivilegedAction<Object>()
+                 {
+                     public Object run()
+                     {
+                         try {
+                             boolean     needsClosing = false;
+
+                             PrintWriter pw;
+                             if (
+                                 (configurationParameters != null) &&
+                                 (configurationParameters.length > 0)
+                                 )
+                             {
+                                 pw = new PrintWriter( configurationParameters[ 0 ] );
+                                 needsClosing = true;
+                             }
+                             else { pw = new PrintWriter( System.out ); }
         
-            if ( tracer != null )
-            {
-                tracer.printToWriter( pw );
-                pw.flush();
-            }
-
-            if ( needsClosing ) { pw.close(); }
+                             if ( tracer != null )
+                             {
+                                 tracer.printToWriter( pw );
+                                 pw.flush();
+                             }
+
+                             if ( needsClosing ) { pw.close(); }
+                         
+                             return null;
+                         } catch (IOException ioe) { throw new IllegalArgumentException(
ioe.getMessage(), ioe ); }
+                     }  
+                 }
+                 );
         }
         catch (Exception e) { throw wrap( e ); }
         finally

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLOptTrace.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLOptTrace.java?rev=1500056&r1=1500055&r2=1500056&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLOptTrace.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLOptTrace.java Fri
Jul  5 16:17:17 2013
@@ -39,10 +39,13 @@ import org.apache.derby.iapi.sql.compile
 import org.apache.derby.iapi.sql.compile.Optimizable;
 import org.apache.derby.iapi.sql.compile.OptimizableList;
 import org.apache.derby.iapi.sql.compile.Optimizer;
+import org.apache.derby.iapi.sql.compile.OptimizerPlan;
 import org.apache.derby.iapi.sql.compile.RequiredRowOrdering;
+import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.dictionary.AliasDescriptor;
 import org.apache.derby.iapi.sql.dictionary.TableDescriptor;
 import org.apache.derby.iapi.sql.dictionary.ConglomerateDescriptor;
+import org.apache.derby.iapi.sql.dictionary.UniqueTupleDescriptor;
 import org.apache.derby.iapi.util.IdUtil;
 import org.apache.derby.iapi.util.JBitSet;
 import org.w3c.dom.Document;
@@ -106,7 +109,6 @@ class   XMLOptTrace implements  OptTrace
     private static  final   String  PC_COMPLETE = "pcComplete";
     private static  final   String  PC_AVOID_SORT= "pcAvoidSort";
     private static  final   String  PC_SUMMARY= "pcSummary";
-    private static  final   String  PC_VERBOSE= "pcVerbose";
 
     // CostEstimate tags
     private static  final   String  CE_ESTIMATED_COST = "ceEstimatedCost";
@@ -140,7 +142,6 @@ class   XMLOptTrace implements  OptTrace
         "    qbID   int,\n" +
         "    complete  boolean,\n" +
         "    summary   varchar( 32672 ),\n" +
-        "    verbose   varchar( 32672 ),\n" +
         "    type        varchar( 50 ),\n" +
         "    estimatedCost        double,\n" +
         "    estimatedRowCount    bigint\n" +
@@ -158,7 +159,7 @@ class   XMLOptTrace implements  OptTrace
         "        'FILE_URL',\n" +
         "        'planCost',\n" +
         "        asList( '" + STMT_TEXT + "', '" + STMT_ID + "', '" + QBLOCK_ID + "' ),\n"
+
-        "        asList( '" + PC_COMPLETE + "', '" + PC_SUMMARY + "', '" + PC_VERBOSE + "',
'" + PC_TYPE + "', '" +
+        "        asList( '" + PC_COMPLETE + "', '" + PC_SUMMARY + "', '" + PC_TYPE + "',
'" +
         CE_ESTIMATED_COST + "', '" + CE_ROW_COUNT + "' )\n" +
         "     )\n" +
         ") v\n";
@@ -186,6 +187,10 @@ class   XMLOptTrace implements  OptTrace
     private JoinStrategy    _currentDecorationStrategy;
     private Element         _currentDecoration;
 
+    // context
+    private ContextManager  _cm;
+    private LanguageConnectionContext   _lcc;
+
     ////////////////////////////////////////////////////////////////////////
     //
     //	CONSTRUCTOR
@@ -248,6 +253,13 @@ class   XMLOptTrace implements  OptTrace
             for ( int i = 0; i < _currentOptimizableList.size(); i++ )
             {
                 Optimizable opt = _currentOptimizableList.getOptimizable( i );
+
+                if ( i == 0 )
+                {
+                    _cm = ((QueryTreeNode) opt).getContextManager();
+                    _lcc = (LanguageConnectionContext) _cm.getContext( LanguageConnectionContext.CONTEXT_ID
);
+                }
+                
                 Element optElement = createElement
                     ( _currentQuery, QBLOCK_OPTIMIZABLE, getOptimizableName( opt ).getFullSQLName()
);
                 optElement.setAttribute( QBLOCK_OPT_TABLE_NUMBER, Integer.toString( opt.getTableNumber()
) );
@@ -489,15 +501,13 @@ class   XMLOptTrace implements  OptTrace
     /** Get the name of an optimizable */
     private TableName    getOptimizableName( Optimizable optimizable )
     {
-        ContextManager  cm = ((QueryTreeNode) optimizable).getContextManager();
-        
         try {
             if ( isBaseTable( optimizable ) )
             {
                 ProjectRestrictNode prn = (ProjectRestrictNode) optimizable;
                 TableDescriptor td = 
                     ((FromBaseTable) prn.getChildResult()).getTableDescriptor();
-                return makeTableName( td.getSchemaName(), td.getName(), cm );
+                return makeTableName( td.getSchemaName(), td.getName(), _cm );
             }
             else if ( OptimizerImpl.isTableFunction( optimizable ) )
             {
@@ -505,7 +515,7 @@ class   XMLOptTrace implements  OptTrace
                 AliasDescriptor ad =
                     ((StaticMethodCallNode) ((FromVTI) prn.getChildResult()).
                         getMethodCall() ).ad;
-                return makeTableName( ad.getSchemaName(), ad.getName(), cm );
+                return makeTableName( ad.getSchemaName(), ad.getName(), _cm );
             }
             else if ( isFromTable( optimizable ) )
             {
@@ -523,7 +533,7 @@ class   XMLOptTrace implements  OptTrace
         String  nodeClass = optimizable.getClass().getName();
         String  unqualifiedName = nodeClass.substring( nodeClass.lastIndexOf( "." ) + 1 );
 
-        return makeTableName( null, unqualifiedName, cm );
+        return makeTableName( null, unqualifiedName, _cm );
     }
 
     /** Return true if the optimizable is a base table */
@@ -597,8 +607,7 @@ class   XMLOptTrace implements  OptTrace
         if ( isComplete( planOrder ) ) { cost.setAttribute( PC_COMPLETE, "true" ); }
         if ( planType == Optimizer.SORT_AVOIDANCE_PLAN ) { cost.setAttribute( PC_AVOID_SORT,
"true" ); }
 
-        createElement( cost, PC_SUMMARY, formatPlanSummary( planOrder, planType, false )
);
-        createElement( cost, PC_VERBOSE, formatPlanSummary( planOrder, planType, true ) );
+        createElement( cost, PC_SUMMARY, formatPlanSummary( planOrder, planType ) );
         formatCost( cost, raw );
 
         return cost;
@@ -666,96 +675,57 @@ class   XMLOptTrace implements  OptTrace
      * factor :== factor | conglomerateName
      * </pre>
      */
-    private String  formatPlanSummary( int[] planOrder, int planType, boolean verbose )
+    private String  formatPlanSummary( int[] planOrder, int planType )
     {
-        StringBuilder   buffer = new StringBuilder();
-        boolean     avoidSort = (planType == Optimizer.SORT_AVOIDANCE_PLAN);
-
-        // a negative optimizable number indicates the end of the plan
-        int planLength = 0;
-        for ( ; planLength < planOrder.length; planLength++ )
-        {
-            if ( planOrder[ planLength ] < 0 ) { break; }
-        }
-
-        // only add parentheses if there are more than 2 slots in the join order
-        int     dontNeedParentheses = 2;
-        int     lastParenthesizedIndex = planLength - dontNeedParentheses;
-        for ( int i = 0; i < lastParenthesizedIndex; i++ ) { buffer.append( "(" ); }
+        try {
+            OptimizerPlan   plan = null;
         
-        for ( int i = 0; i < planLength; i++ )
-        {
-            int     listIndex = planOrder[ i ];
+            StringBuilder   buffer = new StringBuilder();
+            boolean     avoidSort = (planType == Optimizer.SORT_AVOIDANCE_PLAN);
 
-            if ( listIndex >= _currentOptimizableList.size() )
+            // a negative optimizable number indicates the end of the plan
+            int planLength = 0;
+            for ( ; planLength < planOrder.length; planLength++ )
             {
-                // should never happen!
-                buffer.append( "{ UNKNOWN LIST INDEX " + listIndex + " } " );
-                continue;
+                if ( planOrder[ planLength ] < 0 ) { break; }
             }
 
-            Optimizable optimizable = _currentOptimizableList.getOptimizable( listIndex );
-            
-            AccessPath  ap = avoidSort ?
-                optimizable.getBestSortAvoidancePath() : optimizable.getBestAccessPath();
-            ConglomerateDescriptor  cd = ap.getConglomerateDescriptor();
-            String  conglomerateName = getSQLName( optimizable, cd, verbose );
-            JoinStrategy    js = ap.getJoinStrategy();
-
-            //
-            // The very first optimizable in the join order obiously doesn't join
-            // to anything before it. For that reason, its join strategy is always
-            // NESTED_LOOP. We can just assume that and not clutter up the
-            // representation with vacuous information.
-            //
-            if ( i > 0 ) { buffer.append( " " + js.getOperatorSymbol() + " " ); }
-            
-            buffer.append( conglomerateName );
-            if ( (i > 0) && (i <= lastParenthesizedIndex) ) { buffer.append(
")" ); }
-        }
+            for ( int i = 0; i < planLength; i++ )
+            {
+                int     listIndex = planOrder[ i ];
 
-        return buffer.toString();
-    }
+                if ( listIndex >= _currentOptimizableList.size() )
+                {
+                    // should never happen!
+                    buffer.append( "{ UNKNOWN LIST INDEX " + listIndex + " } " );
+                    continue;
+                }
 
-    /**
-     * <p>
-     * Get a human-readable name for a conglomerate.
-     * </p>
-     */
-    private String  getSQLName( Optimizable optimizable, ConglomerateDescriptor cd, boolean
verbose )
-    {
-        if ( !verbose && (cd != null) )
-        {
-            String  schemaName = getOptimizableName( optimizable ).getSchemaName();
-            String  conglomerateName = cd.getConglomerateName();
+                Optimizable optimizable = _currentOptimizableList.getOptimizable( listIndex
);
+            
+                AccessPath  ap = avoidSort ?
+                    optimizable.getBestSortAvoidancePath() : optimizable.getBestAccessPath();
+                JoinStrategy    js = ap.getJoinStrategy();
+                UniqueTupleDescriptor   utd = OptimizerImpl.isTableFunction( optimizable
) ?
+                    ((StaticMethodCallNode) ((FromVTI) ((ProjectRestrictNode) optimizable).getChildResult()).getMethodCall()).ad
:
+                    ap.getConglomerateDescriptor();
 
-            return IdUtil.mkQualifiedName( schemaName, conglomerateName );
-        }
+                OptimizerPlan   current = OptimizerPlan.makeRowSource( utd, _lcc.getDataDictionary()
);
 
-        boolean isTableFunction = OptimizerImpl.isTableFunction( optimizable );
-        StringBuilder   buffer = new StringBuilder();
-        buffer.append( getOptimizableName( optimizable ).getFullSQLName() );
-        if ( isTableFunction ) { buffer.append( TABLE_FUNCTION_FLAG ); }
-        
-        if ( (cd != null) && cd.isIndex() )
-        {
-            buffer.append( "{" );
-            String[]	columnNames = cd.getColumnNames();
-            
-            if ( columnNames != null )
-            {
-                int[]   keyColumns = cd.getIndexDescriptor().baseColumnPositions();
-                
-                for ( int i = 0; i < keyColumns.length; i++ )
+                if ( plan != null )
                 {
-                    if ( i > 0 ) { buffer.append( "," ); }
-                    buffer.append( columnNames[ keyColumns[ i ] - 1 ] );
+                    current = new OptimizerPlan.Join( js, plan, current );
                 }
+
+                plan = current;
             }
-            buffer.append( "}" );
-        }
 
-        return buffer.toString();
+            return plan.toString();
+        }
+        catch (Exception e)
+        {
+            return e.getMessage();
+        }
     }
-    
+
 }

Modified: db/derby/code/trunk/java/engine/org/apache/derby/vti/XmlVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/vti/XmlVTI.java?rev=1500056&r1=1500055&r2=1500056&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/vti/XmlVTI.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/vti/XmlVTI.java Fri Jul  5 16:17:17 2013
@@ -23,6 +23,9 @@ package org.apache.derby.vti;
 
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.text.DateFormat;
@@ -34,6 +37,7 @@ import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
 
 /**
  * <p>
@@ -308,15 +312,30 @@ public  class   XmlVTI  extends StringCo
         
         _builder = factory.newDocumentBuilder();
 
-        File                file = new File( _xmlResourceName );
-        FileInputStream     is = new FileInputStream( file );
-        Document        doc = _builder.parse( is );
-        Element             root = doc.getDocumentElement();
-
-        _rawRows = root.getElementsByTagName( _rowTag );
-        _rowCount = _rawRows.getLength();
-
-        is.close();
+        AccessController.doPrivileged
+            (
+             new PrivilegedAction<Object>()
+             {
+                 public Object run()
+                 {
+                     try {
+                         File                file = new File( _xmlResourceName );
+                         FileInputStream     is = new FileInputStream( file );
+                         Document        doc = _builder.parse( is );
+                         Element             root = doc.getDocumentElement();
+                         
+                         _rawRows = root.getElementsByTagName( _rowTag );
+                         _rowCount = _rawRows.getLength();
+                         
+                         is.close();
+                         
+                         return null;
+                     }
+                     catch (IOException ioe) { throw new IllegalArgumentException( ioe.getMessage(),
ioe ); }
+                     catch (SAXException ioe) { throw new IllegalArgumentException( ioe.getMessage(),
ioe ); }
+                 }  
+             }
+           );
     }
     
     /**

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RSMDWrapper.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RSMDWrapper.java?rev=1500056&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RSMDWrapper.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RSMDWrapper.java
Fri Jul  5 16:17:17 2013
@@ -0,0 +1,204 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.RSMDWrapper
+
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.lang.reflect.Method;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Types;
+
+import org.apache.derby.vti.StringColumnVTI;
+
+/**
+ * <p>
+ * Table function wrapping the result set meta data for a query.
+ * </p>
+ */
+public class RSMDWrapper extends StringColumnVTI
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private static final String[] COLUMN_NAMES = new String[]
+    {
+        "getCatalogName",
+        "getColumnClassName",
+        "getColumnDisplaySize",
+        "getColumnLabel",
+        "getColumnName",
+        "getColumnType",
+        "getColumnTypeName",
+        "getPrecision",
+        "getScale",
+        "getSchemaName",
+        "getTableName",
+        "isAutoIncrement",
+        "isCaseSensitive",
+        "isCurrency",
+        "isDefinitelyWritable",
+        "isNullable",
+        "isReadOnly",
+        "isSearchable",
+        "isSigned",
+        "isWritable",
+    };
+
+    private static final int[] COLUMN_TYPES = new int[]
+    {
+        Types.VARCHAR,
+        Types.VARCHAR,
+        Types.INTEGER,
+        Types.VARCHAR,
+        Types.VARCHAR,
+        Types.INTEGER,
+        Types.VARCHAR,
+        Types.INTEGER,
+        Types.INTEGER,
+        Types.VARCHAR,
+        Types.VARCHAR,
+        Types.BOOLEAN,
+        Types.BOOLEAN,
+        Types.BOOLEAN,
+        Types.BOOLEAN,
+        Types.INTEGER,
+        Types.BOOLEAN,
+        Types.BOOLEAN,
+        Types.BOOLEAN,
+        Types.BOOLEAN,
+    };
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private Method[] _methods;
+    private ResultSetMetaData _rsmd;
+    private int _rowCount;
+    private int _currentRow;
+    private Integer _currentRowNumber;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // TABLE FUNCTION
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * This is the method which is registered as a table function.
+     * </p>
+     */
+    public static ResultSet getResultSetMetaData( String query )
+        throws Exception
+    {
+        return new RSMDWrapper( DriverManager.getConnection( "jdbc:default:connection" ),
query );
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public RSMDWrapper( Connection conn, String query ) throws Exception
+    {
+        super( COLUMN_NAMES );
+
+        loadMethods();
+
+        PreparedStatement ps = conn.prepareStatement( query );
+        ResultSet rs = ps.executeQuery();
+
+        _rsmd = rs.getMetaData();
+        _rowCount = _rsmd.getColumnCount();
+        _currentRow = 0;
+
+        rs.close();
+        ps.close();
+    }
+    private void loadMethods() throws Exception
+    {
+        int count = COLUMN_NAMES.length;
+
+        _methods = new Method[ count ];
+
+        for ( int i = 0; i < count; i++ )
+        {
+            _methods[ i ] = ResultSetMetaData.class.getMethod( COLUMN_NAMES[ i ], Integer.TYPE
);
+        }
+    }
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // IMPLEMENTATIONS OF ABSTRACT METHODS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public boolean next() throws SQLException
+    {
+        if ( _currentRow >= _rowCount ) { return false; }
+
+        _currentRow++;
+        _currentRowNumber = new Integer( _currentRow );
+        
+        return true;
+    }
+    public void close()
+    {
+        _rsmd = null;
+    }
+    public ResultSetMetaData getMetaData() { return null; }
+
+    protected  String  getRawColumn( int columnNumber ) throws SQLException
+    {
+        int zeroIdx = columnNumber - 1;
+        Method method = _methods[ zeroIdx ];
+
+        Object result = null;
+
+        try {
+            result = method.invoke( _rsmd, _currentRowNumber );
+        }
+        catch (Exception e)
+        {
+            e.printStackTrace();
+            throw new SQLException( "Could not invoke method '" + method + "'" );
+        }
+
+        int columnType = COLUMN_TYPES[ zeroIdx ];
+        switch( columnType )
+        {
+            case Types.VARCHAR: return (String) result;
+            case Types.INTEGER: return ((Integer) result).toString();
+            case Types.BOOLEAN: return ((Boolean) result).toString();
+            default: throw new SQLException( "Unknown data type: " + columnType );
+        }
+    }
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/RSMDWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLOptimizerTraceTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLOptimizerTraceTest.java?rev=1500056&view=auto
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLOptimizerTraceTest.java
(added)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLOptimizerTraceTest.java
Fri Jul  5 16:17:17 2013
@@ -0,0 +1,334 @@
+/*
+
+   Derby - Class org.apache.derbyTesting.functionTests.tests.lang.XMLOptimizerTraceTest
+   
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to you under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+     http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+ */
+
+package org.apache.derbyTesting.functionTests.tests.lang;
+
+import java.io.File;
+import java.sql.CallableStatement;
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import org.apache.derbyTesting.junit.Decorator;
+import org.apache.derbyTesting.junit.SupportFilesSetup;
+import org.apache.derbyTesting.junit.TestConfiguration;
+import org.apache.derbyTesting.junit.JDBC;
+
+/**
+ * <p>
+ * Test xml-based optimizer tracing, introduced by DERBY-6211.
+ * </p>
+ */
+public class XMLOptimizerTraceTest  extends GeneratedColumnsHelper
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    private static  final   String  TRACE_FILE_NAME = "xott.xml";
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Create a new instance.
+     */
+
+    public XMLOptimizerTraceTest(String name)
+    {
+        super(name);
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // JUnit BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+
+    /**
+     * Construct top level suite in this JUnit test
+     */
+    public static Test suite()
+    {
+        TestSuite       suite = new TestSuite( "XMLOptimizerTraceTest" );
+
+        suite.addTest( TestConfiguration.defaultSuite( XMLOptimizerTraceTest.class ) );
+
+        return new SupportFilesSetup( TestConfiguration.singleUseDatabaseDecorator( suite
) );
+    }
+
+    protected void    setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        Connection conn = getConnection();
+
+        if ( !routineExists( conn, "INTEGERLIST" ) )
+        {
+            goodStatement
+                (
+                 conn,
+                 "create function integerList()\n" +
+                 "returns table( a int, b int, c int, d int )\n" +
+                 "language java parameter style derby_jdbc_result_set no sql\n" +
+                 "external name 'org.apache.derbyTesting.functionTests.tests.lang.RestrictedVTITest.integerList'\n"
+                 );
+        }
+        
+        if ( !routineExists( conn, "GETRESULTSETMETADATA" ) )
+        {
+            goodStatement
+                (
+                 conn,
+                 "create function getResultSetMetaData( query varchar( 32672 ) )\n" +
+                 "returns table\n" +
+                 "(\n" +
+                 "        getCatalogName varchar( 32672 ),\n" +
+                 "        getColumnClassName varchar( 32672 ),\n" +
+                 "        getColumnDisplaySize int,\n" +
+                 "        getColumnLabel varchar( 32672 ),\n" +
+                 "        getColumnName varchar( 32672 ),\n" +
+                 "        getColumnType int,\n" +
+                 "        getColumnTypeName varchar( 32672 ),\n" +
+                 "        getPrecision int,\n" +
+                 "        getScale int,\n" +
+                 "        getSchemaName varchar( 32672 ),\n" +
+                 "        getTableName varchar( 32672 ),\n" +
+                 "        isAutoIncrement boolean,\n" +
+                 "        isCaseSensitive boolean,\n" +
+                 "        isCurrency boolean,\n" +
+                 "        isDefinitelyWritable boolean,\n" +
+                 "        isNullable int,\n" +
+                 "        isReadOnly boolean,\n" +
+                 "        isSearchable boolean,\n" +
+                 "        isSigned boolean,\n" +
+                 "        isWritable boolean\n" +
+                 ")\n" +
+                 "language java parameter style derby_jdbc_result_set reads sql data\n" +
+                 "external name 'org.apache.derbyTesting.functionTests.tests.lang.RSMDWrapper.getResultSetMetaData'\n"
+                 );
+        }
+        
+        if ( !tableExists( conn, "T" ) )
+        {
+            goodStatement
+                (
+                 conn,
+                 "create table t( a int, b varchar( 100 ) )"
+                 );
+            goodStatement
+                (
+                 conn,
+                 "create index t_a on t( a )"
+                 );
+        }
+        
+        if ( !tableExists( conn, "S" ) )
+        {
+            goodStatement
+                (
+                 conn,
+                 "create table s( a int, b varchar( 100 ) )"
+                 );
+            goodStatement
+                (
+                 conn,
+                 "create index s_a on s( a )"
+                 );
+        }
+        
+        if ( !tableExists( conn, "R" ) )
+        {
+            goodStatement
+                (
+                 conn,
+                 "create table r( a int, b varchar( 100 ) )"
+                 );
+            goodStatement
+                (
+                 conn,
+                 "create index r_a on r( a )"
+                 );
+        }
+    }
+    
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // TESTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * <p>
+     * Test the planCost table function.
+     * </p>
+     */
+    public void test_01_planCost() throws Exception
+    {
+        Connection conn = getConnection();
+        File    traceFile = SupportFilesSetup.getReadWrite( TRACE_FILE_NAME );
+
+        // turn on xml-based optimizer tracing and run some queries
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_register_tool( 'optimizerTracing', true, 'xml' )"
+             );
+
+        // 2-table query
+        goodStatement
+            (
+             conn,
+             "select s.a from t, s where t.a = s.a"
+             );
+        // 3-table query
+        goodStatement
+            (
+             conn,
+             "select s.a from t, s, r where t.a = s.a and s.a = r.a"
+             );
+        // query involving a table function
+        goodStatement
+            (
+             conn,
+             "select s.a from s, table( integerList() ) i where s.a = i.a"
+             );
+
+        // turn off optimizer tracing and dump the xml trace to a file
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_register_tool( 'optimizerTracing', false, '" + traceFile.getPath()
+ "' )"
+             );
+
+        // install the planCost table function and view
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_register_tool( 'optimizerTracingViews', true, '" + traceFile.getPath()
+ "' )"
+             );
+
+        // verify the full signature of the planCost table function
+        assertResults
+            (
+             conn,
+             "select getColumnName, getColumnTypeName, getPrecision from table( getResultSetMetaData(
'select * from planCost where 1=2' ) ) g",
+             new String[][]
+             {
+                 { "TEXT", "VARCHAR", "32672" },
+                 { "STMTID", "INTEGER", "10" },
+                 { "QBID", "INTEGER", "10" },
+                 { "COMPLETE", "BOOLEAN", "1" },
+                 { "SUMMARY", "VARCHAR", "32672" },
+                 { "TYPE", "VARCHAR", "50" },
+                 { "ESTIMATEDCOST", "DOUBLE", "15" },
+                 { "ESTIMATEDROWCOUNT", "BIGINT", "19" },         
+             },
+             false
+             );
+
+        // verify some contents of the xml output which we hope will remain stable
+        // across test platforms
+        assertResults
+            (
+             conn,
+             "select distinct stmtID, summary from planCost where complete order by stmtID,
summary",
+             new String[][]
+             {
+                 { "1", "( \"APP\".\"S_A\" # \"APP\".\"T_A\" )" },
+                 { "1", "( \"APP\".\"T_A\" # \"APP\".\"S_A\" )" },
+                 { "2", "( ( \"APP\".\"R_A\" # \"APP\".\"S_A\" ) * \"APP\".\"T_A\" )" },
+                 { "2", "( ( \"APP\".\"R_A\" # \"APP\".\"T_A\" ) * \"APP\".\"S_A\" )" },
+                 { "2", "( ( \"APP\".\"S_A\" # \"APP\".\"R_A\" ) * \"APP\".\"T_A\" )" },
+                 { "2", "( ( \"APP\".\"S_A\" # \"APP\".\"T_A\" ) * \"APP\".\"R_A\" )" },
+                 { "2", "( ( \"APP\".\"T_A\" # \"APP\".\"R_A\" ) * \"APP\".\"S_A\" )" },
+                 { "2", "( ( \"APP\".\"T_A\" # \"APP\".\"S_A\" ) * \"APP\".\"R_A\" )" },
+                 { "3", "( \"APP\".\"INTEGERLIST\"() # \"APP\".\"S_A\" )" },
+                 { "3", "( \"APP\".\"S_A\" # \"APP\".\"INTEGERLIST\"() )" },
+             },
+             false
+             );
+
+        // uninstall the planCost table function and view
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_register_tool( 'optimizerTracingViews', false )"
+             );
+    }
+
+   ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // MINIONS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** Return true if the SQL routine exists */
+    private boolean routineExists( Connection conn, String functionName ) throws Exception
+    {
+        PreparedStatement ps = chattyPrepare( conn, "select count (*) from sys.sysaliases
where alias = ?" );
+        ps.setString( 1, functionName );
+
+        ResultSet rs = ps.executeQuery();
+        rs.next();
+
+        boolean retval = rs.getInt( 1 ) > 0 ? true : false;
+
+        rs.close();
+        ps.close();
+
+        return retval;
+    }
+
+    /** Return true if the table exists */
+    private boolean tableExists( Connection conn, String tableName ) throws Exception
+    {
+        PreparedStatement ps = chattyPrepare( conn, "select count (*) from sys.systables
where tablename = ?" );
+        ps.setString( 1, tableName );
+
+        ResultSet rs = ps.executeQuery();
+        rs.next();
+
+        boolean retval = rs.getInt( 1 ) > 0 ? true : false;
+
+        rs.close();
+        ps.close();
+
+        return retval;
+    }
+
+}

Propchange: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/XMLOptimizerTraceTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java?rev=1500056&r1=1500055&r2=1500056&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
(original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/_Suite.java
Fri Jul  5 16:17:17 2013
@@ -238,6 +238,7 @@ public class _Suite extends BaseTestCase
         suite.addTest(QueryPlanTest.suite());
         suite.addTest(Derby6131.suite());
         suite.addTest(NewOptimizerOverridesTest.suite());
+        suite.addTest(XMLOptimizerTraceTest.suite());
         return suite;
 	}
 }



Mime
View raw message