Skip to Content
Author's profile photo Horst Keller

ABAP News for Release 7.40 – Internal Tables with Empty Key

Internal tables with empty key?

Each internal table has a primary key. Even standard tables have a table key. Key access is not optimized for standard tables but the primary key plays a role if you use SORT itab without explicit sort fields or for table statements with FROM wa.

How do you declare a table? Pragmatically, often as follows:

DATA: BEGIN OF struct,
        col1 TYPE i,
        col2 TYPE i,
      END OF struct.

DATA itab LIKE TABLE OF struct.

Looks good. But now do the following (in all releases):

DATA: BEGIN OF struct,
        col1 TYPE i,
        col2 TYPE i,
      END OF struct.

DATA itab LIKE TABLE OF struct.

structcol1 = 3. structcol2 = 1.
APPEND struct TO itab.
structcol1 = 2. structcol2 = 2.
APPEND struct TO itab.
structcol1 = 1. structcol2 = 1.
APPEND struct TO itab.

DATA jtab LIKE itab.
jtab = itab.

SORT jtab.

IF jtab = itab.
  MESSAGE ‘nop!’ TYPE ‘I’.
ENDIF.

SORT itab does nothing (some people tend to open a ticket now)! Why? Because itab has an empty key!

When you declare a standard table data object without specifiying the primary key, the default key is taken. The default key consists of all character and byte like fields of the table structrure. If the structure contains only numeric fields, duh! The same would have happened if you declared the DEFAULT KEY explicitly. But note that an empty key is not possible for sorted and hashed tables.

If you declare standard table types, the situation can become even more confusing.

TYPES: BEGIN OF struct,
         col1 TYPE i,
         col2 TYPE i,
       END OF struct.

TYPES itab TYPE STANDARD TABLE OF struct.

Here it is not the default key that is declared implicitly, but the table type is generic regarding its key.

To prove that, write

FIELD-SYMBOLS <itab> TYPE itab.
DATA jtab like <itab>.

Yo get a syntax error because the field symbol is generic and cannot be used behind LIKE.To get rid of the error you could add WITH DEFAULT KEY to the TYPES itab statement – and have an empty key again!

So, if you want to work with a table key it is always a good idea to explicitly define the key fields. Using the default key – either by chance or explicitly – is almost always critical because:

  • Identifying the key fields only by their data type often leads to unexpected behavior in sorts and other access types.
  • The possibility of an empty standard key in standard tables can cause unexpected behavior.
  • The standard key can contain many key fields, leading to performance problems.
  • In sorted tables and hashed tables the key fields are read-only, which can cause unexpected runtime errors.

But what if you do not care about the key at all? If you simply want to use an internal table as an array that does not depend on key values?

Before release 7.40, some unexpected behavior could arise for such arrays.With release 7.40 you can specify

… WITH EMPTY KEY.

when declaring standard table objects or table types. If you don’t care about the key, this new addition is always recommended in order to circumvent all problems with the default key or with a generic key.

 

TYPES itab TYPE STANDARD TABLE OF string WITH EMPTY KEY.

DATA(itab) = VALUE itab(
  ( `I’m going slightly mad` )
  ( `I’m going slightly mad` )
  ( `It finally happened – happened` )
  ( `It finally happened – ooh woh` ) ).

Without explicit key declaration the type would not be usable for the inline data declaration shown here. Since I don’t care about the key, I use the empty key. A SORT itab without specifying a sort key will do nothing and produce a warning from the syntax check.

Starting with release 7.40 you declare your standard tables either with a good key or an empty key but never with the chancy default key!

Assigned Tags

      17 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Starting with release 7.40 you declare your standard tables either with a good key or an empty key but never with the chancy default key!


      How about with KEY table_line?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Why? This is of course a way to define a key. Either alle columns of a structured line (if you really need it) or a key of an elementary (or other) line type.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Just pointing out the omission.

      However, the since default key is always potentially chancy, in pre 7.4 (which most of us are on!) perhaps it should be advised to use table_line instead.

      I recently got bitten by a default key when using DELETE ADJACENT. Of course COMPARING ALL FIELDS fixed the issue.

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hmm, don't agree.

      Instead of using DEFAULT KEY before 7.40 you must think about the key to use. table_line is a short form for denoting all components of a structured table line. This can be OK from case to case but I think not generalized. So before 7.40 you must denote either individual components or table_line.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      before 7.40 you must denote either individual components or table_line.

      Isn't that what I said?

      Pre 7.4: Don't use default key if you're not specifying the components - use table_line.

      7.4 on: Don't use default key if you're not specifying the components - use empty key.


      Mind you, we're still dealing with a large programming community who still widely use tables with headers, SO_NEW_DOCUMENT_ATT_SEND_API1, FAE, ON CHANGE, standard tables and binary search, global variables, forms...

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Just noticed that Web Dynpro context type definitions use DEFAULT KEY.

      Author's profile photo Timo John
      Timo John

      Hello Horst,

      thanks for sharing this Information.

      I'm currently working as ABAP Quality Engineer in an SAP Implementation project, so I am interested in having as much checked as possible.

      Do you think this could be tested using the SCI? With other words, can SAP come up with a test in category robustness as example?

      Kind Regards

      Timo

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hello Timo,

      Unfortunately I don't know about any plans for such quality checks coming from SAP.

      Some years ago, there were plans for this, but alas the written ABAP Programming Guidelines were the main output of that period. Further plans, e.g. for a Quality Cockpit where the  robustness of programs can be testet was stopped short. The concern of the test writers is more about performance and security now.

      Best

      Horst

      Author's profile photo Lars Hvam
      Lars Hvam

      Hi,

      I've added check 48 in GitHub - larshp/abapOpenChecks: Open source checks for SAP Code Inspector / ABAP Test Cockpit which will check for DEFAULT KEY when EMPTY KEY is possible in the system.

      Beware of bugs, bad check performance, false positives etc. Feedback and issues appreciated at the github page

      Author's profile photo Jacques Nomssi Nzali
      Jacques Nomssi Nzali

      Hello Horst,

      my understanding is that

      TYPES tt_list TYPE STANDARD TABLE OF i WITH DEFAULT KEY

      will build a table type with an empty key while

      TYPES tt_list TYPE SORTED TABLE OF i WITH NON-UNIQUE DEFAULT KEY.

      will have a primary key. Is this correct? How is the DEFAULT KEY logic key for sorted table different from the standard table logic?

      best regards,

      JNN

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Hi Jacques,

      No, the DEFAULT KEY for non-structured table lines is the table line. So, in both of your cases WITH  ... DEFAULT KEY has the same effect as WITH ... KEY table_line. In both cases it is not empty. It is empty, if the line type is a structure with one component of type i. Then you get a syntax error in the second case.

      Best

      Horst

      Author's profile photo Yu Chen
      Yu Chen

      I have writen following codes:

      DATA itab2 TYPE TABLE OF i.

      itab2 VALUE #).

      DATA jtab2 LIKE itab2.

      jtab2 itab2.
      SORT jtab2.

      IF jtab2 itab2.
      MESSAGE ‘nop again!’ TYPE ‘I’.
      ENDIF.

      The sort is working and the table jtab2 is sorted. But why is jtab2 still equal to itab2 and the message comes again?

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      A bug in the ABAP kernel.

      I also found it some months ago and it is corrected now.

       

      Author's profile photo Yu Chen
      Yu Chen

      Hi Horst,

      Thank you for the prompt answer. And I have one more question:

      I have tried the last example above with an addional action sort:

      TYPES itab TYPE STANDARD TABLE OF string WITH EMPTY KEY.

      DATA(itab) = VALUE itab(
      ( `I’m going slightly mad` )
      ( `I’m going slightly mad` )
      ( `It finally happened – happened` )
      ( `It finally happened – ooh woh` ) ).

      SORT itab STABLE.

      But the sort is still working. Do you know why?

      My system is 7.40 SP13

      Best, Yu

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

      Exactly the same bug for elementary line type.

      Horst

      Author's profile photo Andrew Howell
      Andrew Howell

      Sorry to resurrect this old discussion.. Regarding your final sentence "Starting with release 7.40 you declare your standard tables either with a good key or an empty key but never with the chancy default key!" I just stumbled into a problem:

      I want to call a function module which has a 'tables' parameter defined with typing 'LIKE conf_out'

      I tried typing my internal table which I pass as
      TYPE STANDARD TABLE OF conf_out WITH EMPTY KEY

      but was told it is incompatible.

      I tried
      TYPE STANDARD TABLE OF conf_out WITH KEY atinn

      but was told it is also incompatible.

       

      It is happy with
      TYPE STANDARD TABLE OF conf_out WITH DEFAULT KEY

      Would this be a valid use-case for DEFAULT KEY or have a missed some other way of creating a compatible parameter without header line?

       

      Thanks in advance

      Author's profile photo Horst Keller
      Horst Keller
      Blog Post Author

       

      The type of the actual parameter must match the type of the formal parameter. For internal tables, the key is part of the type. Since a TABLES parameter has a default key, normally you cannot pass a formal parameter with empty key.