Skip to content

Docs: migrating-from-ads.md should warn that CDX written by OpenADS is unreadable by SAP ACE (error 7017) #129

Description

@rkedzioralmaalpinex

Summary

docs/en/migrating-from-ads.md positions OpenADS as a drop-in replacement for SAP ACE ("move without rewriting"), but does not warn users that CDX files written by OpenADS are unreadable by SAP ACE. Applications that migrate to OpenADS, then attempt to switch back to ace64.dll from SAP (rollback, side-by-side testing, or mixed environment), get error 7017 Corrupt .ADI, .CDX, or .IDX index on every table that OpenADS has written to.

This is not a bug in the write path — it is intentional per src/drivers/cdx/cdx_index.cpp:1686:

// Harbour index signature "RCHB" (big-endian) at offset 20, as the
// native writer emits for the structure tag (TagBlock == 0).
file_hdr[20] = 0x52; file_hdr[21] = 0x43;

OpenADS emulates Harbour's native DBFCDX writer format, not the ACE CDX format. Both share the .cdx extension but are not binary-compatible headers. That's a defensible engineering choice, but users hitting rollback need to be told upfront.

Reproduction

  1. Start with SAP-built DRUKAR.cdx (single-tag CDX, ~3 KB) — SAP opens it fine.
  2. Point application at OpenADS ace64.dll, open the table and let OpenADS write to it (any index rebuild or record append that touches the CDX).
  3. Restore SAP ace64.dll and re-open the same table → error 7017 Corrupt .CDX.

Header diff (offset 0x00-0x1F, 3 KB DRUKAR.cdx):

Offset SAP OpenADS Meaning
0x04-07 00 00 00 00 FF FF FF FF free-page pointer
0x08-0B 00 00 00 01 (BE) 01 00 00 00 (LE) version/count word
0x0F 00 01 flag byte
0x10-13 zeros 00 04 00 02 reserved area, populated
0x14-17 zeros 52 43 48 42 = RCHB Harbour-writer magic
0x614-1B zeros DRUKAR\0 extra copy extra tag-name string

SAP's parser trips on the non-zero header/RCHB bytes and returns 7017.

What the docs currently say (and don't say)

  • docs/en/migrating-from-ads.md — pitches OpenADS as ADS-compatible, "move without rewriting", but has no section on rollback or on binary CDX format differences.
  • docs/en/known-issues.md — no mention of CDX header layout, 7017, or RCHB. The one CDX-adjacent note is about the ADS_DESCENDING flag value (0x08 vs 0x02), which is API-level, not file-format.
  • docs/en/rddads-compat.md — no mention.
  • docs/en/ordinal-compat.md — covers the DLL-level ordinal issue but not the on-disk format.

A user following the migration guide has no way to discover the one-way nature of the transition until an outage forces a rollback.

Proposed fix (docs only)

Add a short section to migrating-from-ads.md (or a dedicated docs/en/rollback.md linked from it), roughly:

Rollback to SAP ACE is not automatic

OpenADS writes CDX files in Harbour's DBFCDX-compatible format (magic RCHB at offset 0x14 in each CDX header). SAP ACE does not recognize this format and will return error 7017 "Corrupt .ADI, .CDX, or .IDX index" on any table whose CDX has been touched by OpenADS.

If you may need to run against SAP ACE again later (rollback, mixed environment, side-by-side benchmark), either:

  • Keep the original SAP-built CDX files backed up outside the working directory before pointing the app at OpenADS, or
  • After rolling back, run a global DELETE FILE *.cdx + rebuild-all-tags pass under SAP.

This does not apply in reverse: OpenADS reads SAP-built CDX files without modification, as long as no write happens.

Optionally: mention it near the top of migrating-from-ads.md as a callout, since it's the kind of thing that surprises people at the worst moment (production incident, needing to revert).

Not a feature request

I understand the format choice is deliberate and rewriting the whole write path in ACE-binary shape isn't in scope for this ticket. Just the documentation gap.

Related: #128 (perf regression on INDEX ON — separate concern). Both surfaced during a real-world evaluation on a 5.6 GB, 609-table Harbour/rddads app; happy to share more repro details from that environment on request.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions