OpenEdge BUFFER-COPY from INT64 to INT Causes Index Corruption

March 24, 2008 · Filed Under Reliability · Comment 

A kbase entry P129814 regarding code that can cause database index corruption affects all V10 versions and service packs. The index corruption occurs when an INT64 field is buffer-copied to an INT field. Our testing shows that this also corrupts temp-table indexes and only manifests when the INT64 value is greater than MAX_INTEGER (about 2.1 billion).

What makes this more concerning is that the index corruption will go undetected until the record is accessed as the code below shows. In addition with shops migrating from 9 to 10 it is likely that INT64 and INT fields will co-exist for some time in the database and temp-table as new code and fields are added in the normal evolutionary process.

We recommend caution when writing code that mixes INT64 with INT fields.

Some simple code to manifest the bug:

/*
BUFFER-COPY from INT64 to INT Causes Index Corruption */
DEFINE TEMP-TABLE ttTest NO-UNDO FIELD iIdxNorm AS INTEGER
   FORMAT “z,zzz,zzz,zz9″ INDEX idxPrime IS PRIMARY UNIQUE iIdxNorm ASC.
DEFINE TEMP-TABLE ttTest2 NO-UNDO
FIELD iIdxNorm AS INT64 INDEX idxPrime IS PRIMARY UNIQUE iIdxNorm ASC.
/* The value of the copy from int64 must be greater than MAX_INTEGER (32 bit)
(about 2.147 billion) to cause the error. */
DO cnt = 1 TO 2:
    CREATE ttTest2.
    ASSIGN iIdxNorm = 2400000000 + cnt.
END.
FOR EACH ttTest2:
    /* The first ttTest2 record creates a new ttTest. The 2nd ttTest2
    record is copied over the ttTest which modifies the existing ttTest
    index record and corrupts it. */
    BUFFER-COPY ttTest2 TO ttTest.
END.
/* No errors thrown to this point, the creates appear to have succeeded */
/* Attempting to access the ttTest index throws the error */
FOR EACH ttTest NO-LOCK:
    DISPLAY ttTest.iIdxNorm.
END.