public VoltXMLDiff runDDLCommandAndDiff ( HSQLDDLInfo stmtInfo , String ddl ) throws HSQLParseException { // name of the table we're going to have to diff (if any) String expectedTableAffected = null ; // If we fail to pre-process a statement, then we want to fail, but we're // still going to run the statement through HSQL to get its error message. // This variable helps us make sure we don't fail to preprocess and then // succeed at runnign the statement through HSQL. boolean expectFailure = false ; // If cascade, we're going to need to look for any views that might have // gotten deleted. So get a list of all tables and views that existed before // we run the ddl, then we'll do a comparison later. Set < String > existingTableNames = null ; if ( stmtInfo != null ) { if ( stmtInfo . cascade ) { existingTableNames = getTableNames ( ) ; } // we either have an index name or a table/view name, but not both if ( stmtInfo . noun == HSQLDDLInfo . Noun . INDEX ) { if ( stmtInfo . verb == HSQLDDLInfo . Verb . CREATE ) { expectedTableAffected = stmtInfo . secondName ; } else { expectedTableAffected = tableNameForIndexName ( stmtInfo . name ) ; } } else { expectedTableAffected = stmtInfo . name ; } // Note that we're assuming ifexists can't happen with "create" expectFailure = ( expectedTableAffected == null ) && ! stmtInfo . ifexists ; } else { expectFailure = true ; } runDDLCommand ( ddl ) ; // If we expect to fail, but the statement above didn't bail... // (Shouldn't get here ever I think) if ( expectFailure ) { throw new HSQLParseException ( "Unable to plan statement due to VoltDB DDL pre-processing error" ) ; } // sanity checks for non-failure assert ( stmtInfo != null ) ; // get old and new XML representations for the affected table VoltXMLElement tableXMLNew = null , tableXMLOld = null ; if ( expectedTableAffected != null ) { tableXMLNew = getXMLForTable ( expectedTableAffected ) ; tableXMLOld = lastSchema . get ( expectedTableAffected ) ; } // valid reasons for tableXMLNew to be null are DROP IF EXISTS and not much else if ( tableXMLNew == null ) { tableXMLNew = emptySchema ; } // the old table can be null for CREATE TABLE or for IF EXISTS stuff if ( tableXMLOld == null ) { tableXMLOld = emptySchema ; } VoltXMLDiff diff = VoltXMLElement . computeDiff ( tableXMLOld , tableXMLNew ) ; // now find any views that might be missing and make sure the diff reflects that // they're gone if ( stmtInfo . cascade ) { Set < String > finalTableNames = getTableNames ( ) ; for ( String tableName : existingTableNames ) { if ( ! finalTableNames . contains ( tableName ) ) { tableName = tableName . toLowerCase ( ) ; tableXMLOld = lastSchema . get ( tableName ) . children . get ( 0 ) ; lastSchema . remove ( tableName ) ; if ( tableName . equals ( expectedTableAffected ) ) { continue ; } diff . m_removedElements . add ( tableXMLOld ) ; } } } // this is a hack to allow the diff-apply-er to accept a diff that has no order diff . m_elementOrder . clear ( ) ; // remember the current schema if ( expectedTableAffected != null ) { lastSchema . put ( expectedTableAffected , tableXMLNew . duplicate ( ) ) ; } return diff ; }
Modify the current schema with a SQL DDL command and get the diff which represents the changes .