Application Development and Automation Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

Weird behaviour with VALUE and SWITCH

EnnoWulff
Active Contributor
6,210

Today I encountered a strange behaviour after I added a SWITCH statement in a VALUE assignment.

Let's assume there is a simple table with two columns ID and TXT:

  TYPES: BEGIN OF _test,
           id   TYPE char02,
           txt  TYPE string,
         END OF _test,
         _test_t TYPE STANDARD TABLE OF _test WITH DEFAULT KEY.

Then there is a simple VALUE statement to fill the table:

  DATA(test) =  VALUE _test_t(
      ( id = 'AA'   txt = 'AAA' )
      ( id = 'bb'   txt = 'bbb' )
      (             txt = 'CCC' )     ).

Not a big deal and works as expected:

ID | TXT
---+-----
AA | AAA
bb | bbb
   | CCC

Then I added the SWITCH statement because line #2 should have a different value depending on a variable:

  DATA(test) =  VALUE _test_t(
      ( id = 'AA' txt = 'AAA' )
      ( SWITCH #( sy-uname(1)
         WHEN 'E' THEN VALUE #( id = 'BB'  txt = 'BBB' )
                  ELSE VALUE #( id = 'bb'  txt = 'bbb' ) ) )
      ( txt = 'CCC' ) ).

As my username starts with E the result looks - also expected - like this:

ID | TXT
---+-----
AA | AAA
BB | BBB
   | CCC

But then for any reason I didn't want to have the field ID filled in the first line and changed my code accordingly:

  DATA(test) =  VALUE _test_t(
      ( txt = 'AAA' )              "Value for ID deleted!
      ( SWITCH #( sy-uname(1)
         WHEN 'E' THEN VALUE #( id = 'BB'  txt = 'BBB' )
                  ELSE VALUE #( id = 'bb'  txt = 'bbb' ) ) )
      ( txt = 'CCC' ) ).

The expected result would be, that line #2 is the only line where field ID is filled:

ID | TXT
---+-----
   | AAA
BB | BBB
   | CCC

But the result is the following:

ID | TXT
---+-----
   | AAA
BB | BBB
BB | CCC

Line #3 is filled with ID = "BB" although I do not tell the system to do so...

I tested on two different SAP-Systems:

  • SAP_ABA 750/ SAP_BASIS 750
  • SAP_ABA 75E/ SAP_BASIS 754

Can anyone proof this behavior or tell me what I am doing wrong?

Thanks in advance
~Enno

1 ACCEPTED SOLUTION
Read only

joltdx
Active Contributor
5,728

This is fun! 🙂

I don't think it has anything do to with SWITCH though. It's probably something with the VALUE operator itself, or nested VALUEs, or something... It's reproducible with this code:

DATA(test) =  VALUE _test_t( (                     txt = 'AAA' )
                             ( VALUE #( id = 'BB'  txt = 'BBB' ) )
                             (                     txt = 'CCC' ) ).
   AAA  
BB BBB  
BB CCC  

I guess the inner VALUE leaks it's id out to the outer?

Removing the inner VALUE, and it works as expected:

DATA(test_line) = VALUE _test( id = 'BB'  txt = 'BBB' ).
DATA(test) = VALUE _test_t( ( txt = 'AAA' )
                            ( test_line )
                            ( txt = 'CCC' ) ).
    AAA  
BB  BBB  
    CCC  

Oddly enough, as you also noted, setting the id on the first line or actually any line before the nested VALUE also works as expected:

DATA(test) = VALUE _test_t( (                    txt = 'AAA' )
                            (          id = 'BB' txt = 'BBB' )
                            ( VALUE #( id = 'CC' txt = 'CCC' ) )
                            (                    txt = 'DDD' ) ).
    AAA  
BB  BBB  
CC  CCC
    DDD  

Maybe it's affecting the superstructure? Because this is valid, and expected:

DATA(test) = VALUE _test_t( (           txt = 'AAA' )
                            ( id = 'BB' txt = 'BBB' )
                              id = 'CC'
                            (           txt = 'DDD' )
                            (           txt = 'EEE' )
                              id = 'FF'
                            (           txt = 'GGG' ) ).
    AAA  
BB  BBB  
CC  DDD  
CC  EEE  
FF  GGG  
20 REPLIES 20
Read only

nomssi
Active Contributor
5,728
DATA(test) =  VALUE _test_t(
      ( txt = 'AAA' )             
      ( id = 'BB'  txt = 'BBB' )        
                 ( txt = 'CCC' ) ).

I guess you are using the short form described in this Horst Keller Post, allowing you to fill columns with the same value in subsequent lines.

Read only

EnnoWulff
Active Contributor
0 Likes
5,728

Thanks jacques.nomssi for this idea! I firstly thought of this. but afik my code exactly fills 3 lines. I might be wrong though.

Read only

5,728

That does exist but to achieve this shouldn't the id Part be OUTSIDE the line brackets (on table type Level)?

Read only

EnnoWulff
Active Contributor
0 Likes
5,728

Hey michael.biber2! yes that's right. see example of jorgen_lindqvist41

Read only

thalesvb
Active Contributor
5,721

I toyed with it (7.52 trial) and found something else. Code below, moving "id = 'No' " part between later lines and that tells a bit more.

DATA(test) =  VALUE _test_t(
      ( txt = 'AAA' )              "Value for ID deleted!
      ( SWITCH #( 'E'
         WHEN 'E' THEN VALUE #( id = 'BB'  txt = 'BBB' )
                  ELSE VALUE #( id = 'bb'  txt = 'bbb' ) ) )
      ( txt = 'CCC' )
      ( txt = 'DDD' )
      ( id = 'No' txt = 'EEE' )
      ( txt = 'FFF' ) ).

Kernel had a hangover with that switch, it looks like a bug.

Read only

joltdx
Active Contributor
0 Likes
5,721

Hah, that line reset the functionality again to a working state... 🙂

Read only

EnnoWulff
Active Contributor
5,721

Thanks thalesvb for also proving it is a bug.

Read only

joltdx
Active Contributor
5,729

This is fun! 🙂

I don't think it has anything do to with SWITCH though. It's probably something with the VALUE operator itself, or nested VALUEs, or something... It's reproducible with this code:

DATA(test) =  VALUE _test_t( (                     txt = 'AAA' )
                             ( VALUE #( id = 'BB'  txt = 'BBB' ) )
                             (                     txt = 'CCC' ) ).
   AAA  
BB BBB  
BB CCC  

I guess the inner VALUE leaks it's id out to the outer?

Removing the inner VALUE, and it works as expected:

DATA(test_line) = VALUE _test( id = 'BB'  txt = 'BBB' ).
DATA(test) = VALUE _test_t( ( txt = 'AAA' )
                            ( test_line )
                            ( txt = 'CCC' ) ).
    AAA  
BB  BBB  
    CCC  

Oddly enough, as you also noted, setting the id on the first line or actually any line before the nested VALUE also works as expected:

DATA(test) = VALUE _test_t( (                    txt = 'AAA' )
                            (          id = 'BB' txt = 'BBB' )
                            ( VALUE #( id = 'CC' txt = 'CCC' ) )
                            (                    txt = 'DDD' ) ).
    AAA  
BB  BBB  
CC  CCC
    DDD  

Maybe it's affecting the superstructure? Because this is valid, and expected:

DATA(test) = VALUE _test_t( (           txt = 'AAA' )
                            ( id = 'BB' txt = 'BBB' )
                              id = 'CC'
                            (           txt = 'DDD' )
                            (           txt = 'EEE' )
                              id = 'FF'
                            (           txt = 'GGG' ) ).
    AAA  
BB  BBB  
CC  DDD  
CC  EEE  
FF  GGG  
Read only

5,721

The last one is very interesting

Read only

joltdx
Active Contributor
5,721

It is, and it's quite useful. It's the short form documented under Alternative 1 here.

It also states that it is allowed to use VALUE line_type( ) inside the VALUE...

Read only

EnnoWulff
Active Contributor
5,721

Thanks jorgen_lindqvist41 for "eliminating" SWITCH from the construct and confirming that I am not completely mad... 😉

Read only

joltdx
Active Contributor
5,721

I can only confirm that you are not madder than me, but anytime you need help with that, just ping me... 🙂

Read only

EnnoWulff
Active Contributor
0 Likes
5,721

Thanks for your offer! 😉 Still unsure if I will have to open a defect or if horst.keller will suddenly breach in... :]

Read only

Sandra_Rossi
Active Contributor
5,721

I looked at the generated byte code. We can see that it uses one work area that it appends repeatedly to the table for each new line, and does automatically the CLEAR of each field that is to be reinitialized if a value was set in the previous line but not in the new line. But it forgets to do the CLEAR after the VALUE #( ... ) line (I took the simplified example of Jörgen).

Read only

5,721

The big question: Is it a bug or a feature?

Read only

5,721

I don't think it's a feature ! 😄

Read only

abo
Active Contributor
5,721

That depends on the seniority of the bug 😉

Read only

matt
Active Contributor
5,721

Looking at the byte code. I already had very high respect for your technical abilities, but now...

I agree - it's a bug.

Read only

5,721

Matthew Billingham Not so complex 😉 (TAPP = table append, iclr = clear, mvqw = quick move, STCK = obscure stacking function / first code indicates a variant and next arguments are memory address references)

iclr 04  0019            
STCK 05  0000            
STCK 07  001A            

iclr 03  001A            
MOVE FF  0229  001C  001B
TAPP 20  0352  0019  001A

mvqw 04  0200  0010  00A4
MOVE FF  0229  001C  001F
TAPP 20  0352  0019  001A

iclr 00  0022            
MOVE FF  0229  001C  0021
TAPP 20  0352  0019  001A
STCK 06  0000            
Read only

EnnoWulff
Active Contributor
5,721

Dear Customer,

you have found a bug in the ABAP compiler. The kernel patch will be made
available via note 3042453.

Thanks @all for your participation!