There is a note http://service.sap.com/sap/support/notes/1090369 which describes difference between IF and IFS. Here I will try to explain with the help of mapping example how both the Boolean functions will behave with same input.

As per SAP Note, IF and IFS Pseudocode

IF:

========================================================================

Value = if (<condition>, <expression1>, <expression2>)

“That is, all arguments are evaluated first, then value of one of them is returned. To minimize compatibility problems with old usages, the function makes one exception to this rule: in case when evaluating one of the branches throws an Exception, the function ignores it, if the exception is in the branch that is not selected by condition”

IFS:

========================================================================

If <condition>
value = <expression1>
else
value = <expression2>
end

“In this case, one expects that the <condition> expression is evaluated first and then, depending on the value of the condition, one of the branch expressions is evaluated and assigned to variable ‘value’.”

IFS and IFSWIthoutElse functions have a Limitation.

When the The IFS and IFSWIthoutElse functions have the UDF of type Queue or Context, it will be executed unconditionally.
i.e the Queue UDF will be executed once even it does not have a matching condition in the input queue and the Context UDF will be executed once for every Context in the input queue, even if there is no matching condition in the input context.

For situation with functions leaving side-effects described above, we recommend to add a new argument to the User-Defined Function and create the side-effect conditionally based on that argument. Most probably you will want to put in this additional argument the same queue that you use in condition for function ‘ifS’.

1.      Standard functions

When IF function used, both the expressions are evaluated whereas in IFS case, only one expression will be evaluated based on the condition.

IF

standard functions.jpg

condition is true

if true.jpg

condition is false

/wp-content/uploads/2014/02/false_943341.jpg

You get the same result when you use IFS function in the above mapping. With standard function it is difficult to show how both the expressions are evaluated for if function.


2.      Simple UDF

I wrote small UDF function to write trace to show both the UDFs are evaluated when if function is used.

Condition: when Field value is equal to “IF” return expression 1 result. Else expression 2 result.

Expression 1: UDFA



UDF!.jpg



UDF B



UDFB.jpg



/wp-content/uploads/2014/02/mapping_943347.jpg

/wp-content/uploads/2014/02/true_943349.jpg

/wp-content/uploads/2014/02/false_943341.jpg

IFS

Condition is true:you can notice, only one UDF gets evaluated here based on the condition.


/wp-content/uploads/2014/02/true_943349.jpg

Condition is false

/wp-content/uploads/2014/02/false_943341.jpg

with multiple condition

/wp-content/uploads/2014/02/multiple_943354.jpg

3.  Simple UDF with exceptions

Let us put exception statement in UDFB.

UDF B

UDFB.jpg

IF

condition is true

/wp-content/uploads/2014/02/true_943349.jpg

condition is false

/wp-content/uploads/2014/02/false_943341.jpg

IFS

condition is true

IFS_true.jpg

condition is false

IFS_false.jpg

4.      Advanced UDF

Change the execution type to all values of context or all values of Queue. In my UDF I have used all values of Queue for both UDF A and UDF B.

I am changing the simple udf java code to fit into execution type all values of context/all values of queue.

UDF

UDF.jpg

If function behaviour is same in this use case as it works in simple UDF. As usual both the expressions are evaluated and only selected branch output is given.

/wp-content/uploads/2014/02/if_943362.jpg

IF

condition is true

If_true.jpg

IFS

As mentioned in the note, when IFS used with advanced UDFS, false condition branch executes at least once per context/queue. output is returned from branch one.

IFS_true.jpg

Let us put some exception statement in UDFB and use the same input for if and ifs.

UDF.jpg


IF result


condition is true. Both the expression are evaluated. Exceptions thrown in UDFB is ignored as branch is not selected. Mapping test produces output

IF.jpg



IFS result

condition is true, expression 1 is evaluated. Expression 2 also evaluated (for ifs function, this gets executed at least once). Branch 2 is not selected, but exception thrown in branch 2 is not ignored. So mapping test ends in error.


/wp-content/uploads/2014/02/ifs_943367.jpg


5.      Global container

Let us assume you want to generate numbers in sequence in target like 1,2,3. You will get different results for if and ifs

Create global variables in initialization block.




Global Variable.jpg


UDF A and UDF B are using the same code. ie. Incrementing the number by 1.

Please note execution type is  single values


UDF A.jpg


UDF B.jpg





if function result

mapping test.jpg

ifs function result

Only one UDF is called per condition so it produces expected output as 1,2,3

ifs_mapping results.jpg

Similarly you can try yourself for look up use case.

Modified the blog as per Artem Osukhovskyi comments.

To report this post you need to login first.

17 Comments

You must be Logged on to comment or reply to a post.

  1. Suseelan Hari

    Hi Muniyappan,

    Good Day!

    Keep up the good work! You have documented very clearly and it is very easy to understand. Thanks for sharing.

    Have a great day!

    Regards,

    Hari Suseelan

    (0) 
  2. Artem Osukhovskyi

    Hello Muni.

    Unfortunately your assumptions are wrong and they in fact contradict to the content of the note 1090369 you’ve mentioned in this blog post.

    Let me explain why:

    For the first case described in fact should be mentioned IfS and IfSWithoutElse (and for second case – their counter-parts).

    However IfS/IfSwithoutElse have limitations – when UDF is present in one of the result branches – it is called unconditionally as side-effect.

    Also you don’t have exception when using “If” because as it is mentioned in the note – such exceptions are ignored by mapping runtime unless this branch is selected by evaluated condition.

    See below quote for better explanation:

    Note :

    IFS and IFSWIthoutElse functions have a Limitation.

    When the The IFS and IFSWIthoutElse functions have the UDF of type Queue or Context, it will be executed unconditionally.

    i.e the Queue UDF will be executed once even it does not have a matching condition in the input queue and the Context UDF will be executed once for every Context in the input queue, even if there is no matching condition in the input context.

    For situation with functions leaving side-effects described above, we recommend to add a new argument to the User-Defined Function and create the side-effect conditionally based on that argument. Most probably you will want to put in this additional argument the same queue that you use in condition for function ‘ifS’.”


    Please adjust this post to reflect true behavior of described functions or remove it because it confuses other developers.


    Regards, Artem.

    (0) 
    1. Muniyappan Marasamy Post author

      You meant to say case one is talking about IFS and IFSWIthoutElse and case two is about if and ifwithoutelse.

      Where does the second condition come in either functions Ifwithoutelse and ifSwithoutelse?

      I believe below two cases are applicable for if. Not ifwithoutelse.

      1)

      if <condition>

        value = <expression1>

      else

        value = <expression2>

      end


      2)


      value = if (<condition>, <expression1>, <expression2>)

      (0) 
      1. Artem Osukhovskyi

        Hello Muni.

        Doesn’t matter whether it is IfS or IfSWithoutElse… Still there might be evaluated chain of functions which are passed to one or two inputs (if UDF is in corresponding chain).

        Here is an example:

        a) For “IfSWithoutElse” let’s imagine such pseudocode:

        if (false)

        value = UDF1

        end

        UDF1 will be executed as a side effect of IfS function. if your UDF1 contains throw Exception(..) – you will get see that exception during mapping test

        b) If you are using IfWithoutElse and same pseudocode:

        if (false)

        value = UDF1

        end

        Still UDF1 will be called, but exception will be suppressed by mapping runtime as explained in the note (because it is placed in the branch which doesn’t satisfy “If” condition).

        Conclusion:

        IfS/IfSwithoutElse works as “if” statement execution (besides the case when UDF is used – as explained in above examples).

        If/IfWithoutElse works as function call (when all arguments are evaluated and passed into function), but exceptions are suppressed for branch which doesn’t satisfy the condition.

        Regards, Artem.

        (0) 
        1. Muniyappan Marasamy Post author

          Sure. it should be “exceptions thrown will be suppressed for if/ifwithoutelse”. updated the blog.

          >>>If you are using IfWithoutElse and same pseudocode:

          if (false)

          value = UDF1

          end

          Still UDF1 will be called, but exception will be suppressed by mapping runtime as explained in the note (because it is placed in the branch which doesn’t satisfy “If” condition).

          i tested this, exception is suppressed for both the cases( condition true and condition false).

          (0) 
          1. Artem Osukhovskyi

              Hi Muni. Unfortunately this blog post is still confusing – I would recommend you to double check related note, compare it with your test results and rewrite it from scratch.

            Basically IfS and IfSwithoutElse should be used in order to avoid unnecessary overhead in branches which doesn’t satisfy IF-condition.

              Imagine that you have RFC or JDBC lookup as one of the arguments for IF-statement (not the condition, but outcome of IF-statement).  Obviously better to avoid or minimize any external communication during mapping when it’s not required (especially when it’s part of the loop with big number of elements). However adding UDF as part of respective branch will lead to side-effect that this branch will be executed unconditionally (and corresponding lookup/communication will take place as well). This unconditional invocation might be a headache for testing, add unnecessary system load and should be avoided at all costs.

              I would conclude that in most of cases UDFs should not be mapped to outputs of IF-statements (besides to the input condition) because it will be misleading anyway. Either if processing will be triggered but exceptions will be suppressed or when some branch will be executed unconditionally and possibly will modify queue/context supposed to be modified by another branch (satisfying actual condition).

            So if we are taking case with lookups but without any UDF – it can be explained like that:

            1. If you need to execute lookups in all outcome branches (either satisfying or not satisfying condition) – use If/IfWithoutElse, but be aware of possible exception suppression. Reasonable alternative to that – is using concat function to merge results.

            2. If you need to execute lookup only in the branch which satisfies IF-condition – use IfS/IfSwithoutElse. But avoid putting UDF in this branch.


            Regards, Artem.

            (0) 
            1. Muniyappan Marasamy Post author

              Thank you for your help and patience. i will modify and let you know. at the moment i am facing issues in attaching screenshots.Editor options are missing for reply

              just have one comment when using UDF along with  If function for your reply.

              >>>>>Also you don’t have exception when using “If” because as it is mentioned in the note – such exceptions are ignored by mapping runtime unless this branch is selected by evaluated condition.

              Here even if the branch is selected and exception is thrown, exception will be ignored and queue context will be suppressed. This is what i understood from mapping testing.

              (0) 
              1. Artem Osukhovskyi

                No problem, Muni.

                I think that is important and much confusing topic.

                While I was mixing IfS with UDFs – it was producing unexpected and weird results.

                E.g. when editing and testing mapping “display queue” command shows “true” as a result for IfS, but for subsequent function “createif” it shows that “false” is passed as input. 

                However when I moved my UDF and placed it after IfS – everything started to work as expected. I haven’t experimented with If/IfwithoutElse and exceptions, but if it’s true that exceptions are suppressed in both branches – it’s complete mess. At least one exception (from branch satisfying If-condition) should be thrown successfully, otherwise that greatly limits usability of these functions.

                Btw, it might be the case that such behavior is artifact of mapping editor or only related to specific UDF design. Hopefully you’ll be able to clarify that and provide good explanation for PI novices.

                Regards, Artem.

                (0) 
                1. Muniyappan Marasamy Post author

                  If function with UDF( all values queue/context ) works different. not able to get why it happens like this.

                  when i directly give true to condition, if branch is selected, but exception is not thrown. suppressed.

                  UDF:

                  MappingTrace t = container.getTrace();

                  t.addInfo(“UDF start”);

                  int i = 5/0;

                  result.addValue(“Street”);

                  1.

                  /wp-content/uploads/2016/05/1_943808.jpg

                  /wp-content/uploads/2016/05/2_943809.jpg

                  2.

                  i was wondering may be giving “true'” directly to condition is causing the issue. i tried removing the UDF.

                  /wp-content/uploads/2016/05/3_943810.jpg

                  it produces proper output in the above case which means supplying “true” directly to the condition works.

                  /wp-content/uploads/2016/05/4_943814.jpg

                  3.

                  if i place any expression(putting the condition to check if street value is”if” ) in the condition, it throws exception, this is expected. branch is selected, exception is thrown, mapping results end in error.

                  /wp-content/uploads/2016/05/5_943815.jpg

                  /wp-content/uploads/2016/05/6_943816.jpg

                  (0) 

Leave a Reply