flink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fhue...@apache.org
Subject [3/6] incubator-flink git commit: [FLINK-1040] Make types() call in projections optional
Date Wed, 10 Dec 2014 15:50:54 GMT
http://git-wip-us.apache.org/repos/asf/incubator-flink/blob/a9ecaba7/flink-java/src/main/java/org/apache/flink/api/java/operators/JoinOperator.java
----------------------------------------------------------------------
diff --git a/flink-java/src/main/java/org/apache/flink/api/java/operators/JoinOperator.java b/flink-java/src/main/java/org/apache/flink/api/java/operators/JoinOperator.java
index 21534f1..39d0f18 100644
--- a/flink-java/src/main/java/org/apache/flink/api/java/operators/JoinOperator.java
+++ b/flink-java/src/main/java/org/apache/flink/api/java/operators/JoinOperator.java
@@ -53,9 +53,9 @@ import org.apache.flink.util.Collector;
 
 //CHECKSTYLE.OFF: AvoidStarImport - Needed for TupleGenerator
 import org.apache.flink.api.java.tuple.*;
+//CHECKSTYLE.ON: AvoidStarImport
 
 import com.google.common.base.Preconditions;
-//CHECKSTYLE.ON: AvoidStarImport
 
 /**
  * A {@link DataSet} that is the result of a Join transformation. 
@@ -545,30 +545,30 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 				out.collect (this.wrappedFunction.join(left, right));
 			}
 		}
-		
+
 		/**
 		 * Initiates a ProjectJoin transformation and projects the first join input<br/>
 		 * If the first join input is a {@link Tuple} {@link DataSet}, fields can be selected by their index.
 		 * If the first join input is not a Tuple DataSet, no parameters should be passed.<br/>
 		 * 
 		 * Fields of the first and second input can be added by chaining the method calls of
-		 * {@link org.apache.flink.api.java.operators.JoinOperator.JoinProjection#projectFirst(int...)} and
-		 * {@link org.apache.flink.api.java.operators.JoinOperator.JoinProjection#projectSecond(int...)}.
+		 * {@link org.apache.flink.api.java.operators.JoinOperator.ProjectJoin#projectFirst(int...)} and
+		 * {@link org.apache.flink.api.java.operators.JoinOperator.ProjectJoin#projectSecond(int...)}.
 		 * 
 		 * @param firstFieldIndexes If the first input is a Tuple DataSet, the indexes of the selected fields.
 		 * 					   For a non-Tuple DataSet, do not provide parameters.
 		 * 					   The order of fields in the output tuple is defined by to the order of field indexes.
-		 * @return A JoinProjection that needs to be converted into a
-		 *           {@link org.apache.flink.api.java.operators.JoinOperator.ProjectJoin} to complete the 
-		 *           Join transformation by calling the corresponding {@code types()} function.
+		 * @return A ProjectJoin to complete the Join transformation.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 * @see org.apache.flink.api.java.operators.JoinOperator.JoinProjection
 		 * @see org.apache.flink.api.java.operators.JoinOperator.ProjectJoin
 		 */
-		public JoinProjection<I1, I2> projectFirst(int... firstFieldIndexes) {
-			return new JoinProjection<I1, I2>(getInput1(), getInput2(), getKeys1(), getKeys2(), getJoinHint(), firstFieldIndexes, null);
+		public <OUT extends Tuple> ProjectJoin<I1, I2, OUT> projectFirst(int... firstFieldIndexes) {
+			JoinProjection<I1, I2> joinProjection = new JoinProjection<I1, I2>(getInput1(), getInput2(), getKeys1(), getKeys2(), getJoinHint(), firstFieldIndexes, null);
+			
+			return joinProjection.projectTupleX();
 		}
 		
 		/**
@@ -577,23 +577,23 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 		 * If the second join input is not a Tuple DataSet, no parameters should be passed.<br/>
 		 * 
 		 * Fields of the first and second input can be added by chaining the method calls of
-		 * {@link org.apache.flink.api.java.operators.JoinOperator.JoinProjection#projectFirst(int...)} and
-		 * {@link org.apache.flink.api.java.operators.JoinOperator.JoinProjection#projectSecond(int...)}.
+		 * {@link org.apache.flink.api.java.operators.JoinOperator.ProjectJoin#projectionFirst(int...)} and
+		 * {@link org.apache.flink.api.java.operators.JoinOperator.ProjectJoin#projectionSecond(int...)}.
 		 * 
 		 * @param secondFieldIndexes If the second input is a Tuple DataSet, the indexes of the selected fields. 
 		 * 					   For a non-Tuple DataSet, do not provide parameters.
 		 * 					   The order of fields in the output tuple is defined by to the order of field indexes.
-		 * @return A JoinProjection that needs to be converted into a
-		 *           {@link org.apache.flink.api.java.operators.JoinOperator.ProjectJoin} to complete the 
-		 *           Join transformation by calling the corresponding {@code types()} function.
+		 * @return A ProjectJoin to complete the Join transformation.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 * @see org.apache.flink.api.java.operators.JoinOperator.JoinProjection
 		 * @see org.apache.flink.api.java.operators.JoinOperator.ProjectJoin
 		 */
-		public JoinProjection<I1, I2> projectSecond(int... secondFieldIndexes) {
-			return new JoinProjection<I1, I2>(getInput1(), getInput2(), getKeys1(), getKeys2(), getJoinHint(), null, secondFieldIndexes);
+		public <OUT extends Tuple> ProjectJoin<I1, I2, OUT> projectSecond(int... secondFieldIndexes) {
+			JoinProjection<I1, I2> joinProjection = new JoinProjection<I1, I2>(getInput1(), getInput2(), getKeys1(), getKeys2(), getJoinHint(), null, secondFieldIndexes);
+			
+			return joinProjection.projectTupleX();
 		}
 		
 //		public JoinOperator<I1, I2, I1> leftSemiJoin() {
@@ -625,14 +625,47 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 	 * @see Tuple
 	 * @see DataSet
 	 */
-	public static final class ProjectJoin<I1, I2, OUT extends Tuple> extends EquiJoin<I1, I2, OUT> {
+	public static class ProjectJoin<I1, I2, OUT extends Tuple> extends EquiJoin<I1, I2, OUT> {
+		
+		private JoinProjection<I1, I2> joinProj;
 		
 		protected ProjectJoin(DataSet<I1> input1, DataSet<I2> input2, Keys<I1> keys1, Keys<I2> keys2, JoinHint hint, int[] fields, boolean[] isFromFirst, TupleTypeInfo<OUT> returnType) {
 			super(input1, input2, keys1, keys2, 
 					new ProjectFlatJoinFunction<I1, I2, OUT>(fields, isFromFirst, returnType.createSerializer().createInstance()),
 					returnType, hint, Utils.getCallLocationName(4)); // We need to use the 4th element in the stack because the call comes through .types().
+
+			
+			joinProj = null;
+		}
+		
+		protected ProjectJoin(DataSet<I1> input1, DataSet<I2> input2, Keys<I1> keys1, Keys<I2> keys2, JoinHint hint, int[] fields, boolean[] isFromFirst, TupleTypeInfo<OUT> returnType, JoinProjection<I1, I2> joinProj) {
+			super(input1, input2, keys1, keys2, 
+					new ProjectFlatJoinFunction<I1, I2, OUT>(fields, isFromFirst, returnType.createSerializer().createInstance()),
+					returnType, hint, Utils.getCallLocationName(4));
+			
+			this.joinProj = joinProj;
+		}
+		
+		@SuppressWarnings("hiding")
+		public <OUT extends Tuple> ProjectJoin<I1, I2, OUT> projectFirst(int... firstFieldIndexes) {	
+			joinProj = joinProj.projectFirst(firstFieldIndexes);
+			
+			return joinProj.projectTupleX();
+		}
+		
+		@SuppressWarnings("hiding")
+		public <OUT extends Tuple> ProjectJoin<I1, I2, OUT> projectSecond(int... secondFieldIndexes) {
+			joinProj = joinProj.projectSecond(secondFieldIndexes);
+			
+			return joinProj.projectTupleX();
 		}
 
+		@SuppressWarnings({ "unchecked", "hiding" })
+		@Deprecated
+		public <OUT extends Tuple> ProjectJoin<I1, I2, OUT> types(Class<?>... types) {
+			return (ProjectJoin<I1, I2, OUT>) this;
+		}
+		
 		@Override
 		public JoinOperator<I1, I2, OUT> withConstantSetFirst(String... constantSetFirst) {
 			throw new InvalidProgramException("The semantic properties (constant fields and forwarded fields) are automatically calculated.");
@@ -954,6 +987,7 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 			}
 			out.collect(outTuple);
 		}
+		
 	}
 	
 	public static final class JoinProjection<I1, I2> {
@@ -1038,9 +1072,8 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 				// check field indexes and adapt to position in tuple
 				int maxFieldIndex = firstInput ? numFieldsDs1 : numFieldsDs2;
 				for(int i=0; i<this.fieldIndexes.length; i++) {
-					if(this.fieldIndexes[i] > maxFieldIndex - 1) {
-						throw new IndexOutOfBoundsException("Provided field index is out of bounds of input tuple.");
-					}
+					Preconditions.checkElementIndex(this.fieldIndexes[i], maxFieldIndex);
+
 					if(firstInput) {
 						this.isFieldInFirst[i] = true;
 					} else {
@@ -1101,9 +1134,8 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 				int maxFieldIndex = numFieldsDs1;
 				for(int i = 0; i < firstFieldIndexes.length; i++) {
 					// check if indexes in range
-					if(firstFieldIndexes[i] > maxFieldIndex - 1) {
-						throw new IndexOutOfBoundsException("Provided field index is out of bounds of input tuple.");
-					}
+					Preconditions.checkElementIndex(firstFieldIndexes[i], maxFieldIndex);
+
 					this.isFieldInFirst[offset + i] = true;
 					this.fieldIndexes[offset + i] = firstFieldIndexes[i];
 				}
@@ -1167,9 +1199,8 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 				int maxFieldIndex = numFieldsDs2;
 				for(int i = 0; i < secondFieldIndexes.length; i++) {
 					// check if indexes in range
-					if(secondFieldIndexes[i] > maxFieldIndex - 1) {
-						throw new IndexOutOfBoundsException("Provided field index is out of bounds of input tuple.");
-					}
+					Preconditions.checkElementIndex(secondFieldIndexes[i], maxFieldIndex);
+					
 					this.isFieldInFirst[offset + i] = false;
 					this.fieldIndexes[offset + i] = secondFieldIndexes[i];
 				}
@@ -1193,860 +1224,452 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 	// GENERATED FROM org.apache.flink.api.java.tuple.TupleGenerator.
 
 		/**
+		 * Chooses a projectTupleX according to the length of {@link JoinProjection#fieldIndexes} 
+		 * 
+		 * @return The projected DataSet.
+		 * 
+		 * @see Projection
+		 */
+		@SuppressWarnings("unchecked")
+		public <OUT extends Tuple> ProjectJoin<I1, I2, OUT> projectTupleX() {
+			ProjectJoin<I1, I2, OUT> projectJoin = null;
+
+			switch (fieldIndexes.length) {
+			case 1: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple1(); break;
+			case 2: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple2(); break;
+			case 3: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple3(); break;
+			case 4: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple4(); break;
+			case 5: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple5(); break;
+			case 6: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple6(); break;
+			case 7: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple7(); break;
+			case 8: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple8(); break;
+			case 9: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple9(); break;
+			case 10: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple10(); break;
+			case 11: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple11(); break;
+			case 12: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple12(); break;
+			case 13: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple13(); break;
+			case 14: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple14(); break;
+			case 15: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple15(); break;
+			case 16: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple16(); break;
+			case 17: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple17(); break;
+			case 18: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple18(); break;
+			case 19: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple19(); break;
+			case 20: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple20(); break;
+			case 21: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple21(); break;
+			case 22: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple22(); break;
+			case 23: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple23(); break;
+			case 24: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple24(); break;
+			case 25: projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple25(); break;
+			default: throw new IllegalStateException("Excessive arity in tuple.");
+			}
+
+			return projectJoin;
+		}
+
+		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0> ProjectJoin<I1, I2, Tuple1<T0>> types(Class<T0> type0) {
-			Class<?>[] types = {type0};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0> ProjectJoin<I1, I2, Tuple1<T0>> projectTuple1() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple1<T0>> tType = new TupleTypeInfo<Tuple1<T0>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple1<T0>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple1<T0>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1> ProjectJoin<I1, I2, Tuple2<T0, T1>> types(Class<T0> type0, Class<T1> type1) {
-			Class<?>[] types = {type0, type1};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1> ProjectJoin<I1, I2, Tuple2<T0, T1>> projectTuple2() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple2<T0, T1>> tType = new TupleTypeInfo<Tuple2<T0, T1>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple2<T0, T1>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple2<T0, T1>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2> ProjectJoin<I1, I2, Tuple3<T0, T1, T2>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2) {
-			Class<?>[] types = {type0, type1, type2};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2> ProjectJoin<I1, I2, Tuple3<T0, T1, T2>> projectTuple3() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple3<T0, T1, T2>> tType = new TupleTypeInfo<Tuple3<T0, T1, T2>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple3<T0, T1, T2>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple3<T0, T1, T2>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3> ProjectJoin<I1, I2, Tuple4<T0, T1, T2, T3>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3) {
-			Class<?>[] types = {type0, type1, type2, type3};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3> ProjectJoin<I1, I2, Tuple4<T0, T1, T2, T3>> projectTuple4() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple4<T0, T1, T2, T3>> tType = new TupleTypeInfo<Tuple4<T0, T1, T2, T3>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple4<T0, T1, T2, T3>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple4<T0, T1, T2, T3>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4> ProjectJoin<I1, I2, Tuple5<T0, T1, T2, T3, T4>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4) {
-			Class<?>[] types = {type0, type1, type2, type3, type4};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4> ProjectJoin<I1, I2, Tuple5<T0, T1, T2, T3, T4>> projectTuple5() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple5<T0, T1, T2, T3, T4>> tType = new TupleTypeInfo<Tuple5<T0, T1, T2, T3, T4>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple5<T0, T1, T2, T3, T4>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple5<T0, T1, T2, T3, T4>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5> ProjectJoin<I1, I2, Tuple6<T0, T1, T2, T3, T4, T5>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5> ProjectJoin<I1, I2, Tuple6<T0, T1, T2, T3, T4, T5>> projectTuple6() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple6<T0, T1, T2, T3, T4, T5>> tType = new TupleTypeInfo<Tuple6<T0, T1, T2, T3, T4, T5>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple6<T0, T1, T2, T3, T4, T5>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple6<T0, T1, T2, T3, T4, T5>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6> ProjectJoin<I1, I2, Tuple7<T0, T1, T2, T3, T4, T5, T6>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6> ProjectJoin<I1, I2, Tuple7<T0, T1, T2, T3, T4, T5, T6>> projectTuple7() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple7<T0, T1, T2, T3, T4, T5, T6>> tType = new TupleTypeInfo<Tuple7<T0, T1, T2, T3, T4, T5, T6>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple7<T0, T1, T2, T3, T4, T5, T6>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple7<T0, T1, T2, T3, T4, T5, T6>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7> ProjectJoin<I1, I2, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7> ProjectJoin<I1, I2, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>> projectTuple8() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>> tType = new TupleTypeInfo<Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8> ProjectJoin<I1, I2, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8> ProjectJoin<I1, I2, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>> projectTuple9() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>> tType = new TupleTypeInfo<Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> ProjectJoin<I1, I2, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> ProjectJoin<I1, I2, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>> projectTuple10() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>> tType = new TupleTypeInfo<Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ProjectJoin<I1, I2, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ProjectJoin<I1, I2, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>> projectTuple11() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>> tType = new TupleTypeInfo<Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> ProjectJoin<I1, I2, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> ProjectJoin<I1, I2, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> projectTuple12() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> tType = new TupleTypeInfo<Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> ProjectJoin<I1, I2, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> ProjectJoin<I1, I2, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> projectTuple13() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> tType = new TupleTypeInfo<Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> ProjectJoin<I1, I2, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> ProjectJoin<I1, I2, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> projectTuple14() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> tType = new TupleTypeInfo<Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> ProjectJoin<I1, I2, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> ProjectJoin<I1, I2, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> projectTuple15() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> tType = new TupleTypeInfo<Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> ProjectJoin<I1, I2, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> ProjectJoin<I1, I2, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> projectTuple16() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> tType = new TupleTypeInfo<Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> ProjectJoin<I1, I2, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> ProjectJoin<I1, I2, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> projectTuple17() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> tType = new TupleTypeInfo<Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> ProjectJoin<I1, I2, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> ProjectJoin<I1, I2, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>> projectTuple18() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>> tType = new TupleTypeInfo<Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> ProjectJoin<I1, I2, Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> ProjectJoin<I1, I2, Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>> projectTuple19() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>> tType = new TupleTypeInfo<Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
-		 * @param type19 The class of field '19' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> ProjectJoin<I1, I2, Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18, Class<T19> type19) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18, type19};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> ProjectJoin<I1, I2, Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>> projectTuple20() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>> tType = new TupleTypeInfo<Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
-		 * @param type19 The class of field '19' of the result tuples.
-		 * @param type20 The class of field '20' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> ProjectJoin<I1, I2, Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18, Class<T19> type19, Class<T20> type20) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18, type19, type20};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> ProjectJoin<I1, I2, Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>> projectTuple21() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>> tType = new TupleTypeInfo<Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
-		 * @param type19 The class of field '19' of the result tuples.
-		 * @param type20 The class of field '20' of the result tuples.
-		 * @param type21 The class of field '21' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> ProjectJoin<I1, I2, Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18, Class<T19> type19, Class<T20> type20, Class<T21> type21) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18, type19, type20, type21};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> ProjectJoin<I1, I2, Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>> projectTuple22() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>> tType = new TupleTypeInfo<Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
-		 * @param type19 The class of field '19' of the result tuples.
-		 * @param type20 The class of field '20' of the result tuples.
-		 * @param type21 The class of field '21' of the result tuples.
-		 * @param type22 The class of field '22' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> ProjectJoin<I1, I2, Tuple23<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18, Class<T19> type19, Class<T20> type20, Class<T21> type21, Class<T22> type22) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18, type19, type20, type21, type22};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> ProjectJoin<I1, I2, Tuple23<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>> projectTuple23() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple23<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>> tType = new TupleTypeInfo<Tuple23<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple23<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple23<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
-		 * @param type19 The class of field '19' of the result tuples.
-		 * @param type20 The class of field '20' of the result tuples.
-		 * @param type21 The class of field '21' of the result tuples.
-		 * @param type22 The class of field '22' of the result tuples.
-		 * @param type23 The class of field '23' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> ProjectJoin<I1, I2, Tuple24<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18, Class<T19> type19, Class<T20> type20, Class<T21> type21, Class<T22> type22, Class<T23> type23) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18, type19, type20, type21, type22, type23};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> ProjectJoin<I1, I2, Tuple24<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>> projectTuple24() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple24<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>> tType = new TupleTypeInfo<Tuple24<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple24<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple24<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		/**
 		 * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. 
 		 * Requires the classes of the fields of the resulting tuples. 
 		 * 
-		 * @param type0 The class of field '0' of the result tuples.
-		 * @param type1 The class of field '1' of the result tuples.
-		 * @param type2 The class of field '2' of the result tuples.
-		 * @param type3 The class of field '3' of the result tuples.
-		 * @param type4 The class of field '4' of the result tuples.
-		 * @param type5 The class of field '5' of the result tuples.
-		 * @param type6 The class of field '6' of the result tuples.
-		 * @param type7 The class of field '7' of the result tuples.
-		 * @param type8 The class of field '8' of the result tuples.
-		 * @param type9 The class of field '9' of the result tuples.
-		 * @param type10 The class of field '10' of the result tuples.
-		 * @param type11 The class of field '11' of the result tuples.
-		 * @param type12 The class of field '12' of the result tuples.
-		 * @param type13 The class of field '13' of the result tuples.
-		 * @param type14 The class of field '14' of the result tuples.
-		 * @param type15 The class of field '15' of the result tuples.
-		 * @param type16 The class of field '16' of the result tuples.
-		 * @param type17 The class of field '17' of the result tuples.
-		 * @param type18 The class of field '18' of the result tuples.
-		 * @param type19 The class of field '19' of the result tuples.
-		 * @param type20 The class of field '20' of the result tuples.
-		 * @param type21 The class of field '21' of the result tuples.
-		 * @param type22 The class of field '22' of the result tuples.
-		 * @param type23 The class of field '23' of the result tuples.
-		 * @param type24 The class of field '24' of the result tuples.
 		 * @return The projected data set.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> ProjectJoin<I1, I2, Tuple25<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>> types(Class<T0> type0, Class<T1> type1, Class<T2> type2, Class<T3> type3, Class<T4> type4, Class<T5> type5, Class<T6> type6, Class<T7> type7, Class<T8> type8, Class<T9> type9, Class<T10> type10, Class<T11> type11, Class<T12> type12, Class<T13> type13, Class<T14> type14, Class<T15> type15, Class<T16> type16, Class<T17> type17, Class<T18> type18, Class<T19> type19, Class<T20> type20, Class<T21> type21, Class<T22> type22, Class<T23> type23, Class<T24> type24) {
-			Class<?>[] types = {type0, type1, type2, type3, type4, type5, type6, type7, type8, type9, type10, type11, type12, type13, type14, type15, type16, type17, type18, type19, type20, type21, type22, type23, type24};
-			if(types.length != this.fieldIndexes.length) {
-				throw new IllegalArgumentException("Numbers of projected fields and types do not match.");
-			}
-			
-			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> ProjectJoin<I1, I2, Tuple25<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>> projectTuple25() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);
 			TupleTypeInfo<Tuple25<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>> tType = new TupleTypeInfo<Tuple25<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>>(fTypes);
 
-			return new ProjectJoin<I1, I2, Tuple25<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);
+			return new ProjectJoin<I1, I2, Tuple25<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24>>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);
 		}
 
 		// END_OF_TUPLE_DEPENDENT_CODE
 		// -----------------------------------------------------------------------------------------
 		
-			
-		private TypeInformation<?>[] extractFieldTypes(int[] fields, Class<?>[] givenTypes) {
+		private TypeInformation<?>[] extractFieldTypes(int[] fields) {
 			
 			TypeInformation<?>[] fieldTypes = new TypeInformation[fields.length];
 
@@ -2066,10 +1689,6 @@ public abstract class JoinOperator<I1, I2, OUT> extends TwoInputUdfOperator<I1,
 						typeInfo = ds2.getType();
 					}
 				}
-				
-				if(typeInfo.getTypeClass() != givenTypes[i]) {
-					throw new IllegalArgumentException("Given types do not match types of input data set.");
-				}
 
 				fieldTypes[i] = typeInfo;
 			}


Mime
View raw message