Menu ▾ ▴

#1292 RELATIVE file: DELETE and REWRITE of a deleted or never-written record return status 00, not 23

unclassified
open
nobody
None
5 - default
2026-11-04
2026-11-04
No

For a RELATIVE file in RANDOM or DYNAMIC access, DELETE and REWRITE of a record number whose slot is empty, because the record was deleted or never written, give I-O status 00 and take the NOT INVALID KEY branch, and the REWRITE stores no record; READ of the same key gives 23.

To reproduce

reldel.cob (attached) writes record 1, then in I-O mode deletes it twice, rewrites it and reads it:

IDENTIFICATION DIVISION.
PROGRAM-ID. RELDEL.
ENVIRONMENT DIVISION.
INPUT-OUTPUT SECTION.
FILE-CONTROL.
    SELECT F ASSIGN TO "reldel.dat"
        ORGANIZATION IS RELATIVE
        ACCESS MODE IS RANDOM
        RELATIVE KEY IS RK
        FILE STATUS IS FS.
DATA DIVISION.
FILE SECTION.
FD F.
01 R PIC X(4).
WORKING-STORAGE SECTION.
01 RK PIC 9(3) VALUE 0.
01 FS PIC XX VALUE SPACES.
PROCEDURE DIVISION.
    OPEN OUTPUT F
    MOVE 1 TO RK
    MOVE "AAAA" TO R
    WRITE R
    CLOSE F
    OPEN I-O F
    DELETE F RECORD
    DISPLAY "DELETE 1   " FS
    DELETE F RECORD
    DISPLAY "DELETE 2   " FS
    MOVE "BBBB" TO R
    REWRITE R
    DISPLAY "REWRITE    " FS
    READ F
    DISPLAY "READ       " FS
    CLOSE F
    STOP RUN.
cobc -std=cobol2014 -fformat=free -x reldel.cob && ./reldel

What happens

3.2.0 and 3.3-dev r5751 both print

DELETE 1   00
DELETE 2   00
REWRITE    00
READ       23

and the same with -std=cobol2002, -std=cobol85 and the default dialect. delhole.cob, attached, shows the same for a slot that was never written, and deltwice.cob shows that the INVALID KEY phrase is not taken (SECOND DELETE OK 00).

What should happen

The second DELETE and the REWRITE give status 23, run their INVALID KEY phrase and change nothing in the file. DELETE general rule 4 (ISO/IEC 1989:2023 14.9.10.4) and REWRITE general rule 21 (14.9.35.4) make this the invalid key condition, and then, by 9.1.14, "execution of the input-output statement that recognized the condition is unsuccessful and the file is not affected". The same rules are in the 2002 final draft and the 2014 FCD (REWRITE rule 20 there).

Why it happens

In libcob/fileio.c, relative_read treats a record-size word of 0 as an empty slot, but relative_rewrite (random and dynamic access) and relative_delete return 23 only when the size word cannot be read, past the end of the file.

Proposed fix

The attached n10-relative-delete-rewrite.patch (against 3.3-dev r5751) makes relative_delete and relative_rewrite return COB_STATUS_23_KEY_NOT_EXISTS before writing anything when the size word for the key is 0. Both leave the file offset where it was before the patch, so later READ NEXT and READ PREVIOUS return the same records. It adds the testsuite case "DELETE / REWRITE of a missing RELATIVE record" to run_file.at, with ChangeLog entries. make check: 1373 expected, 9 skipped, 0 failed (1372 unpatched); the new test fails without the patch.

Other behavior changes:

  • A program with a USE procedure for the file now runs it where it continued silently.
  • A program with no FILE STATUS clause, no INVALID KEY phrase and no USE procedure now stops with libcob: error: record key does not exist (status = 23), as it does today for any other status 23.
  • In sequential access, a DELETE after the program has moved the RELATIVE KEY to an empty slot now gives 23 instead of 00.
  • A zero-length record, which WRITE stores as an empty slot with status 00 (a separate defect), now gives 23 at DELETE and REWRITE, as at READ.

bugs #1281: the run unit stops on a status 10 or 2x when the file has no FILE STATUS clause.

Details

GnuCOBOL 3.2.0 (Ubuntu gnucobol3 3.2-4build1) and 3.3-dev r5751 (CI snapshot 3.3-dev.138 of 2026-10-29), x86_64 Linux, both run 2026-11-04, default file handler.

4 Attachments

Discussion


Log in to post a comment.