Skip to main content

The Segment Dictionary

Typed mode needs to know each segment's field layout (name, offset, length, type). That segment dictionary is just a relation with these columns:

idoctyp, cimtyp, release, segnam, segdef, field_pos, field_name, offset, length, datatype, ...

Its origin is irrelevant to the parser — a file, a table, a view, or a query all work. The readers that take a dict argument (sap_idoc_read_segment, sap_idoc_read_fields, and the converters) accept any of them.

Option A — Offline / hand-authored

Write the fields (order + width) and let sap_idoc_dict_offsets compute the offsets, then check it with sap_idoc_dict_validate:

-- compute field offsets from lengths
SELECT * FROM sap_idoc_dict_offsets('mytype.fields.csv');

-- list structural problems — an empty result means the dictionary is sound
SELECT * FROM sap_idoc_dict_validate('mytype.dict.csv');

sap_idoc_dict_validate catches bad offsets, overlaps, and missing fields early — run it before you rely on a hand-authored dictionary.

Option B — Online, from a live system

Requires erpl_rfc loaded. The extension ships two SQL macros so it's a one-liner:

LOAD erpl_rfc;
LOAD erpl_idoc;

CREATE SECRET sap (
TYPE sap_rfc, ASHOST '…', SYSNR '00', CLIENT '100', USER '…', PASSWD '…'
);

-- fetch + normalize the dictionary for a basic type
SELECT * FROM sap_idoc_dictionary(sap_idoc_params('ORDERS05'));

Persist once → reuse forever offline

This is the connected → detached bridge: fetch the dictionary once on a machine that can reach SAP, persist it to Parquet, then decode IDocs anywhere with no SAP and no erpl_rfc.

COPY (SELECT * FROM sap_idoc_dictionary(sap_idoc_params('ORDERS05')))
TO 'orders.dict.parquet' (FORMAT parquet);
-- later, on a SAP-less host — only erpl_idoc + the dictionary file
SELECT * FROM sap_idoc_read_segment('doc.idoc', 'E1BPSBONEW', 'orders.dict.parquet');

Normalizing a raw field list

If you already have a raw IDOCTYPE_READ_COMPLETE field list, normalize it to the dictionary schema:

SELECT * FROM sap_idoc_dict_from_fields(fields, 'ORDERS05', '', '740');

See also