Java Code Examples for org.apache.flink.api.common.operators.SemanticProperties#InvalidSemanticAnnotationException

The following examples show how to use org.apache.flink.api.common.operators.SemanticProperties#InvalidSemanticAnnotationException . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine6() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input1 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 4L, 5L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input2 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input1.join(input2).where(0).equalTo(0).with(new AllForwardedExceptJoin<Long>())
			.withForwardedFieldsSecond("0->1;");
}
 
Example 2
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine4() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedBothAnnotationJoin<Long, Long, Long, Long>())
			.withForwardedFieldsSecond("0->1;");
}
 
Example 3
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine3() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedBothAnnotationJoin<Long, Long, Long, Long>())
			.withForwardedFieldsFirst("0->1;");
}
 
Example 4
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine2() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedSecondAnnotationJoin<Long>())
			.withForwardedFieldsSecond("0->1");
}
 
Example 5
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine1() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedFirstAnnotationJoin<Long>())
			.withForwardedFieldsFirst("0->1");
}
 
Example 6
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testUnaryForwardedOverwritingInLine2() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input.map(new AllForwardedExceptMapper<Tuple3<Long, Long, Long>>()).withForwardedFields("0->1; 2");
}
 
Example 7
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testUnaryForwardedOverwritingInLine1() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input.map(new WildcardForwardedMapper<Tuple3<Long, Long, Long>>()).withForwardedFields("0->1; 2");
}
 
Example 8
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine5() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input1 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 4L, 5L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input2 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input1.join(input2).where(0).equalTo(0).with(new AllForwardedExceptJoin<Long>())
			.withForwardedFieldsFirst("0->1;");
}
 
Example 9
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine5() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input1 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 4L, 5L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input2 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input1.join(input2).where(0).equalTo(0).with(new AllForwardedExceptJoin<Long>())
			.withForwardedFieldsFirst("0->1;");
}
 
Example 10
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine4() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedBothAnnotationJoin<Long, Long, Long, Long>())
			.withForwardedFieldsSecond("0->1;");
}
 
Example 11
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine3() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedBothAnnotationJoin<Long, Long, Long, Long>())
			.withForwardedFieldsFirst("0->1;");
}
 
Example 12
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine2() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedSecondAnnotationJoin<Long>())
			.withForwardedFieldsSecond("0->1");
}
 
Example 13
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine1() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input1 = env.fromElements(new Tuple2<Long, Long>(3L, 4L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple2<Long, Long>> input2 = env.fromElements(new Tuple2<Long, Long>(3L, 2L));
	input1.join(input2).where(0).equalTo(0).with(new ForwardedFirstAnnotationJoin<Long>())
			.withForwardedFieldsFirst("0->1");
}
 
Example 14
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testUnaryForwardedOverwritingInLine2() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input.map(new AllForwardedExceptMapper<Tuple3<Long, Long, Long>>()).withForwardedFields("0->1; 2");
}
 
Example 15
Source File: SemanticPropertiesTranslationTest.java    From Flink-CEPplus with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testUnaryForwardedOverwritingInLine1() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input.map(new WildcardForwardedMapper<Tuple3<Long, Long, Long>>()).withForwardedFields("0->1; 2");
}
 
Example 16
Source File: SemanticPropertiesTranslationTest.java    From flink with Apache License 2.0 5 votes vote down vote up
@Test(expected = SemanticProperties.InvalidSemanticAnnotationException.class)
public void testBinaryForwardedOverwritingInLine6() {
	ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input1 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 4L, 5L));
	@SuppressWarnings("unchecked")
	DataSet<Tuple3<Long, Long, Long>> input2 = env.fromElements(new Tuple3<Long, Long, Long>(3L, 2L, 1L));
	input1.join(input2).where(0).equalTo(0).with(new AllForwardedExceptJoin<Long>())
			.withForwardedFieldsSecond("0->1;");
}
 
Example 17
Source File: SingleInputUdfOperator.java    From Flink-CEPplus with Apache License 2.0 3 votes vote down vote up
/**
 * Adds semantic information about forwarded fields of the user-defined function.
 * The forwarded fields information declares fields which are never modified by the function and
 * which are forwarded at the same position to the output or unchanged copied to another position in the output.
 *
 * <p>Fields that are forwarded at the same position are specified by their position.
 * The specified position must be valid for the input and output data type and have the same type.
 * For example <code>withForwardedFields("f2")</code> declares that the third field of a Java input tuple is
 * copied to the third field of an output tuple.
 *
 * <p>Fields which are unchanged copied to another position in the output are declared by specifying the
 * source field reference in the input and the target field reference in the output.
 * {@code withForwardedFields("f0->f2")} denotes that the first field of the Java input tuple is
 * unchanged copied to the third field of the Java output tuple. When using a wildcard ("*") ensure that
 * the number of declared fields and their types in input and output type match.
 *
 * <p>Multiple forwarded fields can be annotated in one ({@code withForwardedFields("f2; f3->f0; f4")})
 * or separate Strings ({@code withForwardedFields("f2", "f3->f0", "f4")}).
 * Please refer to the JavaDoc of {@link org.apache.flink.api.common.functions.Function} or Flink's documentation for
 * details on field references such as nested fields and wildcard.
 *
 * <p>It is not possible to override existing semantic information about forwarded fields which was
 * for example added by a {@link org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFields} class annotation.
 *
 * <p><b>NOTE: Adding semantic information for functions is optional!
 * If used correctly, semantic information can help the Flink optimizer to generate more efficient execution plans.
 * However, incorrect semantic information can cause the optimizer to generate incorrect execution plans which compute wrong results!
 * So be careful when adding semantic information.
 * </b>
 *
 * @param forwardedFields A list of field forward expressions.
 * @return This operator with annotated forwarded field information.
 *
 * @see org.apache.flink.api.java.functions.FunctionAnnotation
 * @see org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFields
 */
public O withForwardedFields(String... forwardedFields) {

	if (this.udfSemantics == null) {
		// extract semantic properties from function annotations
		setSemanticProperties(extractSemanticAnnotations(getFunction().getClass()));
	}

	if (this.udfSemantics == null
			|| this.analyzedUdfSemantics) { // discard analyzed semantic properties
		setSemanticProperties(new SingleInputSemanticProperties());
		SemanticPropUtil.getSemanticPropsSingleFromString(this.udfSemantics, forwardedFields, null, null, this.getInputType(), this.getResultType());
	} else {
		if (udfWithForwardedFieldsAnnotation(getFunction().getClass())) {
			// refuse semantic information as it would override the function annotation
			throw new SemanticProperties.InvalidSemanticAnnotationException("Forwarded field information " +
					"has already been added by a function annotation for this operator. " +
					"Cannot overwrite function annotations.");
		} else {
			SemanticPropUtil.getSemanticPropsSingleFromString(this.udfSemantics, forwardedFields, null, null, this.getInputType(), this.getResultType());
		}
	}

	@SuppressWarnings("unchecked")
	O returnType = (O) this;
	return returnType;
}
 
Example 18
Source File: SingleInputUdfOperator.java    From flink with Apache License 2.0 3 votes vote down vote up
/**
 * Adds semantic information about forwarded fields of the user-defined function.
 * The forwarded fields information declares fields which are never modified by the function and
 * which are forwarded at the same position to the output or unchanged copied to another position in the output.
 *
 * <p>Fields that are forwarded at the same position are specified by their position.
 * The specified position must be valid for the input and output data type and have the same type.
 * For example <code>withForwardedFields("f2")</code> declares that the third field of a Java input tuple is
 * copied to the third field of an output tuple.
 *
 * <p>Fields which are unchanged copied to another position in the output are declared by specifying the
 * source field reference in the input and the target field reference in the output.
 * {@code withForwardedFields("f0->f2")} denotes that the first field of the Java input tuple is
 * unchanged copied to the third field of the Java output tuple. When using a wildcard ("*") ensure that
 * the number of declared fields and their types in input and output type match.
 *
 * <p>Multiple forwarded fields can be annotated in one ({@code withForwardedFields("f2; f3->f0; f4")})
 * or separate Strings ({@code withForwardedFields("f2", "f3->f0", "f4")}).
 * Please refer to the JavaDoc of {@link org.apache.flink.api.common.functions.Function} or Flink's documentation for
 * details on field references such as nested fields and wildcard.
 *
 * <p>It is not possible to override existing semantic information about forwarded fields which was
 * for example added by a {@link org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFields} class annotation.
 *
 * <p><b>NOTE: Adding semantic information for functions is optional!
 * If used correctly, semantic information can help the Flink optimizer to generate more efficient execution plans.
 * However, incorrect semantic information can cause the optimizer to generate incorrect execution plans which compute wrong results!
 * So be careful when adding semantic information.
 * </b>
 *
 * @param forwardedFields A list of field forward expressions.
 * @return This operator with annotated forwarded field information.
 *
 * @see org.apache.flink.api.java.functions.FunctionAnnotation
 * @see org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFields
 */
public O withForwardedFields(String... forwardedFields) {

	if (this.udfSemantics == null) {
		// extract semantic properties from function annotations
		setSemanticProperties(extractSemanticAnnotations(getFunction().getClass()));
	}

	if (this.udfSemantics == null
			|| this.analyzedUdfSemantics) { // discard analyzed semantic properties
		setSemanticProperties(new SingleInputSemanticProperties());
		SemanticPropUtil.getSemanticPropsSingleFromString(this.udfSemantics, forwardedFields, null, null, this.getInputType(), this.getResultType());
	} else {
		if (udfWithForwardedFieldsAnnotation(getFunction().getClass())) {
			// refuse semantic information as it would override the function annotation
			throw new SemanticProperties.InvalidSemanticAnnotationException("Forwarded field information " +
					"has already been added by a function annotation for this operator. " +
					"Cannot overwrite function annotations.");
		} else {
			SemanticPropUtil.getSemanticPropsSingleFromString(this.udfSemantics, forwardedFields, null, null, this.getInputType(), this.getResultType());
		}
	}

	@SuppressWarnings("unchecked")
	O returnType = (O) this;
	return returnType;
}
 
Example 19
Source File: TwoInputUdfOperator.java    From flink with Apache License 2.0 3 votes vote down vote up
/**
 * Adds semantic information about forwarded fields of the second input of the user-defined function.
 * The forwarded fields information declares fields which are never modified by the function and
 * which are forwarded at the same position to the output or unchanged copied to another position in the output.
 *
 * <p>Fields that are forwarded at the same position are specified by their position.
 * The specified position must be valid for the input and output data type and have the same type.
 * For example <code>withForwardedFieldsSecond("f2")</code> declares that the third field of a Java input tuple
 * from the second input is copied to the third field of an output tuple.
 *
 * <p>Fields which are unchanged copied from the second input to another position in the output are declared
 * by specifying the source field reference in the second input and the target field reference in the output.
 * {@code withForwardedFieldsSecond("f0->f2")} denotes that the first field of the second input Java tuple is
 * unchanged copied to the third field of the Java output tuple. When using a wildcard ("*") ensure that
 * the number of declared fields and their types in second input and output type match.
 *
 * <p>Multiple forwarded fields can be annotated in one ({@code withForwardedFieldsSecond("f2; f3->f0; f4")})
 * or separate Strings ({@code withForwardedFieldsSecond("f2", "f3->f0", "f4")}).
 * Please refer to the JavaDoc of {@link org.apache.flink.api.common.functions.Function} or Flink's documentation for
 * details on field references such as nested fields and wildcard.
 *
 * <p>It is not possible to override existing semantic information about forwarded fields of the second input which was
 * for example added by a {@link org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFieldsSecond} class annotation.
 *
 * <p><b>NOTE: Adding semantic information for functions is optional!
 * If used correctly, semantic information can help the Flink optimizer to generate more efficient execution plans.
 * However, incorrect semantic information can cause the optimizer to generate incorrect execution plans which compute wrong results!
 * So be careful when adding semantic information.
 * </b>
 *
 * @param forwardedFieldsSecond A list of forwarded field expressions for the second input of the function.
 * @return This operator with annotated forwarded field information.
 *
 * @see org.apache.flink.api.java.functions.FunctionAnnotation
 * @see org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFieldsSecond
 */
@SuppressWarnings("unchecked")
public O withForwardedFieldsSecond(String... forwardedFieldsSecond) {
	if (this.udfSemantics == null || this.analyzedUdfSemantics) {
		// extract semantic properties from function annotations
		setSemanticProperties(extractSemanticAnnotationsFromUdf(getFunction().getClass()));
	}

	if (this.udfSemantics == null || this.analyzedUdfSemantics) {
		setSemanticProperties(new DualInputSemanticProperties());
		SemanticPropUtil.getSemanticPropsDualFromString(this.udfSemantics, null, forwardedFieldsSecond,
				null, null, null, null, getInput1Type(), getInput2Type(), getResultType());
	} else {
		if (udfWithForwardedFieldsSecondAnnotation(getFunction().getClass())) {
			// refuse semantic information as it would override the function annotation
			throw new SemanticProperties.InvalidSemanticAnnotationException("Forwarded field information " +
					"has already been added by a function annotation for the second input of this operator. " +
					"Cannot overwrite function annotations.");
		} else {
			SemanticPropUtil.getSemanticPropsDualFromString(this.udfSemantics, null, forwardedFieldsSecond,
					null, null, null, null, getInput1Type(), getInput2Type(), getResultType());
		}
	}

	O returnType = (O) this;
	return returnType;
}
 
Example 20
Source File: TwoInputUdfOperator.java    From Flink-CEPplus with Apache License 2.0 3 votes vote down vote up
/**
 * Adds semantic information about forwarded fields of the first input of the user-defined function.
 * The forwarded fields information declares fields which are never modified by the function and
 * which are forwarded at the same position to the output or unchanged copied to another position in the output.
 *
 * <p>Fields that are forwarded at the same position are specified by their position.
 * The specified position must be valid for the input and output data type and have the same type.
 * For example <code>withForwardedFieldsFirst("f2")</code> declares that the third field of a Java input tuple
 * from the first input is copied to the third field of an output tuple.
 *
 * <p>Fields which are unchanged copied from the first input to another position in the output are declared
 * by specifying the source field reference in the first input and the target field reference in the output.
 * {@code withForwardedFieldsFirst("f0->f2")} denotes that the first field of the first input Java tuple is
 * unchanged copied to the third field of the Java output tuple. When using a wildcard ("*") ensure that
 * the number of declared fields and their types in first input and output type match.
 *
 * <p>Multiple forwarded fields can be annotated in one ({@code withForwardedFieldsFirst("f2; f3->f0; f4")})
 * or separate Strings ({@code withForwardedFieldsFirst("f2", "f3->f0", "f4")}).
 * Please refer to the JavaDoc of {@link org.apache.flink.api.common.functions.Function} or Flink's documentation for
 * details on field references such as nested fields and wildcard.
 *
 * <p>It is not possible to override existing semantic information about forwarded fields of the first input which was
 * for example added by a {@link org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFieldsFirst} class annotation.
 *
 * <p><b>NOTE: Adding semantic information for functions is optional!
 * If used correctly, semantic information can help the Flink optimizer to generate more efficient execution plans.
 * However, incorrect semantic information can cause the optimizer to generate incorrect execution plans which compute wrong results!
 * So be careful when adding semantic information.
 * </b>
 *
 * @param forwardedFieldsFirst A list of forwarded field expressions for the first input of the function.
 * @return This operator with annotated forwarded field information.
 *
 * @see org.apache.flink.api.java.functions.FunctionAnnotation
 * @see org.apache.flink.api.java.functions.FunctionAnnotation.ForwardedFieldsFirst
 */
@SuppressWarnings("unchecked")
public O withForwardedFieldsFirst(String... forwardedFieldsFirst) {
	if (this.udfSemantics == null || this.analyzedUdfSemantics) {
		// extract semantic properties from function annotations
		setSemanticProperties(extractSemanticAnnotationsFromUdf(getFunction().getClass()));
	}

	if (this.udfSemantics == null || this.analyzedUdfSemantics) {
		setSemanticProperties(new DualInputSemanticProperties());
		SemanticPropUtil.getSemanticPropsDualFromString(this.udfSemantics, forwardedFieldsFirst, null,
				null, null, null, null, getInput1Type(), getInput2Type(), getResultType());
	} else {
		if (this.udfWithForwardedFieldsFirstAnnotation(getFunction().getClass())) {
			// refuse semantic information as it would override the function annotation
			throw new SemanticProperties.InvalidSemanticAnnotationException("Forwarded field information " +
					"has already been added by a function annotation for the first input of this operator. " +
					"Cannot overwrite function annotations.");
		} else {
			SemanticPropUtil.getSemanticPropsDualFromString(this.udfSemantics, forwardedFieldsFirst, null,
					null, null, null, null, getInput1Type(), getInput2Type(), getResultType());
		}
	}

	O returnType = (O) this;
	return returnType;
}