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 rh...@apache.org on 2012/07/11 19:14:49 UTC

svn commit: r1360306 - in /db/derby/code/trunk/java: engine/org/apache/derby/impl/sql/compile/FromVTI.java testing/org/apache/derbyTesting/functionTests/tests/lang/SysDiagVTIMappingTest.java

Author: rhillegas
Date: Wed Jul 11 17:14:49 2012
New Revision: 1360306

URL: http://svn.apache.org/viewvc?rev=1360306&view=rev
Log:
DERBY-5554: Allow multiple tables in FROM lists which join tables to VTI arguments.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromVTI.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SysDiagVTIMappingTest.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromVTI.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromVTI.java?rev=1360306&r1=1360305&r2=1360306&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromVTI.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/FromVTI.java Wed Jul 11 17:14:49 2012
@@ -117,6 +117,9 @@ public class FromVTI extends FromTable i
     private String[] projectedColumnNames; // for RestrictedVTIs
     private Restriction vtiRestriction; // for RestrictedVTIs
 
+    // for remapping column references in VTI args at code generation time
+    private HashMap argSources = new HashMap();
+
     /**
 	 * @param invocation		The constructor or static method for the VTI
 	 * @param correlationName	The correlation name
@@ -885,13 +888,17 @@ public class FromVTI extends FromTable i
             // VTI parameters to refer to other VTIs.
             //
             int referencedTableNumber = ref.getTableNumber();
-                
+
             for ( int i = 0; i < fromListParam.size(); i++ )
             {
                 FromTable   fromTable = (FromTable) fromListParam.elementAt( i );
 
                 if ( referencedTableNumber == fromTable.getTableNumber() )
                 {
+                    // remember this FromTable so that we can code generate the arg
+                    // from actual result columns later on.
+                    argSources.put( new Integer( fromTable.getTableNumber() ), fromTable );
+                    
                     if ( isDerbyStyleTableFunction || (fromTable instanceof FromVTI) )
                     {
                         throw StandardException.newException
@@ -1503,6 +1510,7 @@ public class FromVTI extends FromTable i
 		 */
 		RemapCRsVisitor rcrv = new RemapCRsVisitor(true);
 		methodCall.accept(rcrv);
+        remapBaseTableColumns();
 
 		/* Get the next ResultSet #, so that we can number this ResultSetNode, its
 		 * ResultColumnList and ResultSet.
@@ -1514,6 +1522,36 @@ public class FromVTI extends FromTable i
 		mb.callMethod(VMOpcode.INVOKEINTERFACE, (String) null, "getVTIResultSet",ClassName.NoPutResultSet, nargs);
 	}
 
+    /**
+     * <p>
+     * Remap the column references in vti arguments.
+     * Point those column references at the result columns for the base table. This
+     * prevents us from code-generating the args from references to unfilled columns in
+     * higher join nodes. See DERBY-5554.
+     * </p>
+     */
+    private void remapBaseTableColumns() throws StandardException
+    {
+		Vector colRefs = getNodesFromParameters(ColumnReference.class);
+		for (Enumeration e = colRefs.elements(); e.hasMoreElements(); )
+		{
+			ColumnReference ref = (ColumnReference)e.nextElement();
+            FromTable   fromTable = (FromTable) argSources.get( new Integer( ref.getTableNumber() ) );
+
+            if ( fromTable != null )
+            {
+                ResultColumnList    rcl = fromTable.getResultColumns();
+
+                if ( rcl != null )
+                {
+                    ResultColumn    newRC = rcl.getResultColumn( ref.getColumnName() );
+
+                    if ( newRC != null ) { ref.setSource( newRC ); }
+                }
+            }
+        }
+    }
+
 	private int getScanArguments(ActivationClassBuilder acb,
 										  MethodBuilder mb)
 		throws StandardException

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SysDiagVTIMappingTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SysDiagVTIMappingTest.java?rev=1360306&r1=1360305&r2=1360306&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SysDiagVTIMappingTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SysDiagVTIMappingTest.java Wed Jul 11 17:14:49 2012
@@ -369,7 +369,35 @@ public final class SysDiagVTIMappingTest
         
         JDBC.assertColumnNames(rs, ALL_SPACE_TABLE_COLUMNS);
         JDBC.assertFullResultSet(rs, expRS, true);
+
+        // verify the fix to DERBY-5554: joins to VTIs in the FROM list still
+        // work when there are more than 1 base tables in the FROM list and
+        // they join in the WHERE clause
         
+        rs = st.executeQuery
+            (
+             "select t2.*\n" +
+             "    from\n" +
+             "        sys.systables systabs,\n" +
+             "        table (syscs_diag.space_table(systabs.tablename)) as t2,\n" +
+             "        sys.sysconglomerates syscgs\n" +
+             "    where systabs.tabletype = 'T' and systabs.tableid = syscgs.tableid\n"
+             );        
+        JDBC.assertColumnNames(rs, ALL_SPACE_TABLE_COLUMNS);
+        JDBC.assertFullResultSet(rs, expRS, true);
+
+        rs = st.executeQuery
+            (
+             "select t2.*\n" +
+             "    from\n" +
+             "        sys.sysconglomerates syscgs,\n" +
+             "        table (syscs_diag.space_table(systabs.tablename)) as t2,\n" +
+             "        sys.systables systabs\n" +
+             "    where systabs.tabletype = 'T' and systabs.tableid = syscgs.tableid\n"
+             );        
+        JDBC.assertColumnNames(rs, ALL_SPACE_TABLE_COLUMNS);
+        JDBC.assertFullResultSet(rs, expRS, true);
+
         // Now do some sanity checking to make sure SPACE_TABLE cannot be
         // used in any illegal ways.