Skip to content

[Analytics] Vendor the liquid-cache library crates - #22569

Open
cocosz wants to merge 2 commits into
opensearch-project:mainfrom
cocosz:liquid-cache-plugin
Open

[Analytics] Vendor the liquid-cache library crates#22569
cocosz wants to merge 2 commits into
opensearch-project:mainfrom
cocosz:liquid-cache-plugin

Conversation

@cocosz

@cocosz cocosz commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

Description

Vendors the liquid-cache library as a self-contained Cargo workspace under sandbox/plugins/liquid-cache/src/main/rust:

  • opensearch-liquid-cache-core — the in-memory decoded-batch cache.
  • opensearch-liquid-cache-datafusion — the DataFusion parquet reader that serves from / populates the cache.

These crates build and unit-test on their own and are not yet wired into the engine. The analytics backend compiles them in only when built with the liquid_cache cargo feature introduced in the parent PR, which the follow-up integration PR enables.

Kept as its own PR so the vendored library can be reviewed in isolation, separate from the seam and from the engine/Java wiring.

This is PR 2 of a 3-part stack:

  1. Seam ([Analytics] Add optional liquid cache seam for indexed parquet scans (cargo feature) #22553): feature-gated in-process hook (no-op by default).
  2. This PR — library: vendors the liquid-cache crates in isolation.
  3. Integration ([Analytics] Wire liquid cache into the analytics engine (plugin + integration) #22595): wires the library into the engine + Java plugin + integration test.

Changes

  • 53 files under sandbox/plugins/liquid-cache/src/main/rust (the two crates + workspace Cargo.toml, Cargo.lock, rust-toolchain.toml).
  • sandbox/plugins/liquid-cache/.gitignore.

54 files changed, +12,433. No build.gradle is added, so the Gradle build ignores the directory and the crates stay dormant until the integration PR wires them in.

Check List

Note: PRs target main. Stacked on #22553 — review/merge order: #22553 → this PR → #22595.

@cocosz
cocosz requested a review from a team as a code owner July 26, 2026 22:34
@github-actions

github-actions Bot commented Jul 26, 2026

Copy link
Copy Markdown
Contributor

PR Code Analyzer ❗

AI-powered 'Code-Diff-Analyzer' found issues on commit eb9aff4.

Hard block: Issues at Medium severity or above will block this PR from merging.

PathLineSeverityDescription
sandbox/plugins/analytics-backend-datafusion/rust/Cargo.toml0highMANDATORY DEPENDENCY FLAG: New external crate 'base64 = "0.22"' added. Base64 encoding has no apparent role in a Parquet in-memory cache layer; its presence is anomalous and warrants verification — base64 is a common primitive in credential harvesting and data exfiltration payloads. Maintainers must verify this dependency is actually used and for what purpose.
sandbox/plugins/liquid-cache/src/main/rust/Cargo.toml0highMANDATORY DEPENDENCY FLAG: New Cargo workspace introduces 13+ external crates including arrow=58.3.0, parquet=58.3.0, datafusion=54.0.0, tokio=1.52.3, object_store=0.13.2, serde=1.0.228, ahash=0.8.12, congee=0.4.1, fastlanes=0.5.2, tempfile=3.27.0 and others. Each crate is an independent supply chain trust decision. Artifact authenticity cannot be verified from diff alone.
sandbox/plugins/liquid-cache/src/main/rust/Cargo.toml0highMANDATORY DEPENDENCY FLAG: 'congee = "0.4.1"' is a low-profile ART (Adaptive Radix Tree) index crate with limited ecosystem visibility. Obscure crates with small maintainer bases carry elevated namespace hijacking and typosquatting risk. Verify crate owner identity and audit published artifact against source.
sandbox/plugins/liquid-cache/src/main/rust/Cargo.toml0highMANDATORY DEPENDENCY FLAG: 'fastlanes = "0.5.2"' is a niche SIMD bit-packing compression crate. Low-profile crates are disproportionately targeted in supply chain attacks. Verify crate provenance and published artifact integrity independently.
sandbox/plugins/liquid-cache/src/main/rust/datafusion/src/reader/plantime/row_filter.rs0mediumUnsafe std::mem::transmute reinterprets a &parquet::arrow::ProjectionMask as a locally-defined mirror struct ProjectionMaskLiquid to read private fields. If the upstream struct layout ever diverges (padding, field reordering, version bump) this produces undefined behavior and arbitrary memory reads. In an adversarial context this pattern can be used to craft a read gadget targeting adjacent heap memory. The technique bypasses the intentional API boundary of the parquet crate.
sandbox/plugins/liquid-cache/src/main/rust/datafusion/src/utils.rs0mediumExtensive unsafe raw pointer arithmetic in the BMI2 PDEP fast-path: manual pointer-width reads/writes without bounds checking under #[target_feature(enable="bmi2")]. A logic error or deliberate miscalculation in stride/offset arithmetic yields out-of-bounds reads or writes into the Arrow buffer heap, potentially leaking adjacent decoded column data across tenant queries in a multi-tenant deployment.
sandbox/plugins/liquid-cache/src/main/rust/core/Cargo.toml1mediumProvenance comment names an external unreviewed fork: 'https://github.com/cocosz/liquid-cache branch lc-opensearch-df54-v2 commit 8311bccc258756127adbebee3e54140b60fc09ba'. The vendored code originates from a personal GitHub fork, not an upstream release artifact. The named commit has not been verified against any published release. This is a supply chain insertion point — the fork could contain modifications absent from any public audit trail.
sandbox/libs/dataformat-native/build.gradle0mediumFeature is silently activated by environment variable LIQUID_CACHE=1 in addition to the declared build property. An attacker with ability to inject environment variables into the build or runtime environment (CI/CD pipeline compromise, container escape) can activate this code path without any source-visible configuration change. Hidden activation vectors are a hallmark of logic bomb deployment.
sandbox/plugins/liquid-cache/src/main/rust/datafusion/src/source.rs0lowProcess-global cache state is held in a LazyLock (and similar static). In a JVM-embedded native plugin this means cache contents survive across logical request boundaries for the lifetime of the JVM process. A poisoned or unexpectedly large cache entry affects all subsequent queries globally with no isolation boundary.
sandbox/plugins/liquid-cache/src/main/rust/datafusion/src/source.rs0lowCache population is offloaded via tokio::spawn background tasks that are never awaited. Errors from background fills are silently dropped. In an adversarial scenario, a crafted input that triggers fill failures repeatedly could cause cache starvation while masking the root cause, or background tasks could accumulate unboundedly under high query load (resource exhaustion).

The table above displays the top 10 most important findings.

Total: 10 | Critical: 0 | High: 4 | Medium: 4 | Low: 2


Pull Requests Author(s): Please update your Pull Request according to the report above.

Repository Maintainer(s): You can bypass diff analyzer by adding label skip-diff-analyzer after reviewing the changes carefully, then re-run failed actions. To re-enable the analyzer, remove the label, then re-run all actions.


⚠️ Note: The Code-Diff-Analyzer helps protect against potentially harmful code patterns. Please ensure you have thoroughly reviewed the changes beforehand.

Thanks.

@cocosz
cocosz force-pushed the liquid-cache-plugin branch 13 times, most recently from 3ee183e to 747eb4a Compare July 28, 2026 23:49
@cocosz
cocosz force-pushed the liquid-cache-plugin branch from 747eb4a to b0c598c Compare July 28, 2026 23:58
@cocosz cocosz changed the title Add liquid cache as a standalone OpenSearch plugin [Analytics] Vendor the liquid-cache library crates Jul 29, 2026
@cocosz
cocosz force-pushed the liquid-cache-plugin branch 6 times, most recently from 1622170 to 14023d0 Compare July 29, 2026 00:59
Tanvir Alam added 2 commits July 29, 2026 06:33
Adds an opt-in, in-memory decoded-batch cache (liquid cache) for the
DataFusion analytics backend, wired behind a cargo feature so it is
absent from the default build.

When the `liquid_cache` feature is off (the default), the integration is
an inlined no-op: eligible scans use the plain ParquetSource unchanged.
When on, an eligible indexed row-group scan — all projected columns
numeric/date/timestamp/boolean, within a column budget, and no string or
binary predicate column — is wrapped with LiquidParquetSource so decoded
batches are served from and populated into the process-global cache.

Enabling is a single-file edit plus a build flag: the liquid cache
dependency is a commented placeholder in the analytics-backend-datafusion
crate (uncomment it, set the git repo/branch, and uncomment the matching
`dep:` feature entries), then build with -PliquidCache (or LIQUID_CACHE=1).
The default build declares no liquid cache source, so it resolves and
compiles exactly as before.

Signed-off-by: Tanvir Alam <tanvralm@amazon.com>
Adds the in-memory decoded-batch cache (opensearch-liquid-cache-core) and its DataFusion parquet reader (opensearch-liquid-cache-datafusion) as a self-contained Cargo workspace under sandbox/plugins/liquid-cache/src/main/rust.

These crates build and unit-test on their own and are not yet wired into the engine; the analytics backend compiles them in only when built with the liquid_cache cargo feature, which a follow-up change enables. Kept as its own PR so the vendored library can be reviewed in isolation.

Signed-off-by: Tanvir Alam <tanvralm@amazon.com>
@cocosz
cocosz force-pushed the liquid-cache-plugin branch from 14023d0 to eb9aff4 Compare July 29, 2026 01:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant