{"id":50842412,"url":"https://github.com/datazoode/erpl-rev","last_synced_at":"2026-06-14T07:02:54.836Z","repository":{"id":363132731,"uuid":"1257343741","full_name":"DataZooDE/erpl-rev","owner":"DataZooDE","description":"Standalone C++ SAP RFC server bridging ABAP RFC into DuckDB (the inverse of erpl)","archived":false,"fork":false,"pushed_at":"2026-06-07T16:12:55.000Z","size":335,"stargazers_count":1,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-07T16:23:31.785Z","etag":null,"topics":["abap","cpp","data-integration","duckdb","lakehouse","replication","sap","sap-rfc"],"latest_commit_sha":null,"homepage":null,"language":"ABAP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DataZooDE.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-02T15:34:34.000Z","updated_at":"2026-06-03T07:23:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/DataZooDE/erpl-rev","commit_stats":null,"previous_names":["datazoode/erpl-rev"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/DataZooDE/erpl-rev","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataZooDE%2Ferpl-rev","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataZooDE%2Ferpl-rev/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataZooDE%2Ferpl-rev/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataZooDE%2Ferpl-rev/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DataZooDE","download_url":"https://codeload.github.com/DataZooDE/erpl-rev/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DataZooDE%2Ferpl-rev/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34312137,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-14T02:00:07.365Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abap","cpp","data-integration","duckdb","lakehouse","replication","sap","sap-rfc"],"created_at":"2026-06-14T07:02:53.831Z","updated_at":"2026-06-14T07:02:54.830Z","avatar_url":"https://github.com/DataZooDE.png","language":"ABAP","funding_links":[],"categories":[],"sub_categories":[],"readme":"# erpl-rev — query and replicate SAP through DuckDB\n\n[![CI](https://github.com/DataZooDE/erpl-rev/actions/workflows/ci.yml/badge.svg)](https://github.com/DataZooDE/erpl-rev/actions/workflows/ci.yml)\n\n**Run DuckDB SQL on SAP data, and bulk-replicate SAP into DuckDB — with nothing to install inside SAP.**\n\nerpl-rev is a small C++ server that registers at the SAP gateway as an RFC\ndestination. Your ABAP calls it with `CALL FUNCTION '…' DESTINATION 'ERPL_REV'`\nand **DuckDB runs behind it**. Two things, in equal measure: **query** SAP\ntables, CDS views and BW calculation views with full SQL (and join them to cloud\ndata), and **replicate** them into DuckDB, parquet, DuckLake, Iceberg or any\nDuckDB-attachable warehouse. No DuckDB extension in SAP, no DDIC structures, no\nSLT/SDI/BODS — payloads travel as plain JSON over RFC.\n\nIt's the inverse of [`erpl`](https://github.com/DataZooDE/erpl) — where `erpl`\nmakes DuckDB call *into* SAP, **erpl-rev has SAP call out into DuckDB.**\n\n\u003e **Status:** research prototype, but both paths — **query** (SQL, federation,\n\u003e console, live serving) and **replication** (table / CDS / BW → DuckDB, parquet\n\u003e + attached catalogs) — are verified end-to-end against a live SAP ABAP (A4H)\n\u003e system in `scripts/e2e.sh`.\n\n---\n\n## Query — SQL on SAP data, from ABAP and beyond\n\n- **Run DuckDB SQL from ABAP.** Send a query, get typed rows back — or an\n  interactive **ALV grid** via the in-GUI SQL console (`Z_ERPL_REV_SQL`, `SE38`).\n- **Do what Open SQL can't.** Joins across tables, window functions, aggregations\n  and parquet scans over live SAP data, without staging anything.\n- **Federate in one statement.** Join a SAP slice against a cloud **parquet /\n  Iceberg / DuckLake** dataset or an attached **Postgres / BigQuery** table, and\n  hand the result back to ABAP — cross-system queries SAP can't do alone.\n- **Query live, over the network.** With `--quack`, remote DuckDB clients\n  (notebooks, BI tools) query the same in-process data directly — no export step.\n- **Big results, fixed memory.** A streamed `OPEN`/`FETCH`/`CLOSE` cursor decodes\n  results page-by-page, so result size isn't bounded by ABAP memory.\n\n## Replicate — bulk-load SAP into DuckDB \u0026 the lakehouse\n\n- **Any SAP source.** Replicate **tables, CDS views (incl. `WITH PARAMETERS`) and\n  BW / HANA calculation views** into typed DuckDB — full or filtered, with\n  source-side `WHERE`, column selection and idempotent `UPSERT`. Built for\n  **\u003e100M-row** loads.\n- **Delta (incremental) too.** Keep a target in sync loading only what changed —\n  **watermark, change-document (CDHDR/CDPOS), and snapshot-diff (deletes)** methods,\n  all merging server-side, idempotent and re-runnable. Customer-owned Open SQL only\n  (no ODP / SAPI / `RFC_READ_TABLE`). See [`docs/delta.md`](docs/delta.md).\n- **Land in the open lakehouse.** parquet / partitioned datasets, **DuckLake** or\n  **Iceberg**, on local disk or **cloud object storage** (S3 / GCS / Azure).\n- **Publish into a warehouse.** `ATTACH` **Postgres / MySQL / BigQuery / MotherDuck**\n  and push a SAP slice in with one SQL statement — see\n  [Push to MotherDuck](#push-to-motherduck-duckdbs-cloud) below.\n- **Fast \u0026 parallel** — a live 10M-row run (50-of-400-column BSEG-shaped table,\n  BELNR-partitioned, on the A4H trial / loopback):\n\n![Parallel replication throughput: aggregate rises to ~167k rows/s at 5 workers (10M rows in 60s) while per-worker throughput tapers from 47k to 33k rows/s](docs/perf-scaling.png)\n\n| Workers | Wall time | Aggregate | Per worker |\n|:-------:|----------:|----------:|-----------:|\n| 2 | 106 s | ~94,000 rows/s  | ~47,000 rows/s |\n| 4 |  65 s | ~154,000 rows/s | ~38,000 rows/s |\n| 5 |  60 s | ~167,000 rows/s | ~33,000 rows/s |\n\n**Peak ~167k rows/s — 10M rows in a minute.** Each worker bulk-loads a disjoint\nkey range with a DuckDB `Appender` (~230× a naive per-row path); memory is bounded\nby batch size, and loads are restartable and idempotent\n([`test/bench_ingest.cpp`](test/bench_ingest.cpp)).\n\n### Push to MotherDuck (DuckDB's cloud)\n\n[MotherDuck](https://motherduck.com) is just another DuckDB-attachable catalog, so\nthe embedded engine reaches it exactly like Postgres / BigQuery / Iceberg — only the\n`ATTACH` and credentials differ. Point the server's boot init at MotherDuck once,\nthen replicate or publish SAP slices straight into the cloud.\n\n**1. Boot the server attached to MotherDuck.** Supply the token via the\n`motherduck_token` env var (or a `CREATE SECRET` in an `--init-file`) — never commit it:\n```bash\nexport motherduck_token='\u003cyour-md-token\u003e'\nERPL_REV_GWHOST=\u003cgw\u003e ERPL_REV_GWSERV=sapgw00 \\\n  ./build/erpl_rev_server --db erpl-rev.duckdb \\\n  --init-sql \"INSTALL motherduck; LOAD motherduck; ATTACH 'md:';\"\n```\nYour MotherDuck databases now appear as catalogs (e.g. `my_db.main.\u003ctable\u003e`).\n\n**2. Push a SAP slice from ABAP** — stage locally, then publish to the cloud:\n```abap\nzcl_erpl_rev_util=\u003ereplicate( iv_tab = 'MARA' iv_target = 'mara' ).\nzcl_erpl_rev_util=\u003epublish(                       \" FULL = overwrite, APPEND = insert\n  iv_source = 'mara' iv_kind = 'TABLE'\n  iv_dest   = 'my_db.main.mara' iv_mode = 'FULL' ).\n```\nThe *publish* field of `Z_ERPL_REV_REPLICATE` does the same from the GUI.\n\n**3. Query MotherDuck from the SQL console.** `Z_ERPL_REV_SQL` ships an **example\ndropdown** with ready-to-run queries: the classic NYC-taxi public-Parquet aggregate,\nMotherDuck's shared `sample_data` (taxi + Hacker News), a `SUMMARIZE`, and a\npush-a-table round-trip — pick one and hit *Execute*.\n\n\u003e The released bundle ships DuckDB with `parquet` / `json` built in; `motherduck`\n\u003e (and `httpfs`) auto-install from `extensions.duckdb.org` on first use, so the host\n\u003e needs outbound HTTPS — or pre-stage the extension for air-gapped systems.\n\n---\n\n## Why it fits the SAP data stack\n\n- **No SLT, no SDI, no Data Services, no add-on** — a transport (package `ZERPL`)\n  plus a registered RFC server. No core modification, no HANA license, no BTP.\n  Runs against any NetWeaver ABAP stack (ECC, S/4HANA, BW/4HANA).\n- **Reads what you model** — tables, CDS views (keys auto-detected), BW/HANA calc\n  views (`\"_SYS_BIC\".\"pkg/CV\"`) — semantics intact, not raw dumps.\n- **SLT semantics you know (LTRS)** — field selection, source-side filter, key\n  `UPSERT` — without standing up SLT.\n- **DDIC-typed \u0026 provably faithful** — NUMC / DATS / CURR / DECIMAL / RAW map to\n  real DuckDB types; a built-in diff harness checks the target against the source\n  **cell-by-cell** (incl. a 400-column BSEG-shaped table).\n\n**Security \u0026 authorizations.** Only `Z*` objects (no core mod), reached via a\ntype-T destination locked down with a gateway `reginfo` allow-list and (off-box)\nSNC. FM calls run as a comm user scoped to `S_RFC` for function group `ZERPL_REV`\nonly; the reports run under the end user's auth (CDS DCL is enforced, raw-table\n`SELECT` is **not** implicitly `S_TABU`-checked — gate program execution; the\nnative/ADBC BW path reads cross-client). Full guide: [`docs/security.md`](docs/security.md).\n\n---\n\n## Install \u0026 setup\n\n**Just want to run it?** This is the recommended way — grab the **single\nself-extracting binary** for your OS from the\n[latest release](https://github.com/DataZooDE/erpl-rev/releases)\n(`erpl-rev-linux-amd64`, `erpl-rev-macos-arm64`, `erpl-rev-windows-amd64.exe`) and\nrun it. It bundles the SAP NW RFC SDK + ICU + DuckDB, self-extracts on first\nlaunch, and needs **no `LD_LIBRARY_PATH`** and nothing else installed. Or use\n**Docker** — `docker pull ghcr.io/datazoode/erpl-rev:latest` — the image bakes the\n**same** bundle (see [Run with Docker](#run-with-docker)). Either way you still do\nthe one-time SAP-side wiring (**step 3**) and then run it (**step 4**).\n\n\u003e The numbered steps below **build from source** — only needed to develop erpl-rev\n\u003e or to produce the bundle yourself (`make bundle` → `dist/erpl-rev`).\n\n### Prerequisites\n- Linux host with **CMake ≥ 3.16**, a **C++17** compiler, **Ninja**, and **vcpkg**\n  (supplies Catch2 for the tests).\n- The proprietary **SAP NW RFC SDK** (not redistributed — see below).\n- A reachable SAP **gateway** (any NetWeaver ABAP; a local A4H docker trial works).\n\n### 1. Provide the SDK + DuckDB\nThe NW RFC SDK lives in a repo-local, gitignored `nwrfcsdk/linux/` (same convention\nas `erpl`). Download it from the SAP Software Center, or copy it from an `erpl`\ncheckout. DuckDB is fetched as an official prebuilt:\n```bash\ncp -a /path/to/nwrfcsdk ./nwrfcsdk     # provides nwrfcsdk/linux/{include,lib}\nmake duckdb-dist                       # fetch prebuilt libduckdb 1.5.3 into vendor/\n```\n\n### 2. Build \u0026 test\n```bash\nmake build      # -\u003e build/erpl_rev_server + build/erpl_rev_tests\nmake test       # the Catch2 suite against real DuckDB (no mocks)\n```\n`make build` also initialises the `third_party/posthog-telemetry` submodule, so a\nfresh clone needs no extra `git submodule` step.\n\n### 3. Wire up the SAP side (one-time)\nProduction = import the ABAP transport and run the setup classrun — full guide in\n[`docs/INSTALL.md`](docs/INSTALL.md). You need three things in the SAP system:\n- a **type-T `ERPL_REV` destination** in registration mode (`method='R'`) — created by `ZCL_ERPL_REV_SETUP`;\n- the **`ZERPL_REV` function group + FMs** (`Z_DUCKDB_*`) — created by `ZCL_ERPL_REV_MKFM`;\n- gateway registration allowed for the server's host — [`docs/enable-rfc-registration.md`](docs/enable-rfc-registration.md).\n\n### 4. Run the server\nRunning the **downloaded release binary** (or the Docker image) needs no setup —\njust `./erpl-rev-linux-amd64` with the `ERPL_REV_*` env below; the bundle\nself-extracts and sets its own loader path. The `LD_LIBRARY_PATH` line is **only**\nfor the from-source `build/erpl_rev_server`, whose libs live elsewhere in the tree:\n```bash\nexport LD_LIBRARY_PATH=$PWD/nwrfcsdk/linux/lib:$PWD/vendor/duckdb-1.5.3\nERPL_REV_GWHOST=\u003cgateway-host\u003e ERPL_REV_GWSERV=sapgw00 \\\nERPL_REV_DB_PATH=erpl-rev.duckdb \\\n  ./build/erpl_rev_server            # add --quack for the network server\n# convenience: `make run` (quack on), `make run-mem` (in-memory), or `make run-no-quack`\n```\nEasiest is **[`scripts/run-rfc-server.sh`](scripts/run-rfc-server.sh)**: it sets\n`LD_LIBRARY_PATH`, registers as `ERPL_REV`, and — opt-in via the environment —\nattaches **MotherDuck** (`motherduck_token`) and/or **BigQuery**\n(`ERPL_REV_BQ_PROJECT`). Pass `-r` to restart.\n\nTo publish to **external / cloud catalogs** (parquet, postgres, ducklake,\nbigquery, motherduck), give DuckDB boot SQL that runs `INSTALL`/`LOAD`/`ATTACH`\n(and `CREATE SECRET`) once on a global connection — via `--init-sql \"\u003csql\u003e\"`,\n`--init-file \u003cpath\u003e`, or the `ERPL_REV_DUCKDB_INIT` env var.\n\nFor production, run it as a **systemd service** ([`deploy/erpl-rev.service`](deploy/erpl-rev.service))\nor via **Docker** (image below).\n\n#### Run with Docker\n\nPrebuilt `linux/amd64` images are published to GitHub Container Registry:\n\n```bash\ndocker run -d --name erpl-rev \\\n  -e ERPL_REV_GWHOST=\u003cgateway-host\u003e -e ERPL_REV_GWSERV=sapgw00 \\\n  -e ERPL_REV_PROGRAM_ID=ERPL_REV \\\n  -v erpl-data:/data \\\n  ghcr.io/datazoode/erpl-rev:latest\n# add `--quack` (and `-p 9494:9494`) for the DuckDB network server\n```\n\nConfig is entirely via `ERPL_REV_*` env vars; the DuckDB file lives on the\n`/data` volume. RFC registration is **outbound** to the gateway, so no inbound\nport is needed — the gateway's `reginfo` ACL must allow `ERPL_REV_PROGRAM_ID`\nfrom the container's host. Add `--quack` and publish `-p 9494:9494` for the\nnetwork server; `docker run --rm ghcr.io/datazoode/erpl-rev:latest --smoke`\nchecks a pulled image loads with no gateway. See [`docs/docker.md`](docs/docker.md).\n\n### 5. Smoke test\n- `./build/erpl_rev_server --smoke` (or the bundled binary) — loads the SAP NW RFC\n  SDK + DuckDB and prints their versions; needs no gateway.\n- `Z_ERPL_REV_SQL` (`SE38`) → run `SELECT 42` to confirm the ABAP → server → DuckDB\n  round-trip (server must be running and registered).\n- Run `Z_ERPL_REV_REPLICATE` (`SE38`) on a small table and check row parity.\n\n---\n\n## Quick start\n\n**Query SAP data with SQL** — `Z_ERPL_REV_SQL` (`SE38`) opens a DuckDB SQL console\nin the SAP GUI: type any query (over replicated SAP data, cloud parquet, or\nattached catalogs) and get an ALV grid back; or call the query FM from ABAP and\nreceive typed rows. From an external DuckDB client (with `--quack`):\n```sql\nATTACH 'quack:host:9494' AS r (TOKEN '\u003ctoken\u003e');\nSELECT * FROM r.\u003ctable\u003e;            -- query the live in-process data\n```\n\n**Replicate a table** — `Z_ERPL_REV_REPLICATE` (`SE38`): pick the source (F4 to\nsearch the DDIC), optionally pick columns (F4) and a `WHERE`, choose a target; keys\nare auto-kept so re-runs dedup. For \u003e100M rows, tick *parallel* and run in\nbackground. Mirrors SLT's `LTRS` knobs — details below.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eReplicating SAP tables — the SLT-style detail\u003c/b\u003e\u003c/summary\u003e\n\n`Z_ERPL_REV_REPLICATE` maps to the three per-table controls of SAP SLT (`LTRS`):\n\n| SLT concept | Parameter | Behaviour |\n|---|---|---|\n| Table selection | `p_tab` | source SAP table / CDS view (F4 search). |\n| Field selection | `p_cols` | columns to replicate (blank = all); keys always kept. |\n| Filter (at source) | `p_where` | OpenSQL `WHERE`, applied in the SAP `SELECT` so non-matching rows never transfer. |\n| target / init / mode | `p_target` `p_init` `p_mode` `p_maxrow` `p_verify` | DuckDB table name; pre-SQL; `UPSERT`/`INSERT`; row cap; count-parity check. |\n\nReads are **package-wise** (keyset pagination, 50k/batch) so memory is bounded;\nfull-load-replace makes a crashed run safely re-runnable. The data-identity test\n(`zcl_erpl_rev_difftest`) compares target vs source cell-by-cell (SFLIGHT,\nZWIDE_BSEG, REPOSRC + a negative control). *Known limit:* the binary path drops\ntrailing zero bytes of fixed `RAW` columns. *Future:* delta/incremental loads.\n\u003c/details\u003e\n\n---\n\n## How it works\n\n```\nABAP ──CALL FUNCTION 'Z_DUCKDB_QUERY'/'Z_DUCKDB_INGEST' DESTINATION 'ERPL_REV'──►\n   SAP gateway (registered-server routing, RFCOPTIONS H=RFCSERVER)\n      └──► erpl_rev_server (C++) ──► DuckDbBridge ──► DuckDB (parquet / lakehouse)\n```\n\nA registered RFC server (`RfcCreateServer`/`RfcLaunchServer`) hosts a handful of\nfunction modules whose payloads are **JSON / binary-sXML over scalar `STRING`\nparams** — schema-generic, so no custom DDIC structures. It links the official\nprebuilt **DuckDB 1.5.3** (`libduckdb.so`, parquet+json+quack built in); our code\nplus libstdc++/libgcc are static, leaving only `libduckdb.so` and the SAP `.so`\ntrio dynamic.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eConfiguration (env vars \u0026 flags)\u003c/b\u003e\u003c/summary\u003e\n\n12-factor: config from the environment, logs to stderr, graceful `SIGINT`/`SIGTERM`.\nCLI flags override env (**flag \u003e env \u003e default**); `--help` prints the full surface.\n\n| Concern | Flag | Env var | Default |\n|---|---|---|---|\n| Gateway PROGRAM_ID | — | `ERPL_REV_PROGRAM_ID` | `ERPL_REV` |\n| Gateway host / service | — | `ERPL_REV_GWHOST` / `ERPL_REV_GWSERV` | `localhost` / `3300` |\n| Parallel registrations | — | `ERPL_REV_REG_COUNT` | `5` |\n| Enable quack | `--quack[=\u003clisten\u003e]` | `ERPL_REV_QUACK` | off |\n| Quack bind / token | `--quack-listen` / `--quack-token` | `ERPL_REV_QUACK_LISTEN` / `ERPL_REV_QUACK_TOKEN` | `quack:localhost` (port 9494) / random |\n| DuckDB file | `--db \u003cpath\u003e` | `ERPL_REV_DB_PATH` | `erpl-rev.duckdb` (`:memory:` for in-mem) |\n| Boot init SQL | `--init-sql` / `--init-file` | `ERPL_REV_DUCKDB_INIT` | — (ATTACH/secrets for external/cloud targets) |\n| Telemetry opt-out | `--no-telemetry` | `ERPL_REV_NO_TELEMETRY` / `DATAZOO_DISABLE_TELEMETRY` | on by default ([docs](docs/telemetry.md)) |\n| Self-check \u0026 exit | `--smoke` | — | — |\n| Logging | — | `ERPL_REV_LOG_{LEVEL,FORMAT,COLOR}` | `info` / `console` / `auto` |\n\nA file-backed `--db` makes ingested (and quack-served) data durable across\nrestarts. The quack token is a bearer credential — pin a high-entropy value via\n`--quack-token` (it's redacted from the log) and keep the listener on loopback\nunless you intend remote access.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eBuild internals \u0026 troubleshooting\u003c/b\u003e\u003c/summary\u003e\n\n- The build resolves the SDK from `nwrfcsdk/linux` (override `-DSAPNWRFC_HOME=…` /\n  `make build NWRFC_HOME=…`); Catch2 via **vcpkg** manifest mode (`VCPKG_ROOT`).\n- CI builds the server + runs tests on every push; it pulls the SDK from S3 via the\n  same GitHub-OIDC→AWS role as `erpl` (`scripts/download_and_extract_nwrfc.sh`).\n- **Registered destination must be `method='R'`** (`H=RFCSERVER`) — \"start\" mode\n  makes the gateway try to launch an executable and the call never reaches us.\n- **The FM interface must exist in the backend** or ABAP marshalling returns\n  `SYSTEM_FAILURE` — `ZCL_ERPL_REV_MKFM` creates them.\n- **Run with `LD_LIBRARY_PATH=$NWRFC_HOME/lib`** — `libsapnwrfc.so` `dlopen`s ICU by\n  name, so rpath alone is insufficient.\n\u003c/details\u003e\n\n---\n\n## Telemetry\n\nThe server sends **anonymous** usage telemetry (`application_start` /\n`application_stop` with app/version/platform/DuckDB-version only — **no SAP\ndata, query text, or table/field names**) to help us understand adoption. It is\n**on by default** and disabled by any one of `--no-telemetry`,\n`ERPL_REV_NO_TELEMETRY`, or `DATAZOO_DISABLE_TELEMETRY`. Air-gapped SAP hosts\ndrop the request silently with zero impact. Details: [`docs/telemetry.md`](docs/telemetry.md).\n\n## Docs\n\n- [`docs/delta.md`](docs/delta.md) — incremental extraction (watermark / change-doc / snapshot)\n- [`docs/INSTALL.md`](docs/INSTALL.md) — SAP transport import + server install + upgrade/uninstall\n- [`docs/enable-rfc-registration.md`](docs/enable-rfc-registration.md) — gateway registration / `reginfo`\n- [`docs/security.md`](docs/security.md) — Basis hardening, RFC user, SNC, ACLs\n- [`docs/sql-console.md`](docs/sql-console.md) — the in-GUI DuckDB SQL console\n- [`docs/telemetry.md`](docs/telemetry.md) — what's collected, where, and the three opt-outs\n- [`docs/docker.md`](docs/docker.md) — running the container image from ghcr.io\n\n## License\n\n[Business Source License 1.1](LICENSE) (BSL), Licensor **DataZoo GmbH**, Change\nLicense MPL 2.0 — same terms as [`erpl`](https://github.com/DataZooDE/erpl).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatazoode%2Ferpl-rev","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdatazoode%2Ferpl-rev","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdatazoode%2Ferpl-rev/lists"}