flink-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From fhue...@apache.org
Subject [2/6] incubator-flink git commit: [FLINK-1040] Make types() call in projections optional
Date Wed, 10 Dec 2014 15:50:53 GMT
http://git-wip-us.apache.org/repos/asf/incubator-flink/blob/a9ecaba7/flink-java/src/main/java/org/apache/flink/api/java/operators/ProjectOperator.java
----------------------------------------------------------------------
diff --git a/flink-java/src/main/java/org/apache/flink/api/java/operators/ProjectOperator.java b/flink-java/src/main/java/org/apache/flink/api/java/operators/ProjectOperator.java
index 79f7902..f761b81 100644
--- a/flink-java/src/main/java/org/apache/flink/api/java/operators/ProjectOperator.java
+++ b/flink-java/src/main/java/org/apache/flink/api/java/operators/ProjectOperator.java
@@ -32,6 +32,8 @@ import org.apache.flink.api.java.typeutils.TupleTypeInfo;
 import org.apache.flink.api.java.tuple.*;
 //CHECKSTYLE.ON: AvoidStarImport
 
+import com.google.common.base.Preconditions;
+
 /**
  * This operator represents the application of a projection operation on a data set, and the
  * result data set produced by the function.
@@ -44,10 +46,20 @@ public class ProjectOperator<IN, OUT extends Tuple>
 	
 	protected final int[] fields;
 	
+	private Projection<IN> proj;
+	
 	public ProjectOperator(DataSet<IN> input, int[] fields, TupleTypeInfo<OUT> returnType) {
 		super(input, returnType);
 	
 		this.fields = fields;
+		proj = null;
+	}
+	
+	public ProjectOperator(DataSet<IN> input, int[] fields, TupleTypeInfo<OUT> returnType, Projection<IN> proj) {
+		super(input, returnType);
+	
+		this.fields = fields;
+		this.proj = proj;
 	}
 
 	@Override
@@ -63,11 +75,28 @@ public class ProjectOperator<IN, OUT extends Tuple>
 
 		return ppo;
 	}
-
+	
+	@SuppressWarnings("hiding")
+	public <OUT extends Tuple> ProjectOperator<?, OUT> project(int... fieldIndexes) {
+		proj.acceptAdditionalIndexes(fieldIndexes);
+		
+		return proj.projectTupleX();
+	}
+	/**
+	 * A fake types() call to make codes compatible
+	 * @param types
+	 * @return
+	 */
+	@SuppressWarnings({ "unchecked", "hiding" })
+	@Deprecated
+	public <OUT extends Tuple> ProjectOperator<?, OUT> types(Class<?>... types) {
+		return (ProjectOperator<?, OUT>) this;
+	}
+	
 	public static class Projection<T> {
 		
-		private final DataSet<T> ds;
-		private final int[] fieldIndexes;
+		private final DataSet<T> ds;		
+		private int[] fieldIndexes;
 		
 		public Projection(DataSet<T> ds, int[] fieldIndexes) {
 			
@@ -84,15 +113,36 @@ public class ProjectOperator<IN, OUT extends Tuple>
 			
 			int maxFieldIndex = ((TupleTypeInfo<?>)ds.getType()).getArity();
 			for(int i=0; i<fieldIndexes.length; i++) {
-				if(fieldIndexes[i] > maxFieldIndex - 1) {
-					throw new IndexOutOfBoundsException("Provided field index is out of bounds of input tuple.");
-				}
+				Preconditions.checkElementIndex(fieldIndexes[i], maxFieldIndex);
 			}
 			
 			this.ds = ds;
 			this.fieldIndexes = fieldIndexes;
 		}
 		
+		private void acceptAdditionalIndexes(int... additionalIndexes) {
+			
+			if(additionalIndexes.length == 0) {
+				throw new IllegalArgumentException("project() needs to select at least one (1) field.");
+			} else if(additionalIndexes.length > Tuple.MAX_ARITY - 1) {
+				throw new IllegalArgumentException(
+						"project() may select only up to (" + (Tuple.MAX_ARITY - 1) + ") fields.");
+			}
+			
+			int offset = this.fieldIndexes.length;
+			
+			this.fieldIndexes = Arrays.copyOf(this.fieldIndexes, this.fieldIndexes.length + additionalIndexes.length);
+			
+			int maxFieldIndex = ((TupleTypeInfo<?>)ds.getType()).getArity();
+			for(int i=0; i<additionalIndexes.length; i++) {
+				Preconditions.checkElementIndex(additionalIndexes[i], maxFieldIndex);
+
+				this.fieldIndexes[offset + i] = additionalIndexes[i];
+			}
+		}
+		
+		
+		
 		// --------------------------------------------------------------------------------------------	
 		// The following lines are generated.
 		// --------------------------------------------------------------------------------------------	
@@ -100,870 +150,434 @@ public class ProjectOperator<IN, OUT extends Tuple>
 	// GENERATED FROM org.apache.flink.api.java.tuple.TupleGenerator.
 
 		/**
+		 * Chooses a projectTupleX according to the length of {@link Projection#fieldIndexes} 
+		 * 
+		 * @return The projected DataSet.
+		 * 
+		 * @see Projection
+		 */
+		@SuppressWarnings("unchecked")
+		public <OUT extends Tuple> ProjectOperator<T, OUT> projectTupleX() {
+			ProjectOperator<T, OUT> projOperator = null;
+
+			switch (fieldIndexes.length) {
+			case 1: projOperator = (ProjectOperator<T, OUT>) projectTuple1(); break;
+			case 2: projOperator = (ProjectOperator<T, OUT>) projectTuple2(); break;
+			case 3: projOperator = (ProjectOperator<T, OUT>) projectTuple3(); break;
+			case 4: projOperator = (ProjectOperator<T, OUT>) projectTuple4(); break;
+			case 5: projOperator = (ProjectOperator<T, OUT>) projectTuple5(); break;
+			case 6: projOperator = (ProjectOperator<T, OUT>) projectTuple6(); break;
+			case 7: projOperator = (ProjectOperator<T, OUT>) projectTuple7(); break;
+			case 8: projOperator = (ProjectOperator<T, OUT>) projectTuple8(); break;
+			case 9: projOperator = (ProjectOperator<T, OUT>) projectTuple9(); break;
+			case 10: projOperator = (ProjectOperator<T, OUT>) projectTuple10(); break;
+			case 11: projOperator = (ProjectOperator<T, OUT>) projectTuple11(); break;
+			case 12: projOperator = (ProjectOperator<T, OUT>) projectTuple12(); break;
+			case 13: projOperator = (ProjectOperator<T, OUT>) projectTuple13(); break;
+			case 14: projOperator = (ProjectOperator<T, OUT>) projectTuple14(); break;
+			case 15: projOperator = (ProjectOperator<T, OUT>) projectTuple15(); break;
+			case 16: projOperator = (ProjectOperator<T, OUT>) projectTuple16(); break;
+			case 17: projOperator = (ProjectOperator<T, OUT>) projectTuple17(); break;
+			case 18: projOperator = (ProjectOperator<T, OUT>) projectTuple18(); break;
+			case 19: projOperator = (ProjectOperator<T, OUT>) projectTuple19(); break;
+			case 20: projOperator = (ProjectOperator<T, OUT>) projectTuple20(); break;
+			case 21: projOperator = (ProjectOperator<T, OUT>) projectTuple21(); break;
+			case 22: projOperator = (ProjectOperator<T, OUT>) projectTuple22(); break;
+			case 23: projOperator = (ProjectOperator<T, OUT>) projectTuple23(); break;
+			case 24: projOperator = (ProjectOperator<T, OUT>) projectTuple24(); break;
+			case 25: projOperator = (ProjectOperator<T, OUT>) projectTuple25(); break;
+			default: throw new IllegalStateException("Excessive arity in tuple.");
+			}
+
+			return projOperator;
+		}
+
+		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0> ProjectOperator<T, 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, ds.getType());
+		public <T0> ProjectOperator<T, Tuple1<T0>> projectTuple1() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple1<T0>> tType = new TupleTypeInfo<Tuple1<T0>>(fTypes);
 
-			return new ProjectOperator<T, Tuple1<T0>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple1<T0>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1> ProjectOperator<T, Tuple2<T0, T1>> projectTuple2() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple2<T0, T1>> tType = new TupleTypeInfo<Tuple2<T0, T1>>(fTypes);
 
-			return new ProjectOperator<T, Tuple2<T0, T1>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple2<T0, T1>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2> ProjectOperator<T, Tuple3<T0, T1, T2>> projectTuple3() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple3<T0, T1, T2>> tType = new TupleTypeInfo<Tuple3<T0, T1, T2>>(fTypes);
 
-			return new ProjectOperator<T, Tuple3<T0, T1, T2>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple3<T0, T1, T2>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3> ProjectOperator<T, Tuple4<T0, T1, T2, T3>> projectTuple4() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple4<T0, T1, T2, T3>> tType = new TupleTypeInfo<Tuple4<T0, T1, T2, T3>>(fTypes);
 
-			return new ProjectOperator<T, Tuple4<T0, T1, T2, T3>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple4<T0, T1, T2, T3>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4> ProjectOperator<T, Tuple5<T0, T1, T2, T3, T4>> projectTuple5() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple5<T0, T1, T2, T3, T4>> tType = new TupleTypeInfo<Tuple5<T0, T1, T2, T3, T4>>(fTypes);
 
-			return new ProjectOperator<T, Tuple5<T0, T1, T2, T3, T4>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple5<T0, T1, T2, T3, T4>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5> ProjectOperator<T, Tuple6<T0, T1, T2, T3, T4, T5>> projectTuple6() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple6<T0, T1, T2, T3, T4, T5>> tType = new TupleTypeInfo<Tuple6<T0, T1, T2, T3, T4, T5>>(fTypes);
 
-			return new ProjectOperator<T, Tuple6<T0, T1, T2, T3, T4, T5>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple6<T0, T1, T2, T3, T4, T5>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6> ProjectOperator<T, Tuple7<T0, T1, T2, T3, T4, T5, T6>> projectTuple7() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			TupleTypeInfo<Tuple7<T0, T1, T2, T3, T4, T5, T6>> tType = new TupleTypeInfo<Tuple7<T0, T1, T2, T3, T4, T5, T6>>(fTypes);
 
-			return new ProjectOperator<T, Tuple7<T0, T1, T2, T3, T4, T5, T6>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple7<T0, T1, T2, T3, T4, T5, T6>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7> ProjectOperator<T, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>> projectTuple8() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple8<T0, T1, T2, T3, T4, T5, T6, T7>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8> ProjectOperator<T, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>> projectTuple9() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple9<T0, T1, T2, T3, T4, T5, T6, T7, T8>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> ProjectOperator<T, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>> projectTuple10() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple10<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> ProjectOperator<T, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>> projectTuple11() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple11<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> ProjectOperator<T, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>> projectTuple12() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple12<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> ProjectOperator<T, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>> projectTuple13() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple13<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> ProjectOperator<T, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>> projectTuple14() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple14<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> ProjectOperator<T, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>> projectTuple15() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple15<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> ProjectOperator<T, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>> projectTuple16() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple16<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> ProjectOperator<T, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>> projectTuple17() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple17<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> ProjectOperator<T, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>> projectTuple18() {
+			TypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());
 			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 ProjectOperator<T, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple18<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @see Tuple
 		 * @see DataSet
 		 */
-		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple19<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @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> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple20<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @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> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple21<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @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> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>>(this.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, Tuple22<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21>>(this.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @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> ProjectOperator<T, 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, ds.getType());
+		public <T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, 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.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, 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.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @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> ProjectOperator<T, 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, ds.getType());
+		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> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, 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.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, 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.ds, this.fieldIndexes, tType, this);
 		}
 
 		/**
 		 * Projects a {@link Tuple} {@link DataSet} to 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 DataSet.
 		 * 
 		 * @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> ProjectOperator<T, 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, ds.getType());
+		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> ProjectOperator<T, 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, ds.getType());
 			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 ProjectOperator<T, 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.ds, this.fieldIndexes, tType);
+			return new ProjectOperator<T, 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.ds, this.fieldIndexes, tType, this);
 		}
 
 		// END_OF_TUPLE_DEPENDENT_CODE
 		// -----------------------------------------------------------------------------------------
 		
-			
-		private TypeInformation<?>[] extractFieldTypes(int[] fields, Class<?>[] givenTypes, TypeInformation<?> inType) {
+		
+		
+		private TypeInformation<?>[] extractFieldTypes(int[] fields, TypeInformation<?> inType) {
 			
 			TupleTypeInfo<?> inTupleType = (TupleTypeInfo<?>) inType;
 			TypeInformation<?>[] fieldTypes = new TypeInformation[fields.length];
 					
-			for(int i=0; i<fields.length; i++) {
-				
-				if(inTupleType.getTypeAt(fields[i]).getTypeClass() != givenTypes[i]) {
-					throw new IllegalArgumentException("Given types do not match types of input data set.");
-				}
-					
+			for(int i=0; i<fields.length; i++) {					
 				fieldTypes[i] = inTupleType.getTypeAt(fields[i]);
 			}
 			

http://git-wip-us.apache.org/repos/asf/incubator-flink/blob/a9ecaba7/flink-java/src/main/java/org/apache/flink/api/java/tuple/TupleGenerator.java
----------------------------------------------------------------------
diff --git a/flink-java/src/main/java/org/apache/flink/api/java/tuple/TupleGenerator.java b/flink-java/src/main/java/org/apache/flink/api/java/tuple/TupleGenerator.java
index fab1f75..c0c1587 100644
--- a/flink-java/src/main/java/org/apache/flink/api/java/tuple/TupleGenerator.java
+++ b/flink-java/src/main/java/org/apache/flink/api/java/tuple/TupleGenerator.java
@@ -160,7 +160,34 @@ class TupleGenerator {
 	private static void modifyCrossProjectOperator(File root) throws IOException {
 		// generate code
 		StringBuilder sb = new StringBuilder();
-
+		
+		// method begin
+		sb.append("\n");
+		
+		// method comment
+		sb.append("\t\t/**\n");
+		sb.append("\t\t * Chooses a projectTupleX according to the length of {@link CrossProjection#fieldIndexes} \n");
+		sb.append("\t\t * \n");
+		sb.append("\t\t * @return The projected DataSet.\n");
+		sb.append("\t\t * \n");
+		sb.append("\t\t * @see Projection\n");
+		sb.append("\t\t */\n");
+		
+		// method signature
+		sb.append("\t\t@SuppressWarnings(\"unchecked\")\n");
+		sb.append("\t\tpublic <OUT extends Tuple> ProjectCross<I1, I2, OUT> projectTupleX() {\n");
+		sb.append("\t\t\tProjectCross<I1, I2, OUT> projectionCross = null;\n\n");
+		sb.append("\t\t\tswitch (fieldIndexes.length) {\n");
+		for (int numFields = FIRST; numFields <= LAST; numFields++) {
+			sb.append("\t\t\tcase " + numFields +":" + " projectionCross = (ProjectCross<I1, I2, OUT>) projectTuple"+numFields+"(); break;\n");	
+		}
+		sb.append("\t\t\tdefault: throw new IllegalStateException(\"Excessive arity in tuple.\");\n");
+		sb.append("\t\t\t}\n\n");
+		sb.append("\t\t\treturn projectionCross;\n");
+		
+		// method end
+		sb.append("\t\t}\n");
+		
 		for (int numFields = FIRST; numFields <= LAST; numFields++) {
 
 			// method begin
@@ -169,11 +196,7 @@ class TupleGenerator {
 			// method comment
 			sb.append("\t\t/**\n");
 			sb.append("\t\t * Projects a pair of crossed elements to a {@link Tuple} with the previously selected fields. \n");
-			sb.append("\t\t * Requires the classes of the fields of the resulting tuples. \n");
 			sb.append("\t\t * \n");
-			for (int i = 0; i < numFields; i++) {
-				sb.append("\t\t * @param type" + i + " The class of field '"+i+"' of the result tuples.\n");
-			}
 			sb.append("\t\t * @return The projected data set.\n");
 			sb.append("\t\t * \n");
 			sb.append("\t\t * @see Tuple\n");
@@ -185,33 +208,11 @@ class TupleGenerator {
 			appendTupleTypeGenerics(sb, numFields);
 			sb.append("> ProjectCross<I1, I2, Tuple"+numFields+"<");
 			appendTupleTypeGenerics(sb, numFields);
-			sb.append(">> types(");
-			for (int i = 0; i < numFields; i++) {
-				if (i > 0) {
-					sb.append(", ");
-				}
-				sb.append("Class<");
-				sb.append(GEN_TYPE_PREFIX + i);
-				sb.append("> type" + i);
-			}
+			sb.append(">> projectTuple"+numFields+"(");
 			sb.append(") {\n");
 
-			// convert type0..1 to types array
-			sb.append("\t\t\tClass<?>[] types = {");
-			for (int i = 0; i < numFields; i++) {
-				if (i > 0) {
-					sb.append(", ");
-				}
-				sb.append("type" + i);
-			}
-			sb.append("};\n");
-
-			// check number of types and extract field types
-			sb.append("\t\t\tif(types.length != this.fieldIndexes.length) {\n");
-			sb.append("\t\t\t\tthrow new IllegalArgumentException(\"Numbers of projected fields and types do not match.\");\n");
-			sb.append("\t\t\t}\n");
-			sb.append("\t\t\t\n");
-			sb.append("\t\t\tTypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);\n");
+			// extract field types
+			sb.append("\t\t\tTypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);\n");
 
 			// create new tuple type info
 			sb.append("\t\t\tTupleTypeInfo<Tuple"+numFields+"<");
@@ -223,7 +224,7 @@ class TupleGenerator {
 			// create and return new project operator
 			sb.append("\t\t\treturn new ProjectCross<I1, I2, Tuple"+numFields+"<");
 			appendTupleTypeGenerics(sb, numFields);
-			sb.append(">>(this.ds1, this.ds2, this.fieldIndexes, this.isFieldInFirst, tType);\n");
+			sb.append(">>(this.ds1, this.ds2, this.fieldIndexes, this.isFieldInFirst, tType, this);\n");
 
 			// method end
 			sb.append("\t\t}\n");
@@ -239,7 +240,34 @@ class TupleGenerator {
 	private static void modifyProjectOperator(File root) throws IOException {
 		// generate code
 		StringBuilder sb = new StringBuilder();
-
+		
+		// method begin
+		sb.append("\n");
+		
+		// method comment
+		sb.append("\t\t/**\n");
+		sb.append("\t\t * Chooses a projectTupleX according to the length of {@link Projection#fieldIndexes} \n");
+		sb.append("\t\t * \n");
+		sb.append("\t\t * @return The projected DataSet.\n");
+		sb.append("\t\t * \n");
+		sb.append("\t\t * @see Projection\n");
+		sb.append("\t\t */\n");
+		
+		// method signature
+		sb.append("\t\t@SuppressWarnings(\"unchecked\")\n");
+		sb.append("\t\tpublic <OUT extends Tuple> ProjectOperator<T, OUT> projectTupleX() {\n");
+		sb.append("\t\t\tProjectOperator<T, OUT> projOperator = null;\n\n");
+		sb.append("\t\t\tswitch (fieldIndexes.length) {\n");
+		for (int numFields = FIRST; numFields <= LAST; numFields++) {
+			sb.append("\t\t\tcase " + numFields +":" + " projOperator = (ProjectOperator<T, OUT>) projectTuple"+numFields+"(); break;\n");	
+		}
+		sb.append("\t\t\tdefault: throw new IllegalStateException(\"Excessive arity in tuple.\");\n");
+		sb.append("\t\t\t}\n\n");
+		sb.append("\t\t\treturn projOperator;\n");
+		
+		// method end
+		sb.append("\t\t}\n");
+		
 		for (int numFields = FIRST; numFields <= LAST; numFields++) {
 
 			// method begin
@@ -248,11 +276,7 @@ class TupleGenerator {
 			// method comment
 			sb.append("\t\t/**\n");
 			sb.append("\t\t * Projects a {@link Tuple} {@link DataSet} to the previously selected fields. \n");
-			sb.append("\t\t * Requires the classes of the fields of the resulting Tuples. \n");
 			sb.append("\t\t * \n");
-			for (int i = 0; i < numFields; i++) {
-				sb.append("\t\t * @param type" + i + " The class of field '"+i+"' of the result Tuples.\n");
-			}
 			sb.append("\t\t * @return The projected DataSet.\n");
 			sb.append("\t\t * \n");
 			sb.append("\t\t * @see Tuple\n");
@@ -264,33 +288,11 @@ class TupleGenerator {
 			appendTupleTypeGenerics(sb, numFields);
 			sb.append("> ProjectOperator<T, Tuple"+numFields+"<");
 			appendTupleTypeGenerics(sb, numFields);
-			sb.append(">> types(");
-			for (int i = 0; i < numFields; i++) {
-				if (i > 0) {
-					sb.append(", ");
-				}
-				sb.append("Class<");
-				sb.append(GEN_TYPE_PREFIX + i);
-				sb.append("> type" + i);
-			}
+			sb.append(">> projectTuple"+numFields+"(");
 			sb.append(") {\n");
-
-			// convert type0..1 to types array
-			sb.append("\t\t\tClass<?>[] types = {");
-			for (int i = 0; i < numFields; i++) {
-				if (i > 0) {
-					sb.append(", ");
-				}
-				sb.append("type" + i);
-			}
-			sb.append("};\n");
-
-			// check number of types and extract field types
-			sb.append("\t\t\tif(types.length != this.fieldIndexes.length) {\n");
-			sb.append("\t\t\t\tthrow new IllegalArgumentException(\"Numbers of projected fields and types do not match.\");\n");
-			sb.append("\t\t\t}\n");
-			sb.append("\t\t\t\n");
-			sb.append("\t\t\tTypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types, ds.getType());\n");
+			
+			// extract field types
+			sb.append("\t\t\tTypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, ds.getType());\n");
 
 			// create new tuple type info
 			sb.append("\t\t\tTupleTypeInfo<Tuple"+numFields+"<");
@@ -302,7 +304,7 @@ class TupleGenerator {
 			// create and return new project operator
 			sb.append("\t\t\treturn new ProjectOperator<T, Tuple"+numFields+"<");
 			appendTupleTypeGenerics(sb, numFields);
-			sb.append(">>(this.ds, this.fieldIndexes, tType);\n");
+			sb.append(">>(this.ds, this.fieldIndexes, tType, this);\n");
 
 			// method end
 			sb.append("\t\t}\n");
@@ -318,7 +320,34 @@ class TupleGenerator {
 	private static void modifyJoinProjectOperator(File root) throws IOException {
 		// generate code
 		StringBuilder sb = new StringBuilder();
-
+		
+		// method begin
+		sb.append("\n");
+		
+		// method comment
+		sb.append("\t\t/**\n");
+		sb.append("\t\t * Chooses a projectTupleX according to the length of {@link JoinProjection#fieldIndexes} \n");
+		sb.append("\t\t * \n");
+		sb.append("\t\t * @return The projected DataSet.\n");
+		sb.append("\t\t * \n");
+		sb.append("\t\t * @see Projection\n");
+		sb.append("\t\t */\n");
+		
+		// method signature
+		sb.append("\t\t@SuppressWarnings(\"unchecked\")\n");
+		sb.append("\t\tpublic <OUT extends Tuple> ProjectJoin<I1, I2, OUT> projectTupleX() {\n");
+		sb.append("\t\t\tProjectJoin<I1, I2, OUT> projectJoin = null;\n\n");
+		sb.append("\t\t\tswitch (fieldIndexes.length) {\n");
+		for (int numFields = FIRST; numFields <= LAST; numFields++) {
+			sb.append("\t\t\tcase " + numFields +":" + " projectJoin = (ProjectJoin<I1, I2, OUT>) projectTuple"+numFields+"(); break;\n");	
+		}
+		sb.append("\t\t\tdefault: throw new IllegalStateException(\"Excessive arity in tuple.\");\n");
+		sb.append("\t\t\t}\n\n");
+		sb.append("\t\t\treturn projectJoin;\n");
+		
+		// method end
+		sb.append("\t\t}\n");
+		
 		for (int numFields = FIRST; numFields <= LAST; numFields++) {
 
 			// method begin
@@ -329,9 +358,6 @@ class TupleGenerator {
 			sb.append("\t\t * Projects a pair of joined elements to a {@link Tuple} with the previously selected fields. \n");
 			sb.append("\t\t * Requires the classes of the fields of the resulting tuples. \n");
 			sb.append("\t\t * \n");
-			for (int i = 0; i < numFields; i++) {
-				sb.append("\t\t * @param type" + i + " The class of field '"+i+"' of the result tuples.\n");
-			}
 			sb.append("\t\t * @return The projected data set.\n");
 			sb.append("\t\t * \n");
 			sb.append("\t\t * @see Tuple\n");
@@ -343,33 +369,11 @@ class TupleGenerator {
 			appendTupleTypeGenerics(sb, numFields);
 			sb.append("> ProjectJoin<I1, I2, Tuple"+numFields+"<");
 			appendTupleTypeGenerics(sb, numFields);
-			sb.append(">> types(");
-			for (int i = 0; i < numFields; i++) {
-				if (i > 0) {
-					sb.append(", ");
-				}
-				sb.append("Class<");
-				sb.append(GEN_TYPE_PREFIX + i);
-				sb.append("> type" + i);
-			}
+			sb.append(">> projectTuple"+numFields+"(");
 			sb.append(") {\n");
 
-			// convert type0..1 to types array
-			sb.append("\t\t\tClass<?>[] types = {");
-			for (int i = 0; i < numFields; i++) {
-				if (i > 0) {
-					sb.append(", ");
-				}
-				sb.append("type" + i);
-			}
-			sb.append("};\n");
-
-			// check number of types and extract field types
-			sb.append("\t\t\tif(types.length != this.fieldIndexes.length) {\n");
-			sb.append("\t\t\t\tthrow new IllegalArgumentException(\"Numbers of projected fields and types do not match.\");\n");
-			sb.append("\t\t\t}\n");
-			sb.append("\t\t\t\n");
-			sb.append("\t\t\tTypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes, types);\n");
+			// extract field types
+			sb.append("\t\t\tTypeInformation<?>[] fTypes = extractFieldTypes(fieldIndexes);\n");
 
 			// create new tuple type info
 			sb.append("\t\t\tTupleTypeInfo<Tuple"+numFields+"<");
@@ -381,7 +385,7 @@ class TupleGenerator {
 			// create and return new project operator
 			sb.append("\t\t\treturn new ProjectJoin<I1, I2, Tuple"+numFields+"<");
 			appendTupleTypeGenerics(sb, numFields);
-			sb.append(">>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType);\n");
+			sb.append(">>(this.ds1, this.ds2, this.keys1, this.keys2, this.hint, this.fieldIndexes, this.isFieldInFirst, tType, this);\n");
 
 			// method end
 			sb.append("\t\t}\n");

http://git-wip-us.apache.org/repos/asf/incubator-flink/blob/a9ecaba7/flink-java/src/test/java/org/apache/flink/api/java/functions/SemanticPropertiesProjectionTest.java
----------------------------------------------------------------------
diff --git a/flink-java/src/test/java/org/apache/flink/api/java/functions/SemanticPropertiesProjectionTest.java b/flink-java/src/test/java/org/apache/flink/api/java/functions/SemanticPropertiesProjectionTest.java
index fcef05a..69ef5af 100644
--- a/flink-java/src/test/java/org/apache/flink/api/java/functions/SemanticPropertiesProjectionTest.java
+++ b/flink-java/src/test/java/org/apache/flink/api/java/functions/SemanticPropertiesProjectionTest.java
@@ -84,6 +84,36 @@ public class SemanticPropertiesProjectionTest {
 			fail("Exception in test: " + e.getMessage());
 		}
 	}
+	
+	@Test
+	public void ProjectOperatorWithoutTypesClassTest() {
+		try {
+			ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+			DataSet<Tuple5<Integer, Long, String, Long, Integer>> tupleDs = env.fromCollection(emptyTupleData, tupleTypeInfo);
+			
+			tupleDs.project(1, 3).project(2).project(0).print();
+
+			Plan plan = env.createProgramPlan();
+
+			GenericDataSinkBase<?> sink = plan.getDataSinks().iterator().next();
+			PlanProjectOperator<?, ?> projectOperator = ((PlanProjectOperator<?, ?>) sink.getInput());
+
+			SingleInputSemanticProperties props = projectOperator.getSemanticProperties();
+
+			assertTrue(props.getForwardedField(1).size() == 1);
+			assertTrue(props.getForwardedField(3).size() == 1);
+			assertTrue(props.getForwardedField(2).size() == 1);
+			assertTrue(props.getForwardedField(0).size() == 1);
+			assertTrue(props.getForwardedField(1).contains(0));
+			assertTrue(props.getForwardedField(3).contains(1));
+			assertTrue(props.getForwardedField(2).contains(2));
+			assertTrue(props.getForwardedField(0).contains(3));
+		} catch (Exception e) {
+			System.err.println(e.getMessage());
+			e.printStackTrace();
+			fail("Exception in test: " + e.getMessage());
+		}
+	}
 
 	@Test
 	public void JoinProjectionTest() {
@@ -114,6 +144,36 @@ public class SemanticPropertiesProjectionTest {
 			fail("Exception in test: " + e.getMessage());
 		}
 	}
+	
+	@Test
+	public void JoinProjectionWithoutTypesClassTest() {
+		try {
+			ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+			DataSet<Tuple5<Integer, Long, String, Long, Integer>> tupleDs = env.fromCollection(emptyTupleData, tupleTypeInfo);
+			
+			tupleDs.join(tupleDs).where(0).equalTo(0).projectFirst(2).projectFirst(3).projectSecond(1, 4).print();
+
+			Plan plan = env.createProgramPlan();
+
+			GenericDataSinkBase<?> sink = plan.getDataSinks().iterator().next();
+			JoinOperatorBase<?, ?, ?, ?> projectJoinOperator = ((JoinOperatorBase<?, ?, ?, ?>) sink.getInput());
+
+			DualInputSemanticProperties props = projectJoinOperator.getSemanticProperties();
+
+			assertTrue(props.getForwardedField1(2).size() == 1);
+			assertTrue(props.getForwardedField1(3).size() == 1);
+			assertTrue(props.getForwardedField2(1).size() == 1);
+			assertTrue(props.getForwardedField2(4).size() == 1);
+			assertTrue(props.getForwardedField1(2).contains(0));
+			assertTrue(props.getForwardedField1(3).contains(1));
+			assertTrue(props.getForwardedField2(1).contains(2));
+			assertTrue(props.getForwardedField2(4).contains(3));
+		} catch (Exception e) {
+			System.err.println(e.getMessage());
+			e.printStackTrace();
+			fail("Exception in test: " + e.getMessage());
+		}
+	}
 
 	@Test
 	public void CrossProjectionTest() {
@@ -145,4 +205,35 @@ public class SemanticPropertiesProjectionTest {
 			fail("Exception in test: " + e.getMessage());
 		}
 	}
+	
+	@Test
+	public void CrossProjectionWithoutTypesClassTest() {
+		try {
+			ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
+			DataSet<Tuple5<Integer, Long, String, Long, Integer>> tupleDs = env.fromCollection(emptyTupleData, tupleTypeInfo);
+
+			DataSet<Tuple4<String, Long, Long, Integer>> result = tupleDs.cross(tupleDs).projectFirst(2, 3).projectSecond(1, 4);
+			result.print();
+
+			Plan plan = env.createProgramPlan();
+
+			GenericDataSinkBase<?> sink = plan.getDataSinks().iterator().next();
+			CrossOperatorBase<?, ?, ?, ?> projectCrossOperator = ((CrossOperatorBase<?, ?, ?, ?>) sink.getInput());
+
+			DualInputSemanticProperties props = projectCrossOperator.getSemanticProperties();
+
+			assertTrue(props.getForwardedField1(2).size() == 1);
+			assertTrue(props.getForwardedField1(3).size() == 1);
+			assertTrue(props.getForwardedField2(1).size() == 1);
+			assertTrue(props.getForwardedField2(4).size() == 1);
+			assertTrue(props.getForwardedField1(2).contains(0));
+			assertTrue(props.getForwardedField1(3).contains(1));
+			assertTrue(props.getForwardedField2(1).contains(2));
+			assertTrue(props.getForwardedField2(4).contains(3));
+		} catch (Exception e) {
+			System.err.println(e.getMessage());
+			e.printStackTrace();
+			fail("Exception in test: " + e.getMessage());
+		}
+	}
 }


Mime
View raw message