Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Warning when secondary key fully specified but not used, but if specified then error

I am baffled. If I compile the following piece of code

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      class_constructor,
      main.
  PRIVATE SECTION.
    TYPES: BEGIN OF t_record,
      transid TYPE sy-index,
      item1   TYPE char20,
      value1  TYPE p LENGTH 7 DECIMALS 2,
      value2  TYPE p LENGTH 7 DECIMALS 2,
      value3  TYPE p LENGTH 7 DECIMALS 2,
      value4  TYPE p LENGTH 7 DECIMALS 2,
    END OF t_record,
    tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1 WITH UNIQUE HASHED KEY sec_key COMPONENTS value1 value2 value3.
    CLASS-DATA:
      mt_record TYPE tt_record.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD class_constructor.
    DO 10 TIMES.
      INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
        INTO TABLE mt_record.
    ENDDO.
  ENDMETHOD.

  METHOD main.
    DATA:
      l_secs TYPE i,
      l_millisecs TYPE i,
      l_start TYPE timestampl,
      l_end   TYPE timestampl,
      l_diff  LIKE l_start.
    GET TIME STAMP FIELD l_start.
    LOOP AT mt_record INTO DATA(ls_record)
      WHERE value1 = '100.00' AND value2 = '150.0' AND value3 = '10.0'.

      ASSERT 1 = 1.

    ENDLOOP.
    GET TIME STAMP FIELD l_end.
    l_diff = l_end - l_start.

    WRITE: / l_diff.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).

I get the following warning

Program ZZY
Secondary key "SEC_KEY" is completely specified. However, the primary
key is used for access. Check whether access using "SEC_KEY" is more
efficient

but if I specify this key with USING KEY sec_key then I get a compilation time error!

REPORT zzy.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      class_constructor,
      main.
  PRIVATE SECTION.
    TYPES: BEGIN OF t_record,
      transid TYPE sy-index,
      item1   TYPE char20,
      value1  TYPE p LENGTH 7 DECIMALS 2,
      value2  TYPE p LENGTH 7 DECIMALS 2,
      value3  TYPE p LENGTH 7 DECIMALS 2,
      value4  TYPE p LENGTH 7 DECIMALS 2,
    END OF t_record,
    tt_record TYPE STANDARD TABLE OF t_record WITH NON-UNIQUE KEY transid item1 WITH UNIQUE HASHED KEY sec_key COMPONENTS value1 value2 value3.
    CLASS-DATA:
      mt_record TYPE tt_record.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD class_constructor.
    DO 10 TIMES.
      INSERT VALUE t_record( transid = sy-index item1 = |Item{ sy-index }| value1 = sy-index value2 = sy-index / 2 value3 = sy-index / 4 value4 = 0 )
        INTO TABLE mt_record.
    ENDDO.
  ENDMETHOD.

  METHOD main.
    DATA:
      l_secs TYPE i,
      l_millisecs TYPE i,
      l_start TYPE timestampl,
      l_end   TYPE timestampl,
      l_diff  LIKE l_start.
    GET TIME STAMP FIELD l_start.
    LOOP AT mt_record INTO DATA(ls_record) USING KEY sec_key
      WHERE value1 = '100.00' AND value2 = '150.0' AND value3 = '10.0'.

      ASSERT 1 = 1.

    ENDLOOP.
    GET TIME STAMP FIELD l_end.
    l_diff = l_end - l_start.

    WRITE: / l_diff.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).

Program ZZY
Key "SEC_KEY" is a secondary key of type "HASHED KEY". All key components must be provided in these cases

What am I doing wrong here?

like image 905
Jagger Avatar asked May 03 '16 09:05

Jagger


1 Answers

As stated in the syntax documentation of the LOOP conditions,

If a secondary table key is specified, any WHERE condition also specified must be optimizable. Otherwise a syntax error occurs or an exception is raised.

Be sure to have a sufficient supply of coffee or whatever stimulants you prefer at hand when diving into the rules of what is comparable and optimizable and what not, because that's tedious stuff. In this case, the comparison specified has to include a TYPE P and a TYPE C (like '100.00') - which should be possible - but additionally, the lengths have to match, which they don't. Even the documentation states that

Due to the complexity of the comparison rules (particularly for elementary data types, it is not a good idea to construct a set of rules detailing exactly when the comparison type matches the data type of the left operand.

Bottom line: Use the exact same type for key access, never rely on implicit conversions. If you declare a variable or constant using the same type you used for your valueN columns and use that in the comparison, it works.

like image 172
vwegert Avatar answered Nov 09 '22 20:11

vwegert