Files
openobserve/Cargo.toml
T
Huaijin 37e5f55684 feat(metrics): .midx series index for TSID-major files and PromQL pruning through it (#13899)
The query half of the TSID-major layout: #13882 wrote `tsid-major-v3-*`
files ordered by `(__hash__, _timestamp)`; this PR adds the `.midx`
series index next to them and makes PromQL prune through it. Supersedes
the remaining scope of #13839.

## Write side

- Every `tsid-major-v3-*` file written by the hour-end merge gets a
`.midx` series index (Arrow IPC + zstd), stored like the Tantivy index
under a derived root distinct from the data tree:
`files/{org}/metrics/{stream}/{date}/{hour}/tsid-major-v3-{id}.parquet`
→ `files/{org}/midx/{stream}/{date}/{hour}/tsid-major-v3-{id}.midx`
(Tantivy: `files/{org}/index/{stream}_{type}/…/{id}.ttv`): **one row per
contiguous TSID run** — its `row_count: u32` plus the label columns of
the run's first row (source types preserved). Runs tile the data file,
so each run's starting row is the prefix sum of the preceding counts and
is not stored; `__hash__` is excluded (matchers never reference it). The
whole index is one ZSTD-compressed IPC batch. Runs crossing an input
RecordBatch boundary appear as two adjacent entries; query-time range
coalescing makes that representation equivalent without buffering
samples. File and row-group boundaries stay independent of TSID
boundaries.
- `TsidSeriesIndexWriter` lives inside
`search/datafusion/merge/tsid_major.rs` and collects run entries
alongside the Parquet writer (one buffered row per run), encoding and
compressing once at finish. `MergedFile` carries `series_index:
Option<Vec<u8>>`; the compactor uploads it to the `midx/` tree
(compliance mode included).
- `.midx` is intentionally **not** tracked in `file_list`; its path is
derived from the data file's key
(`MetricsFileLayout::series_index_path`) and it is deleted together with
the parent in the delayed-deletion pass (`deleted.rs`); like the
`index/` tree, the `midx/` day directories are covered by retention's
local-disk deletion and the gc tool.

## Query side (PromQL)

- `promql_service::…::tsid_series_index::search` runs where Tantivy used
to, before the metrics table is registered: for each TSID-major file it
loads the `.midx` (concurrent, `2×target_partitions ≤ 64`), projects the
row-range columns plus the matched labels **by name against each series
index's own schema** (label sets / column orders differ between files),
builds the matcher filter **per series index** with
`physical_expr::create_physical_expr` — the exact same predicates as
`apply_matchers` (`matcher_predicates`) — evaluates it over the run
rows, coalesces adjacent/overlapping ranges and attaches them as
`FileSelection::RowRanges` (converted into a Parquet access plan by the
generic helper from #13861, no per-row bitmap).
- **Applied per file**: files of any other layout in the same query
(still-open hours, legacy data, late arrivals) are left in place and
scanned in full. A matched label missing from a series index
over-selects that file; a query whose matchers cannot be evaluated at
all selects the whole file; any series index failure logs and falls back
to a full scan. The final PromQL matchers are always applied, so results
are exact in every case.
- Evaluated selections are cached (LRU, 256 MiB) keyed by account +
series index path + the full matcher set.
- The Tantivy path in the PromQL storage scan is removed
(`convert_matchers_to_index_condition`, index-field plumbing,
`is_add_filter_back` bookkeeping). SQL search is untouched.

## Benchmark (from the #13839 POC, same layout + series index)

478,144,896 rows, 7 CPUs, one-hour PromQL range, step 15s, result cache
off, release + mimalloc:

| Layout | Filter steady median | No-filter steady median | Data files |
Total storage |
|---|---:|---:|---:|---:|
| main, 2 GiB | 695.709 ms | 4.638 s | 88 | 4,925.81 MiB |
| TSID-major + `.midx` | 269.496 ms | 2.793 s | 80 | 1,294.61 MiB |

## Validation

- `cargo fmt --check`; `cargo check` / `clippy` on config, search,
compaction, promql-service, jobs, search_service (`--tests`) clean
- `config tsid_layout` 3 passed (incl. `series_index_path`); `search
tsid_major mode:: merge::` 10 passed (rotation test now also asserts the
series index, exact-run and coalescing series index tests); `compaction
merge deleted` 33 passed; `promql-service` 20 passed + 1 pre-existing
wall-clock flake (`cache::test_promql_cache_set_and_get`, fails
intermittently on main too)
- End-to-end on the #13839 branch (same code paths): hour-end merge
writes N `tsid-major-v3-*` + `.midx`; PromQL takes the series index path
(`selected 39 ranges across 4/4 files`), counts/sums match the synthetic
data, cold-cache identical after restart; a mixed hour (3 major + 1 late
`tsid-sorted`) reports `1 files without a series index left to
tantivy/full scan` with unchanged results; delayed deletion removes
`.parquet` **and** `.midx`
2026-08-21 10:05:46 +00:00

668 lines
22 KiB
TOML

[package]
description = "OpenObserve is an observability platform that allows you to capture, search, and analyze your logs, metrics, and traces."
edition = "2024"
homepage = "https://openobserve.ai/"
keywords = [
"search",
"log",
"metrics",
"traces",
"analytics",
"openobserve",
"observability",
"open source",
"open-source",
"opensource",
]
license = "AGPL-3.0"
name = "openobserve"
repository = "https://github.com/openobserve/openobserve/"
version = "0.93.0"
publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[features]
default = []
enterprise = [
"audit/enterprise",
"openobserve-api-http/enterprise",
"openobserve-api-grpc/enterprise",
"openobserve-core/enterprise",
"openobserve-jobs/enterprise",
"super_cluster_queue/enterprise",
"search_service/enterprise",
"enrichment-data/enterprise",
"usage_reporting/enterprise",
]
vectorscan = [
"openobserve-api-http/vectorscan",
"openobserve-api-grpc/vectorscan",
"openobserve-core/vectorscan",
"openobserve-jobs/vectorscan",
"super_cluster_queue/vectorscan",
"search_service/vectorscan",
]
cloud = [
"openobserve-api-http/cloud",
"openobserve-api-grpc/cloud",
"openobserve-core/cloud",
"openobserve-jobs/cloud",
]
mimalloc = ["dep:mimalloc"]
jemalloc = ["dep:tikv-jemallocator"]
profiling = [
"jemalloc",
"openobserve-api-http/profiling",
"dep:tikv-jemalloc-ctl",
"dep:tikv-jemalloc-sys",
"dep:jemalloc_pprof",
"dep:pprof",
]
tokio-console = ["dep:console-subscriber"]
[profile.release]
debug = false
strip = true
codegen-units = 4
[profile.release-ci]
inherits = "release"
opt-level = 1
codegen-units = 16
debug = false
debug-assertions = true
strip = true
lto = false
incremental = false
[profile.release-prod]
inherits = "release"
codegen-units = 1
lto = "thin"
[profile.release-profiling]
inherits = "release"
debug = true
strip = false
# tikv-jemalloc-sys is a link-time dependency; prettytable-rs exposes the
# `prettytable` crate name, which cargo-machete does not associate with it.
[package.metadata.cargo-machete]
ignored = ["prettytable-rs", "tikv-jemalloc-sys"]
[dependencies]
axum.workspace = true
axum-extra.workspace = true
axum-server.workspace = true
axum-client-ip.workspace = true
tower.workspace = true
tower-http.workspace = true
http.workspace = true
http-body-util.workspace = true
ahash.workspace = true
anyhow.workspace = true
argon2.workspace = true
async-trait.workspace = true
async-recursion.workspace = true
aws-sdk-sns.workspace = true
base64.workspace = true
bitflags.workspace = true
bytes.workspace = true
byteorder.workspace = true
chrono.workspace = true
clap = { version = "4.5", default-features = false, features = [
"std",
"help",
"usage",
"suggestions",
"cargo",
] }
cron.workspace = true
csv.workspace = true
dashmap.workspace = true
datafusion.workspace = true
datafusion-proto.workspace = true
datafusion-functions-json.workspace = true
arrow.workspace = true
arrow-flight.workspace = true
arrow-json.workspace = true
arrow-schema.workspace = true
parquet.workspace = true
object_store.workspace = true
env_logger.workspace = true
faststr.workspace = true
flate2.workspace = true
futures.workspace = true
hashlink.workspace = true
hashbrown.workspace = true
hex.workspace = true
http-auth-basic.workspace = true
itertools.workspace = true
jsonwebtoken.workspace = true
log.workspace = true
maxminddb.workspace = true
md5.workspace = true
memchr.workspace = true
mimalloc = { version = "0.1.48", features = ["v3"], optional = true }
opentelemetry.workspace = true
opentelemetry_sdk.workspace = true
opentelemetry-otlp.workspace = true
opentelemetry-proto.workspace = true
parking_lot.workspace = true
prometheus.workspace = true
promql-parser.workspace = true
prost.workspace = true
prost-wkt-types.workspace = true
proto.workspace = true
prettytable-rs = "0.10.0"
rand.workspace = true
rayon.workspace = true
regex.workspace = true
regex-syntax.workspace = true
reqwest.workspace = true
rustls.workspace = true
rustls-native-certs.workspace = true
webpki-roots.workspace = true
sea-orm.workspace = true
segment.workspace = true
serde.workspace = true
serde_json.workspace = true
sha256.workspace = true
snafu.workspace = true
snap.workspace = true
sqlparser.workspace = true
sqlx.workspace = true
strum.workspace = true
svix-ksuid.workspace = true
thiserror.workspace = true
time.workspace = true
tikv-jemallocator = { version = "0.6", optional = true, features = [
"profiling",
"stats",
"unprefixed_malloc_on_supported_platforms",
] }
tikv-jemalloc-ctl = { workspace = true, optional = true }
tikv-jemalloc-sys = { workspace = true, optional = true }
jemalloc_pprof = { workspace = true, optional = true }
pprof = { workspace = true, optional = true }
tempfile.workspace = true
tiktoken-rs.workspace = true
tokio.workspace = true
console-subscriber = { version = "0.5", optional = true }
tonic.workspace = true
tonic-prost.workspace = true
tracing.workspace = true
tracing-appender.workspace = true
tracing-opentelemetry.workspace = true
tracing-subscriber.workspace = true
uaparser.workspace = true
url.workspace = true
utoipa.workspace = true
utoipa-swagger-ui.workspace = true
version-compare.workspace = true
x509-parser.workspace = true
zstd.workspace = true
config.workspace = true
infra.workspace = true
ingester.workspace = true
wal.workspace = true
report_server.workspace = true
chromiumoxide.workspace = true
lettre.workspace = true
tantivy.workspace = true
tantivy-fst.workspace = true
tantivy_utils.workspace = true
zip.workspace = true
futures-util.workspace = true
tokio-stream.workspace = true
mime.workspace = true
pin-project-lite.workspace = true
flight.workspace = true
async-stream.workspace = true
sourcemap.workspace = true
audit.workspace = true
openobserve-api-http.workspace = true
openobserve-api-grpc.workspace = true
openobserve-api-management.workspace = true
web.workspace = true
openobserve-api-common.workspace = true
openobserve-core.workspace = true
openobserve-node.workspace = true
ingestion-common.workspace = true
compaction.workspace = true
enrichment-data.workspace = true
common.workspace = true
db.workspace = true
search.workspace = true
search_service.workspace = true
super_cluster_queue.workspace = true
usage_reporting.workspace = true
openobserve-jobs.workspace = true
openobserve-mcp.workspace = true
[dev-dependencies]
arrow.workspace = true
bytes.workspace = true
enrichment-data.workspace = true
openobserve-api-pipelines.workspace = true
expect-test.workspace = true
base64.workspace = true
float-cmp.workspace = true
multer.workspace = true
prost.workspace = true
rcgen.workspace = true
schema.workspace = true
snap.workspace = true
tower.workspace = true
transform.workspace = true
[workspace]
members = [
"src/api/http",
"src/api/grpc",
"src/api/ingest",
"src/api/management",
"src/api/pipelines",
"src/api/search",
"src/api/common",
"src/ingestion_common",
"src/schema",
"src/compaction",
"src/stream",
"src/enrichment_data",
"src/builtins",
"src/org_storage",
"src/sourcemaps",
"src/tls",
"src/common",
"src/core",
"src/node",
"src/transform",
"src/super_cluster_queue",
"src/synthetics",
"src/search",
"src/cipher",
"src/db",
"src/search_service",
"src/usage_reporting",
"src/audit",
"src/promql",
"src/metrics_index",
"src/promql_service",
"src/jobs",
"src/mcp",
"src/config",
"src/infra",
"src/ingester",
"src/wal",
"src/proto",
"src/report_server",
"src/flight",
"src/tantivy_utils",
"src/web",
]
resolver = "2"
[workspace.package]
version = "0.1.0"
edition = "2024"
license = "AGPL-3.0"
[workspace.dependencies]
pulldown-cmark = { version = "0.13", default-features = false, features = [
"html",
] }
config = { path = "src/config" }
infra = { path = "src/infra" }
ingester = { path = "src/ingester" }
wal = { path = "src/wal" }
proto = { path = "src/proto" }
report_server = { path = "src/report_server" }
flight = { path = "src/flight" }
tantivy_utils = { path = "src/tantivy_utils" }
ingestion-common = { path = "src/ingestion_common" }
schema = { path = "src/schema" }
compaction = { path = "src/compaction" }
stream = { path = "src/stream" }
enrichment-data = { path = "src/enrichment_data" }
openobserve-builtins = { path = "src/builtins" }
openobserve-org-storage = { path = "src/org_storage" }
openobserve-sourcemaps = { path = "src/sourcemaps" }
openobserve-tls = { path = "src/tls" }
web = { path = "src/web" }
openobserve-core = { path = "src/core" }
openobserve-node = { path = "src/node" }
common = { path = "src/common" }
transform = { path = "src/transform" }
super_cluster_queue = { path = "src/super_cluster_queue" }
# Deliberately NOT a dependency of super_cluster_queue — see src/synthetics/src/lib.rs.
openobserve-synthetics = { path = "src/synthetics" }
search = { path = "src/search" }
openobserve-cipher = { path = "src/cipher" }
db = { path = "src/db" }
search_service = { path = "src/search_service" }
usage_reporting = { path = "src/usage_reporting" }
audit = { path = "src/audit" }
promql = { path = "src/promql" }
metrics_index = { path = "src/metrics_index" }
promql-service = { path = "src/promql_service" }
openobserve-api-common = { path = "src/api/common" }
openobserve-api-grpc = { path = "src/api/grpc" }
openobserve-api-http = { path = "src/api/http" }
openobserve-api-ingest = { path = "src/api/ingest" }
openobserve-api-management = { path = "src/api/management" }
openobserve-api-pipelines = { path = "src/api/pipelines" }
openobserve-api-search = { path = "src/api/search" }
openobserve-jobs = { path = "src/jobs" }
openobserve-mcp = { path = "src/mcp" }
o2_dex = { path = "src/enterprise/o2_dex" }
o2_enterprise = { path = "src/enterprise/o2_enterprise", default-features = false }
o2_openfga = { path = "src/enterprise/o2_openfga" }
o2_ratelimit = { path = "src/enterprise/o2_ratelimit" }
vortex = { git = "https://github.com/openobserve/vortex", rev = "1cb48912c14d9c7bd29832d9aff5666d730e1f0e", features = [
"tokio",
] }
vortex-btrblocks = { git = "https://github.com/openobserve/vortex", rev = "1cb48912c14d9c7bd29832d9aff5666d730e1f0e" }
vortex-datafusion = { git = "https://github.com/openobserve/vortex", rev = "1cb48912c14d9c7bd29832d9aff5666d730e1f0e" }
aes-siv = "0.7.0"
ahash = { version = "0.8", features = ["serde"] }
axum = { version = "0.8", features = ["macros", "multipart", "tracing"] }
axum-extra = { version = "0.12", features = [
"typed-header",
"query",
"cookie",
] }
axum-server = { version = "0.8", features = ["tls-rustls"] }
axum-client-ip = "1.3"
async-fs = "2.2"
bitflags = "2.11"
csv = "1.3"
float-cmp = "0.10"
futures-util = "0.3.31"
http-auth-basic = "0.3"
jemalloc_pprof = { version = "0.8", features = ["symbolize", "flamegraph"] }
jsonwebtoken = { version = "10.3", features = ["aws_lc_rs"] }
maxminddb = "0.27"
mime = "0.3.17"
mime_guess = "2.0"
multer = "3.1"
pprof = { version = "0.15", features = ["flamegraph", "protobuf-codec"] }
promql-parser = { version = "0.6", git = "https://github.com/openobserve/promql-parser", branch = "openobserve" }
rcgen = "0.14.4"
rmcp-openapi = { version = "0.23.2", git = "https://github.com/openobserve/rmcp-openapi", branch = "v0.23.2-feat" }
rust-embed-for-web = "11.4.1"
sourcemap = "9.3.2"
tikv-jemalloc-ctl = { version = "0.6", features = [
"use_std",
"stats",
"profiling",
] }
tikv-jemalloc-sys = { version = "0.6", features = ["profiling"] }
tower = { version = "0.5", features = ["full"] }
tower-http = { version = "0.6", features = [
"cors",
"compression-gzip",
"compression-br",
"compression-deflate",
"decompression-gzip",
"decompression-br",
"decompression-deflate",
"decompression-zstd",
"trace",
"timeout",
"request-id",
"util",
] }
http = "1.4"
http-body = "1.0"
http-body-util = "0.1"
hyper = { version = "1.8", features = ["full"] }
hyper-util = { version = "0.1", features = [
"tokio",
"server",
"http1",
"http2",
] }
anyhow = "1.0"
arc-swap = "1.8"
argon2 = { version = "0.5", features = ["alloc", "password-hash"] }
async-nats = "0.47"
async-stream = "0.3"
async-trait = "0.1"
async-recursion = "1.0"
aws-config = "1.8"
aws-credential-types = "1.2.14"
aws-sdk-lambda = { version = "1", default-features = false, features = [
"behavior-version-latest",
"default-https-client",
"rt-tokio",
] }
aws-sdk-sns = { version = "1.97", default-features = false, features = [
"behavior-version-latest",
"default-https-client",
"rt-tokio",
] }
base64 = "0.22"
bytes = "1.11"
byteorder = "1.5"
chromiumoxide = { git = "https://github.com/mattsse/chromiumoxide", features = [
"tokio-runtime",
"_fetcher-rusttls-tokio",
], default-features = false, rev = "6f2392f78ae851e2acf33df8e9764cc299d837db" }
chrono = { version = "0.4", default-features = false, features = ["clock"] }
chrono-tz = "0.10"
cityhasher = { version = "0.1", default-features = false }
collapse = "0.1.2"
cron = "0.15"
dashmap = { version = "6.1", features = ["serde"] }
datafusion = "54"
datafusion-proto = "54"
datafusion-functions-aggregate-common = "54"
datafusion-functions-json = { git = "https://github.com/openobserve/datafusion-functions-json", rev = "0df53d710425cc91cf109e77a050bbe1e374e4fe" }
expect-test = "1.4"
arrow = { version = "58", features = ["ipc_compression", "prettyprint"] }
arrow-flight = "58"
arrow-json = "58"
arrow-schema = { version = "58", features = ["serde"] }
parquet = { version = "58", features = ["arrow", "async", "object_store"] }
object_store = { version = "0.13.2", features = ["aws", "azure", "gcp"] }
sqlparser = { version = "0.62", features = ["serde", "visitor"] }
dotenv_config = "0.2"
dotenvy = "0.15"
env_logger = "0.11"
fastdivide = "0.4"
faststr = { version = "0.2", features = ["serde"] }
flate2 = { version = "1.0", features = ["zlib"] }
futures = "0.3"
local-ip-address = "0.6"
hashlink = "0.11"
hashbrown = { version = "0.16", features = ["serde"] }
hex = "0.4"
hmac = "0.12"
image = { version = "0.24", default-features = false, features = ["png"] }
indexmap = { version = "2.8", features = ["serde"] }
itertools = "0.14"
lettre = { version = "0.11", default-features = false, features = [
"builder",
"hostname",
"smtp-transport",
"pool",
"tokio1",
"tokio1-rustls-tls",
"aws-lc-rs",
] }
log = "0.4"
md5 = "0.8.0"
memchr = "2.7"
murmur3 = "0.5"
ordered-float = { version = "5.1.0", features = ["serde"] }
opentelemetry = "0.32"
opentelemetry_sdk = { version = "0.32", features = [
"experimental_trace_batch_span_processor_with_async_runtime",
"rt-tokio",
"trace",
"metrics",
"spec_unstable_metrics_views",
] }
opentelemetry-otlp = { version = "0.32", features = [
"http-proto",
"serialize",
"serde",
"trace",
"reqwest-client",
"grpc-tonic",
] }
opentelemetry-proto = { version = "0.32", features = [
"gen-tonic",
"with-serde",
"logs",
"metrics",
"trace",
] }
parking_lot = "0.12"
pin-project-lite = "0.2.16"
plotters = { version = "0.3.7", default-features = false, features = [
"bitmap_backend",
"ab_glyph",
"area_series",
"line_series",
"point_series",
] }
prometheus = { version = "0.14", features = ["process"] }
prost = "0.14"
prost-wkt-types = "0.7"
rand = "0.10"
rayon = "1.10"
regex = "1.11"
regex-syntax = "0.8"
reqwest = { version = "0.13", default-features = false, features = [
"rustls",
"stream",
"gzip",
"brotli",
"deflate",
"json",
"query",
"form",
"multipart",
] }
rquickjs = { version = "0.11.0", features = ["array-buffer", "classes"] }
rustls = { version = "0.23", default-features = false, features = [
"std",
"tls12",
] }
rustls-native-certs = "0.8"
uaparser = "0.6.4"
version-compare = "0.2.0"
webpki-roots = "1.0"
sea-orm = { version = "1.1.20", features = [
"sqlx-postgres",
"sqlx-sqlite",
"runtime-tokio-rustls",
"macros",
] }
sea-orm-migration = { version = "1.1.20", features = [
"sqlx-postgres",
"sqlx-sqlite",
"runtime-tokio-rustls",
] }
segment = "~0.2.4"
serde = { version = "1", features = ["derive"] }
serde_json = { version = "1", features = ["arbitrary_precision"] }
sha1 = "0.10.6"
sha2 = "0.10"
sha256 = "1.6"
snafu = "0.9"
snap = "1"
sqlx = { version = "0.8.6", features = [
"runtime-tokio-rustls",
"postgres",
"sqlite",
"chrono",
] }
strum = { version = "0.28", features = ["derive"] }
svix-ksuid = { version = "0.8", features = ["serde"] }
sysinfo = "0.38"
tantivy = { version = "0.26", features = ["quickwit"] }
tantivy-fst = "0.5"
tempfile = "3"
thiserror = "2.0"
tiktoken-rs = "0.9.1"
time = "0.3"
tokio = { version = "1", features = ["full"] }
tokio-rustls = { version = "0.26", default-features = false, features = [
"logging",
"tls12",
] }
tokio-util = { version = "0.7", features = ["compat"] }
tokio-stream = "0.1"
tonic = { version = "0.14", features = [
"gzip",
"zstd",
"tls-webpki-roots",
"tls-native-roots",
] }
tonic-prost = "0.14"
tracing = "0.1.44"
tracing-appender = "0.2.4"
tracing-log = "0.2"
tracing-opentelemetry = "0.33"
tracing-subscriber = { version = "0.3.22", features = [
"env-filter",
"json",
"registry",
] }
url = "2.5"
urlencoding = "2.1"
utoipa = { version = "5.4", features = ["axum_extras", "openapi_extensions"] }
utoipa-axum = "0.2"
utoipa-swagger-ui = { version = "9", features = ["axum", "vendored"] }
uuid = { version = "1.20", features = ["v7"] }
vector-enrichment = { version = "0.1.0", package = "enrichment", git = "https://github.com/openobserve/vector", branch = "branch-v0.54" }
vrl = { version = "0.31", features = [
"arbitrary",
"value",
"compiler",
"test",
] }
x509-parser = "0.18.0"
zip = "8.0"
zstd = "0.13"
[patch.crates-io]
datafusion = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-catalog = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-catalog-listing = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-common = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-common-runtime = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-datasource = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-datasource-arrow = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-datasource-csv = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-datasource-json = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-datasource-parquet = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-doc = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-execution = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-expr = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-expr-common = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions-aggregate = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions-aggregate-common = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions-nested = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions-table = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions-window = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-functions-window-common = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-macros = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-optimizer = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-physical-expr = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-physical-expr-adapter = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-physical-expr-common = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-physical-optimizer = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-physical-plan = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-proto = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-proto-common = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-pruning = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-session = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
datafusion-sql = { git = "https://github.com/openobserve/datafusion", rev = "869ec1a70482e1a26c4ac2fde3e9fd5545c33d7b" }
object_store = { git = "https://github.com/openobserve/arrow-rs-object-store", branch = "openobserve-v0.13.2" }
tantivy = { git = "https://github.com/openobserve/tantivy", branch = "perf/openobserve" }