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 2013/07/09 20:07:05 UTC
svn commit: r1501411 - in /db/derby/code/trunk/java:
engine/org/apache/derby/iapi/sql/compile/
engine/org/apache/derby/impl/sql/compile/
engine/org/apache/derby/impl/sql/execute/
testing/org/apache/derbyTesting/functionTests/tests/lang/
Author: rhillegas
Date: Tue Jul 9 18:07:05 2013
New Revision: 1501411
URL: http://svn.apache.org/r1501411
Log:
DERBY-6267: Count row sources in optimizer overrides at optimize() time rather than bind() time; add more tests for optimizer overrides; tests passed cleanly on derby-6267-02-aa-moreTests.diff.
Modified:
db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/OptimizerPlan.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java
db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.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/GenericAggregateResultSet.java
db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NewOptimizerOverridesTest.java
Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/OptimizerPlan.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/OptimizerPlan.java?rev=1501411&r1=1501410&r2=1501411&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/OptimizerPlan.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/sql/compile/OptimizerPlan.java Tue Jul 9 18:07:05 2013
@@ -94,8 +94,7 @@ public abstract class OptimizerPlan
(
DataDictionary dataDictionary,
LanguageConnectionContext lcc,
- CompilerContext cc,
- int fromListSize
+ CompilerContext cc
)
throws StandardException;
@@ -157,29 +156,18 @@ public abstract class OptimizerPlan
(
DataDictionary dataDictionary,
LanguageConnectionContext lcc,
- CompilerContext cc,
- int fromListSize
+ CompilerContext cc
)
throws StandardException
{
- if ( fromListSize > 0 )
- {
- int leafNodeCount = countLeafNodes();
- if ( fromListSize != leafNodeCount )
- {
- throw StandardException.newException
- ( SQLState.LANG_BAD_ROW_SOURCE_COUNT, leafNodeCount, fromListSize );
- }
- }
-
// only left-deep trees allowed at this time
if ( !( rightChild instanceof RowSource ) )
{
throw StandardException.newException( SQLState.LANG_NOT_LEFT_DEEP );
}
- leftChild.bind( dataDictionary, lcc, cc, (leftChild instanceof RowSource) ? 1 : -1 );
- rightChild.bind( dataDictionary, lcc, cc, (rightChild instanceof RowSource) ? 1 : -1 );
+ leftChild.bind( dataDictionary, lcc, cc );
+ rightChild.bind( dataDictionary, lcc, cc );
_isBound = true;
}
@@ -252,17 +240,10 @@ public abstract class OptimizerPlan
(
DataDictionary dataDictionary,
LanguageConnectionContext lcc,
- CompilerContext cc,
- int fromListSize
+ CompilerContext cc
)
throws StandardException
{
- if ( fromListSize != 1 )
- {
- throw StandardException.newException
- ( SQLState.LANG_BAD_ROW_SOURCE_COUNT, 1, fromListSize );
- }
-
// bind the schema name
if ( _schema == null )
{
@@ -317,12 +298,11 @@ public abstract class OptimizerPlan
(
DataDictionary dataDictionary,
LanguageConnectionContext lcc,
- CompilerContext cc,
- int fromListSize
+ CompilerContext cc
)
throws StandardException
{
- super.bind( dataDictionary, lcc, cc, fromListSize );
+ super.bind( dataDictionary, lcc, cc );
if ( _descriptor == null )
{
@@ -351,12 +331,11 @@ public abstract class OptimizerPlan
(
DataDictionary dataDictionary,
LanguageConnectionContext lcc,
- CompilerContext cc,
- int fromListSize
+ CompilerContext cc
)
throws StandardException
{
- super.bind( dataDictionary, lcc, cc, fromListSize );
+ super.bind( dataDictionary, lcc, cc );
if ( _descriptor == null )
{
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java?rev=1501411&r1=1501410&r2=1501411&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/OptimizerImpl.java Tue Jul 9 18:07:05 2013
@@ -285,6 +285,14 @@ class OptimizerImpl implements Optimizer
{
throw StandardException.newException( SQLState.LANG_UNRESOLVED_ROW_SOURCE );
}
+
+ int actualRowSourceCount = optimizableList.size();
+ int overriddenRowSourceCount = overridingPlan.countLeafNodes();
+ if ( actualRowSourceCount != overriddenRowSourceCount )
+ {
+ throw StandardException.newException
+ ( SQLState.LANG_BAD_ROW_SOURCE_COUNT, overriddenRowSourceCount, actualRowSourceCount );
+ }
}
}
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java?rev=1501411&r1=1501410&r2=1501411&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/SelectNode.java Tue Jul 9 18:07:05 2013
@@ -527,7 +527,7 @@ class SelectNode extends ResultSetNode
// if an explicit join plan is requested, bind it
if ( overridingPlan != null )
{
- overridingPlan.bind( dataDictionary, getLanguageConnectionContext(), getCompilerContext(), fromList.size() );
+ overridingPlan.bind( dataDictionary, getLanguageConnectionContext(), getCompilerContext() );
}
return this;
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=1501411&r1=1501410&r2=1501411&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 Tue Jul 9 18:07:05 2013
@@ -21,6 +21,7 @@
package org.apache.derby.impl.sql.execute;
+import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -1064,15 +1065,19 @@ implements NoPutResultSet
*/
public static Element toXML( Element parentNode, String childTag, ResultSet rs ) throws Exception
{
- String childClassName = rs.getClass().getName();
- String typeAttribute = childClassName.substring( childClassName.lastIndexOf( "." ) + 1 );
Element result = parentNode.getOwnerDocument().createElement( childTag );
- result.setAttribute( "type", typeAttribute );
+ result.setAttribute( "type", stripPackage( rs.getClass().getName() ) );
parentNode.appendChild( result );
return result;
}
+ /** Strip the package location from a class name */
+ private static String stripPackage( String className )
+ {
+ return className.substring( className.lastIndexOf( "." ) + 1 );
+ }
+
/**
* <p>
* Pretty-print the inner ResultSet fields inside an outer ResultSet.
@@ -1096,10 +1101,38 @@ implements NoPutResultSet
// Add those fields as children of the outer element.
for ( Field field : fields )
{
- ResultSet innerRS = (ResultSet) field.get( outerRS );
+ Object fieldContents = field.get( outerRS );
- if ( innerRS != null) { innerRS.toXML( outerNode, field.getName() ); }
- }
+ if ( fieldContents != null )
+ {
+ if ( field.getType().isArray() )
+ {
+ Element arrayNode = outerNode.getOwnerDocument().createElement( "array" );
+ arrayNode.setAttribute( "arrayName", field.getName() );
+ String typeName = stripPackage( field.getType().getComponentType().getName() ) + "[]";
+ arrayNode.setAttribute( "type", typeName );
+ outerNode.appendChild( arrayNode );
+
+ int arrayLength = Array.getLength( fieldContents );
+ for ( int i = 0; i < arrayLength; i++ )
+ {
+ ResultSet cellRS = (ResultSet) Array.get( fieldContents, i );
+
+ if ( cellRS != null )
+ {
+ Element cellNode = cellRS.toXML( arrayNode, "cell" );
+ cellNode.setAttribute( "cellNumber", Integer.toString( i ) );
+ }
+ }
+ }
+ else
+ {
+ ResultSet innerRS = (ResultSet) fieldContents;
+
+ innerRS.toXML( outerNode, field.getName() );
+ }
+ } // end if fieldContents is not null
+ } // end loop through fields
return outerNode;
}
@@ -1128,6 +1161,13 @@ implements NoPutResultSet
for ( Field field : fields )
{
if ( ResultSet.class.isAssignableFrom( field.getType() ) ) { fieldList.add( field ); }
+ else if ( field.getType().isArray() )
+ {
+ if ( ResultSet.class.isAssignableFrom( field.getType().getComponentType() ) )
+ {
+ fieldList.add( field );
+ }
+ }
}
findResultSetFields( fieldList, klass.getSuperclass() );
Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregateResultSet.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregateResultSet.java?rev=1501411&r1=1501410&r2=1501411&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregateResultSet.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/execute/GenericAggregateResultSet.java Tue Jul 9 18:07:05 2013
@@ -22,6 +22,9 @@
package org.apache.derby.impl.sql.execute;
import java.util.Vector;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
import org.apache.derby.iapi.error.SQLWarningFactory;
import org.apache.derby.iapi.error.StandardException;
@@ -200,4 +203,18 @@ abstract class GenericAggregateResultSet
super.finish();
}
+ public Element toXML( Element parentNode, String tag ) throws Exception
+ {
+ // don't report the redundant originalSource node
+
+ Element result = super.toXML( parentNode, tag );
+ NodeList children = result.getChildNodes();
+ for ( int i = 0; i < children.getLength(); i++ )
+ {
+ Node child = children.item( 0 );
+ if ( "originalSource".equals( child.getNodeName() ) ) { result.removeChild( child ); }
+ }
+
+ return result;
+ }
}
Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NewOptimizerOverridesTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NewOptimizerOverridesTest.java?rev=1501411&r1=1501410&r2=1501411&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NewOptimizerOverridesTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/NewOptimizerOverridesTest.java Tue Jul 9 18:07:05 2013
@@ -193,19 +193,19 @@ public class NewOptimizerOverridesTest
( WRONG_ROW_SOURCE_COUNT,
"select tablename from v, sys.syscolumns\n" +
"where tablename = columnname\n" +
- "--derbyplan A\n"
+ "--derbyplan sys.syscolumns_heap\n"
);
expectCompilationError
( WRONG_ROW_SOURCE_COUNT,
"select tablename from v, sys.syscolumns\n" +
"where tablename = columnname\n" +
- "--derbyplan A.B\n"
+ "--derbyplan sys.syscolumns_heap\n"
);
expectCompilationError
( WRONG_ROW_SOURCE_COUNT,
"select tablename from v, sys.syscolumns\n" +
"where tablename = columnname\n" +
- "--derbyplan ( ( A.B # C.D ) * E )\n"
+ "--derbyplan ( ( sys.syscolumns_heap # sys.syscolumns_heap ) * sys.syscolumns_heap )\n"
);
// unknown conglomerates
@@ -323,6 +323,54 @@ public class NewOptimizerOverridesTest
select + "\n--derbyplan ( ((SYS.SYSSEQUENCES_INDEX2 # SYS.SYSCOLUMNS_HEAP) # SYS.SYSCOLUMNS_HEAP) # SYS.SYSTABLES_INDEX1 )"
);
+ //
+ // Union query with a separate override clause per branch.
+ //
+ assertPlanShape
+ (
+ conn,
+
+ "select tablename from sys.systables t, sys.syscolumns c, sys.sysaliases a\n" +
+ "where tablename = columnname and tablename = alias\n" +
+ "--derbyplan ( ( sys.systables_index1 # sys.syscolumns_heap ) # sys.sysaliases_index1 )\n" +
+ "union all\n" +
+ "select columnname from sys.systables t, sys.syscolumns c, sys.syssequences s\n" +
+ "where tablename = columnname and tablename = sequencename\n" +
+ "--derbyplan ( ( sys.systables_index1 # sys.syssequences_index2 ) # sys.syscolumns_heap )\n",
+
+ "( ( ( SYSTABLES_INDEX1 # SYSCOLUMNS ) # SYSALIASES_INDEX1 ) ) union ( ( ( SYSTABLES_INDEX1 # SYSSEQUENCES_INDEX2 ) # SYSCOLUMNS ) )"
+ );
+
+ //
+ // Subquery in the WHERE clause (flattened into the main query).
+ //
+ assertPlanShape
+ (
+ conn,
+
+ "select tableid, c.referenceid\n" +
+ "from sys.systables, ( select referenceid from sys.syscolumns ) c\n" +
+ "where 1=2\n" +
+ "--derbyplan ( sys.systables_heap * sys.syscolumns_heap )\n",
+
+ "( SYSTABLES * SYSCOLUMNS )"
+ );
+
+ //
+ // NOT IN subquery (flattened into outer query block).
+ //
+ assertPlanShape
+ (
+ conn,
+
+ "select tableid\n" +
+ "from sys.systables\n" +
+ "where tableid not in ( select referenceid from sys.syscolumns )\n" +
+ "--derbyplan ( sys.systables_heap # sys.syscolumns_index1 )\n",
+
+ "( SYSTABLES # SYSCOLUMNS_INDEX1 )"
+ );
+
}
///////////////////////////////////////////////////////////////////////////////////
@@ -412,6 +460,7 @@ public class NewOptimizerOverridesTest
if ( "HashJoinResultSet".equals( type ) ) { summarizeJoin( buffer, element, "#" ); }
else if ( "NestedLoopJoinResultSet".equals( type ) ) { summarizeJoin( buffer, element, "*" ); }
else if ( "ProjectRestrictResultSet".equals( type ) ) { summarize( buffer, getFirstElement( element, "source" ) ); }
+ else if ( "UnionResultSet".equals( type ) ) { summarizeUnion( buffer, element ); }
else
{
String indexName = element.getAttribute( "indexName" );
@@ -435,6 +484,21 @@ public class NewOptimizerOverridesTest
buffer.append( " )" );
}
+ private static void summarizeUnion( StringBuilder buffer, Element union )
+ throws Exception
+ {
+ NodeList list = union.getChildNodes();
+
+ for ( int i = 0; i < list.getLength(); i++ )
+ {
+ Element child = (Element) list.item( i );
+ if ( i > 0 ) { buffer.append( " union " ); }
+ buffer.append( "( " );
+ summarize( buffer, child );
+ buffer.append( " )" );
+ }
+ }
+
/** Get first element by the give tag name */
private static Element getFirstElement( Element parent, String tag ) throws Exception
{