Skip to content

Commit

Permalink
[BACKLOG-26374] steps creating field name conflicts (#5939)
Browse files Browse the repository at this point in the history
repeated field names could arise after inserting or deleting value metas
select values not checking for conflicts when renaming
  • Loading branch information
tgf authored and marcoslarsen committed Oct 31, 2018
1 parent 25c38fd commit 79dc48a
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 10 deletions.
26 changes: 20 additions & 6 deletions core/src/main/java/org/pentaho/di/core/row/RowMeta.java
Expand Up @@ -253,7 +253,8 @@ public void addValueMeta( int index, ValueMetaInterface meta ) {
newMeta = renameValueMetaIfInRow( meta, null ); newMeta = renameValueMetaIfInRow( meta, null );
} }
valueMetaList.add( index, newMeta ); valueMetaList.add( index, newMeta );
cache.invalidate(); cache.storeMapping( newMeta.getName(), index );
cache.updateFrom( index + 1, valueMetaList );
needRealClone = null; needRealClone = null;
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
Expand Down Expand Up @@ -809,8 +810,11 @@ public void removeValueMeta( String valueName ) throws KettleValueException {
public void removeValueMeta( int index ) { public void removeValueMeta( int index ) {
lock.writeLock().lock(); lock.writeLock().lock();
try { try {
valueMetaList.remove( index ); ValueMetaInterface old = valueMetaList.remove( index );
cache.invalidate(); if ( old != null ) {
cache.removeMapping( old.getName() );
cache.updateFrom( index, valueMetaList );
}
needRealClone = null; needRealClone = null;
} finally { } finally {
lock.writeLock().unlock(); lock.writeLock().unlock();
Expand Down Expand Up @@ -1291,12 +1295,22 @@ void storeMapping( String name, int index ) {
} }


void replaceMapping( String old, String current, int index ) { void replaceMapping( String old, String current, int index ) {
if ( !Utils.isEmpty( old ) ) { removeMapping( old );
mapping.remove( old.toLowerCase() );
}
storeMapping( current, index ); storeMapping( current, index );
} }


void removeMapping( String toRemove ) {
if ( !Utils.isEmpty( toRemove ) ) {
mapping.remove( toRemove.toLowerCase() );
}
}

void updateFrom( int idx, List<ValueMetaInterface> metas ) {
for ( int i = idx; i < metas.size(); i++ ) {
storeMapping( metas.get( i ).getName(), i );
}
}

Integer findAndCompare( String name, List<? extends ValueMetaInterface> metas ) { Integer findAndCompare( String name, List<? extends ValueMetaInterface> metas ) {
if ( Utils.isEmpty( name ) ) { if ( Utils.isEmpty( name ) ) {
return null; return null;
Expand Down
17 changes: 17 additions & 0 deletions core/src/test/java/org/pentaho/di/core/row/RowMetaTest.java
Expand Up @@ -214,6 +214,23 @@ public void testSetValueMetaDup() throws KettlePluginException {
assertEquals( "Original is still the same (name)", 1, rowMeta.indexOfValue( "dup" ) ); assertEquals( "Original is still the same (name)", 1, rowMeta.indexOfValue( "dup" ) );
assertEquals( "Renaming happened", 2, rowMeta.indexOfValue( "dup_1" ) ); assertEquals( "Renaming happened", 2, rowMeta.indexOfValue( "dup_1" ) );
} }

@Test
public void testInsertValueMetaDup() throws Exception {
rowMeta.addValueMeta( 1, new ValueMetaInteger( integer.getName() ) );
assertEquals( "inserted", 4, rowMeta.size() );
assertEquals( "rename new", "integer_1", rowMeta.getValueMeta( 1 ).getName() );
rowMeta.addValueMeta( new ValueMetaInteger( integer.getName() ) );
assertEquals( "rename after", "integer_2", rowMeta.getValueMeta( 4 ).getName() );
}

@Test
public void testRemoveValueMetaDup() throws Exception {
rowMeta.removeValueMeta( date.getName() );
assertEquals( "removed", 2, rowMeta.size() );
rowMeta.addValueMeta( new ValueMetaInteger( integer.getName() ) );
assertEquals( "rename after", "integer_1", rowMeta.getValueMeta( 2 ).getName() );
}


@Test @Test
public void testSetValueMetaNullName() throws KettlePluginException { public void testSetValueMetaNullName() throws KettlePluginException {
Expand Down
Expand Up @@ -411,6 +411,8 @@ public void getMetadataFields( RowMetaInterface inputRowMeta, String name, Varia
if ( !v.getName().equals( metaChange.getRename() ) && !Utils.isEmpty( metaChange.getRename() ) ) { if ( !v.getName().equals( metaChange.getRename() ) && !Utils.isEmpty( metaChange.getRename() ) ) {
v.setName( metaChange.getRename() ); v.setName( metaChange.getRename() );
v.setOrigin( name ); v.setOrigin( name );
// need to reinsert to check name conflicts
inputRowMeta.setValueMeta( idx, v );
} }
// Change the type? // Change the type?
if ( metaChange.getType() != ValueMetaInterface.TYPE_NONE && v.getType() != metaChange.getType() ) { if ( metaChange.getType() != ValueMetaInterface.TYPE_NONE && v.getType() != metaChange.getType() ) {
Expand Down
Expand Up @@ -2,7 +2,7 @@
* *
* Pentaho Data Integration * Pentaho Data Integration
* *
* Copyright (C) 2002-2017 by Hitachi Vantara : http://www.pentaho.com * Copyright (C) 2002-2018 by Hitachi Vantara : http://www.pentaho.com
* *
******************************************************************************* *******************************************************************************
* *
Expand Down Expand Up @@ -36,6 +36,9 @@
import org.junit.ClassRule; import org.junit.ClassRule;
import org.junit.Test; import org.junit.Test;
import org.pentaho.di.core.exception.KettleException; import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.row.RowMeta;
import org.pentaho.di.core.row.RowMetaInterface;
import org.pentaho.di.core.row.value.ValueMetaString;
import org.pentaho.di.junit.rules.RestorePDIEngineEnvironment; import org.pentaho.di.junit.rules.RestorePDIEngineEnvironment;
import org.pentaho.di.trans.steps.loadsave.LoadSaveTester; import org.pentaho.di.trans.steps.loadsave.LoadSaveTester;
import org.pentaho.di.trans.steps.loadsave.validator.ArrayLoadSaveValidator; import org.pentaho.di.trans.steps.loadsave.validator.ArrayLoadSaveValidator;
Expand Down Expand Up @@ -71,8 +74,8 @@ public void loadSaveTest() throws KettleException {
fieldLoadSaveValidatorTypeMap.put( SelectField[].class.getCanonicalName(), new ArrayLoadSaveValidator<SelectField>( fieldLoadSaveValidatorTypeMap.put( SelectField[].class.getCanonicalName(), new ArrayLoadSaveValidator<SelectField>(
new SelectFieldLoadSaveValidator( selectField ), 2 ) ); new SelectFieldLoadSaveValidator( selectField ), 2 ) );


LoadSaveTester tester = LoadSaveTester<SelectValuesMeta> tester =
new LoadSaveTester( SelectValuesMeta.class, attributes, new HashMap<String, String>(), new LoadSaveTester<>( SelectValuesMeta.class, attributes, new HashMap<String, String>(),
new HashMap<String, String>(), new HashMap<String, FieldLoadSaveValidator<?>>(), new HashMap<String, String>(), new HashMap<String, FieldLoadSaveValidator<?>>(),
fieldLoadSaveValidatorTypeMap ); fieldLoadSaveValidatorTypeMap );


Expand Down Expand Up @@ -210,6 +213,21 @@ public void getSelectPrecision() {
assertArrayEquals( new int[0], selectValuesMeta.getSelectPrecision() ); assertArrayEquals( new int[0], selectValuesMeta.getSelectPrecision() );
} }


@Test
public void testMetaDataFieldsRenameConflict() throws Exception {
RowMetaInterface rowMeta = new RowMeta();
rowMeta.addValueMeta( new ValueMetaString( "A" ) );
rowMeta.addValueMeta( new ValueMetaString( "B" ) );

SelectMetadataChange change = new SelectMetadataChange( selectValuesMeta );
change.setName( "A" );
change.setRename( "B" );
selectValuesMeta.setMeta( new SelectMetadataChange[] { change } );

selectValuesMeta.getMetadataFields( rowMeta, "select values", null );
assertEquals( "rename conflict", "B_1", rowMeta.getValueMeta( 0 ).getName() );
}

public static class SelectFieldLoadSaveValidator implements FieldLoadSaveValidator<SelectField> { public static class SelectFieldLoadSaveValidator implements FieldLoadSaveValidator<SelectField> {


private final SelectField defaultValue; private final SelectField defaultValue;
Expand Down
Expand Up @@ -30,7 +30,6 @@
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertTrue;


import org.junit.runner.RunWith;
import org.pentaho.di.core.Const; import org.pentaho.di.core.Const;
import org.pentaho.di.core.KettleEnvironment; import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.RowSet; import org.pentaho.di.core.RowSet;
Expand Down

0 comments on commit 79dc48a

Please sign in to comment.