Return-Path: X-Original-To: apmail-db-derby-commits-archive@www.apache.org Delivered-To: apmail-db-derby-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id CE308C208 for ; Thu, 20 Jun 2013 12:32:30 +0000 (UTC) Received: (qmail 49998 invoked by uid 500); 20 Jun 2013 12:32:29 -0000 Delivered-To: apmail-db-derby-commits-archive@db.apache.org Received: (qmail 49934 invoked by uid 500); 20 Jun 2013 12:32:28 -0000 Mailing-List: contact derby-commits-help@db.apache.org; run by ezmlm Precedence: bulk list-help: list-unsubscribe: List-Post: Reply-To: "Derby Development" List-Id: Delivered-To: mailing list derby-commits@db.apache.org Received: (qmail 49925 invoked by uid 99); 20 Jun 2013 12:32:27 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Jun 2013 12:32:27 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 20 Jun 2013 12:32:23 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id F0A9B2388C2A; Thu, 20 Jun 2013 12:32:02 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1494954 - in /db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile: TableName.java XMLOptTrace.java Date: Thu, 20 Jun 2013 12:32:02 -0000 To: derby-commits@db.apache.org From: rhillegas@apache.org X-Mailer: svnmailer-1.0.8-patched Message-Id: <20130620123202.F0A9B2388C2A@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: rhillegas Date: Thu Jun 20 12:32:02 2013 New Revision: 1494954 URL: http://svn.apache.org/r1494954 Log: DERBY-6211: Use schema-qualified names in plan summaries printed by the xml-based optimizer tracer; commit derby-6211-07-ab-useSchemaQualifiedNamesInSummaries.diff. Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/XMLOptTrace.java Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java?rev=1494954&r1=1494953&r2=1494954&view=diff ============================================================================== --- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java (original) +++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/compile/TableName.java Thu Jun 20 12:32:02 2013 @@ -31,6 +31,7 @@ import org.apache.derby.iapi.services.sa import org.apache.derby.iapi.reference.Property; import org.apache.derby.iapi.reference.SQLState; +import org.apache.derby.iapi.util.IdUtil; /** * A TableName represents a qualified name, externally represented as a schema name @@ -143,6 +144,14 @@ public class TableName extends QueryTree return tableName; } + /** + * Get the full SQL name of this object, properly quoted and escaped. + */ + public String getFullSQLName() + { + return IdUtil.mkQualifiedName( schemaName, tableName ); + } + /** * Convert this object to a String. See comments in QueryTreeNode.java * for how this should be done for tree printing. 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=1494954&r1=1494953&r2=1494954&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 Thu Jun 20 12:32:02 2013 @@ -48,6 +48,9 @@ import org.apache.derby.iapi.sql.compile import org.apache.derby.iapi.sql.compile.OptimizableList; import org.apache.derby.iapi.sql.compile.Optimizer; import org.apache.derby.iapi.sql.compile.RequiredRowOrdering; +import org.apache.derby.iapi.sql.dictionary.AliasDescriptor; +import org.apache.derby.iapi.sql.dictionary.TableDescriptor; +import org.apache.derby.iapi.util.IdUtil; /** * Optimizer tracer which produces output in an xml format. @@ -118,6 +121,9 @@ class XMLOptTrace implements OptTrace private static final String SEL_COUNT = "selCount"; private static final String SEL_SELECTIVITY = "selSelectivity"; + // distinguish table function names from conglomerate names + private static final String TABLE_FUNCTION_FLAG = "()"; + // // Statement and view for declaring a table function which reads the planCost element. // This table function is an instance of the XmlVTI and assumes that you have @@ -246,7 +252,8 @@ class XMLOptTrace implements OptTrace for ( int i = 0; i < _currentOptimizableList.size(); i++ ) { Optimizable opt = _currentOptimizableList.getOptimizable( i ); - Element optElement = createElement( _currentQuery, QBLOCK_OPTIMIZABLE, getOptimizableName( opt ) ); + Element optElement = createElement + ( _currentQuery, QBLOCK_OPTIMIZABLE, getOptimizableName( opt ).getFullSQLName() ); optElement.setAttribute( QBLOCK_OPT_TABLE_NUMBER, Integer.toString( opt.getTableNumber() ) ); } } @@ -293,7 +300,7 @@ class XMLOptTrace implements OptTrace Element skip = formatSkip ( _currentQuery, QBLOCK_SKIP, - "Useless join order. " + getOptimizableName( opt ) + " depends on tables after it in the join order" + "Useless join order. " + getOptimizableName( opt ).getFullSQLName() + " depends on tables after it in the join order" ); formatJoinOrder( skip, proposedJoinOrder ); } @@ -376,7 +383,7 @@ class XMLOptTrace implements OptTrace _currentDecoration = createElement( _currentJoinsElement, DECORATION, null ); _currentDecoration.setAttribute( DECORATION_CONGLOM_NAME, cd.getConglomerateName() ); - _currentDecoration.setAttribute( DECORATION_TABLE_NAME, getOptimizableName( opt ) ); + _currentDecoration.setAttribute( DECORATION_TABLE_NAME, getOptimizableName( opt ).toString() ); _currentDecoration.setAttribute( DECORATION_JOIN_STRATEGY, _currentDecorationStrategy.getName() ); String[] columnNames = cd.getColumnNames(); @@ -483,38 +490,78 @@ class XMLOptTrace implements OptTrace return null; } - /** Get the name of a optimizables */ - private String getOptimizableName( Optimizable optimizable ) + /** Get the name of an optimizable */ + private TableName getOptimizableName( Optimizable optimizable ) { - String name = null; - - if ( optimizable instanceof ProjectRestrictNode ) - { - ProjectRestrictNode prn = (ProjectRestrictNode) optimizable; - ResultSetNode rsn = prn.getChildResult(); - if ( rsn instanceof FromBaseTable ) + try { + if ( isBaseTable( optimizable ) ) { - try { - name = ((FromBaseTable) rsn).getTableName().getFullTableName(); - } - catch (StandardException e) - { - // Technically, an exception could occur here if the table name - // was not previously bound and if an error occured while binding it. - // But the FromBaseTable should have been bound long before optimization, - // so this should not be a problem. - } + TableDescriptor td = ((FromBaseTable) ((ProjectRestrictNode) optimizable).getChildResult()).getTableDescriptor(); + return makeTableName( td.getSchemaName(), td.getName() ); + } + else if ( isTableFunction( optimizable ) ) + { + AliasDescriptor ad = + ((StaticMethodCallNode) ((FromVTI) ((ProjectRestrictNode) optimizable).getChildResult()).getMethodCall() ).ad; + return makeTableName( ad.getSchemaName(), ad.getName() ); + } + else if ( isFromTable( optimizable ) ) + { + return ((FromTable) ((ProjectRestrictNode) optimizable).getChildResult()).getTableName(); } } - - // fallback - if ( name == null ) + catch (StandardException e) { - String nodeClass = optimizable.getClass().getName(); - name = nodeClass.substring( nodeClass.lastIndexOf( "." ) + 1 ); + // Technically, an exception could occur here if the table name + // was not previously bound and if an error occured while binding it. + // But the optimizable should have been bound long before optimization, + // so this should not be a problem. } - return name; + String nodeClass = optimizable.getClass().getName(); + String unqualifiedName = nodeClass.substring( nodeClass.lastIndexOf( "." ) + 1 ); + + return makeTableName( null, unqualifiedName ); + } + + /** Return true if the optimizable is a base table */ + private boolean isBaseTable( Optimizable optimizable ) + { + if ( !( optimizable instanceof ProjectRestrictNode ) ) { return false; } + + ResultSetNode rsn = ((ProjectRestrictNode) optimizable).getChildResult(); + + return ( rsn instanceof FromBaseTable ); + } + + /** Return true if the optimizable is a FromTable */ + private boolean isFromTable( Optimizable optimizable ) + { + if ( !( optimizable instanceof ProjectRestrictNode ) ) { return false; } + + ResultSetNode rsn = ((ProjectRestrictNode) optimizable).getChildResult(); + + return ( rsn instanceof FromTable ); + } + + /** Return true if the optimizable is a table function */ + private boolean isTableFunction( Optimizable optimizable ) + { + if ( !( optimizable instanceof ProjectRestrictNode ) ) { return false; } + + ResultSetNode rsn = ((ProjectRestrictNode) optimizable).getChildResult(); + if ( !( rsn instanceof FromVTI ) ) { return false; } + + return ( ((FromVTI) rsn).getMethodCall() instanceof StaticMethodCallNode ); + } + + /** Make a TableName */ + private TableName makeTableName( String schemaName, String unqualifiedName ) + { + TableName result = new TableName(); + result.init( schemaName, unqualifiedName ); + + return result; } /** Print an exception to the log file */ @@ -607,7 +654,7 @@ class XMLOptTrace implements OptTrace if ( optimizableNumber >= 0 ) { Optimizable optimizable = _currentOptimizableList.getOptimizable( optimizableNumber ); - createElement( parent, JO_SLOT, getOptimizableName( optimizable ) ); + createElement( parent, JO_SLOT, getOptimizableName( optimizable ).getFullSQLName() ); } } } @@ -661,7 +708,7 @@ class XMLOptTrace implements OptTrace AccessPath ap = avoidSort ? optimizable.getBestSortAvoidancePath() : optimizable.getBestAccessPath(); ConglomerateDescriptor cd = ap.getConglomerateDescriptor(); - String conglomerateName = getConglomerateName( optimizable, cd, verbose ); + String conglomerateName = getSQLName( optimizable, cd, verbose ); JoinStrategy js = ap.getJoinStrategy(); // @@ -684,14 +731,22 @@ class XMLOptTrace implements OptTrace * Get a human-readable name for a conglomerate. *

*/ - private String getConglomerateName( Optimizable optimizable, ConglomerateDescriptor cd, boolean verbose ) + private String getSQLName( Optimizable optimizable, ConglomerateDescriptor cd, boolean verbose ) { - if ( !verbose ) { return cd.getConglomerateName(); } + if ( !verbose && (cd != null) ) + { + String schemaName = getOptimizableName( optimizable ).getSchemaName(); + String conglomerateName = cd.getConglomerateName(); + + return IdUtil.mkQualifiedName( schemaName, conglomerateName ); + } + boolean isTableFunction = isTableFunction( optimizable ); StringBuilder buffer = new StringBuilder(); - buffer.append( getOptimizableName( optimizable ) ); + buffer.append( getOptimizableName( optimizable ).getFullSQLName() ); + if ( isTableFunction ) { buffer.append( TABLE_FUNCTION_FLAG ); } - if ( cd.isIndex() ) + if ( (cd != null) && cd.isIndex() ) { buffer.append( "{" ); String[] columnNames = cd.getColumnNames();