diff --git a/.cargo/config b/.cargo/config new file mode 100644 index 00000000000..a16ed45ce85 --- /dev/null +++ b/.cargo/config @@ -0,0 +1,25 @@ +[build] +# enable tokio-console and some other goodies +rustflags = [ + "--cfg", "tokio_unstable", +] + +# sparse protocol opt-in +# See https://blog.rust-lang.org/2023/03/09/Rust-1.68.0.html#cargos-sparse-protocol +[registries.crates-io] +protocol = "sparse" + +[target.x86_64-unknown-linux-gnu] +rustflags = [ + # see above + "--cfg", "tokio_unstable", + # Faster linker. + "-C", "link-arg=-fuse-ld=lld", + # Fix `perf` as suggested by https://github.com/flamegraph-rs/flamegraph/blob/2d19a162df4066f37d58d5471634f0bd9f0f4a62/README.md?plain=1#L18 + # Also see https://bugs.chromium.org/p/chromium/issues/detail?id=919499#c16 + "-C", "link-arg=-Wl,--no-rosegment", + # Enable all features supported by CPUs more recent than haswell (2013) + "-C", "target-cpu=haswell", + # Enable framepointers because profiling and debugging is a nightmare w/o it and it is generally not considered a performance advantage on modern x86_64 CPUs. + "-C", "force-frame-pointers=yes", +] diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000000..b8597819b24 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,284 @@ +--- +# CI Overview +# ----------- +# +# Every commit: +# +# The CI for every PR and merge to main runs tests, fmt, lints and compiles debug binaries +# +# On main if all these checks pass it will then additionally compile in "release" mode and +# publish a docker image to quay.io/influxdb/influxdb3:$COMMIT_SHA +# +# Manually trigger build and push of container image for a branch: +# +# Navigate to https://app.circleci.com/pipelines/github/influxdata/influxdb?branch= (<- change this!) +# Then: +# +# - Click "Run Pipeline" in the top-right +# - Expand "Add Parameters" +# - Add a "boolean" parameter called "release_branch" with the value true +# - Click "Run Pipeline" +# +# You can also do this using the CircleCI API: +# +# Using `xh`: +# +# # e.g. using 'xh' (https://github.com/ducaale/xh) +# $ xh -a ':' POST \ +# https://circleci.com/api/v2/project/github/influxdata/influxdb/pipeline \ +# parameters:='{"release_branch": true}' branch=chore/ci-tidy-up +# +# ...or equivalent with `curl`: +# $ curl -XPOST -H "Content-Type: application/json" -H "Circle-Token: " \ +# -d '{"parameters": {"release_branch": true}, "branch": "chore/ci-tidy-up"}' \ +# https://circleci.com/api/v2/project/github/influxdata/influxdb/pipeline + +version: 2.1 + +commands: + rust_components: + description: Verify installed components + steps: + - run: + name: Verify installed components + command: | + rustup --version + rustup show + cargo fmt --version + cargo clippy --version + + login_to_gcloud: + steps: + - run: + name: Login to gcloud + command: | + echo "${GCLOUD_SERVICE_ACCOUNT_KEY}" >/tmp/gcloud.json + gcloud auth activate-service-account "${GCLOUD_SERVICE_ACCOUNT_EMAIL}" --key-file /tmp/gcloud.json --quiet + rm -f /tmp/gcloud.json + gcloud auth configure-docker us-docker.pkg.dev + +jobs: + fmt: + docker: + - image: quay.io/influxdb/rust:ci + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + steps: + - checkout + - rust_components + - run: + name: Rust fmt + command: cargo fmt --all -- --check + lint: + docker: + - image: quay.io/influxdb/rust:ci + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + steps: + - checkout + - rust_components + - run: + name: Clippy + command: cargo clippy --all-targets --all-features --workspace -- -D warnings + - run: + name: Yamllint + command: yamllint --config-file .circleci/yamllint.yml --strict . + cargo_audit: + docker: + - image: quay.io/influxdb/rust:ci + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + steps: + - checkout + - rust_components + - run: + name: Install cargo-deny + command: cargo install cargo-deny --locked + - run: + name: cargo-deny Checks + command: cargo deny check -s + doc: + docker: + - image: quay.io/influxdb/rust:ci + resource_class: large # use of a smaller executor runs out of memory + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + # Turn warnings into errors + RUSTDOCFLAGS: "-D warnings -A rustdoc::private-intra-doc-links" + steps: + - checkout + - rust_components + - run: + name: Cargo doc + command: cargo doc --document-private-items --no-deps --workspace + - run: + name: Compress Docs + command: tar -cvzf rustdoc.tar.gz target/doc/ + - store_artifacts: + path: rustdoc.tar.gz + + # Run all tests + test: + docker: + - image: quay.io/influxdb/rust:ci + resource_class: 2xlarge+ # use of a smaller executor tends crashes on link + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + RUST_BACKTRACE: "1" + steps: + - checkout + - rust_components + - run: + name: cargo test --workspace + command: cargo test --workspace + + # end to end tests with Heappy (heap profiling enabled) + test_heappy: + docker: + - image: quay.io/influxdb/rust:ci + resource_class: xlarge # use of a smaller executor tends crashes on link + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + RUST_BACKTRACE: "1" + steps: + - checkout + - rust_components + - run: + name: cargo test --no-default-features --features=heappy --workspace + command: cargo test --no-default-features --features=heappy --workspace + + # Build a dev binary. + # + # Compiles a binary with the default ("dev") cargo profile from the influxdb3 source + # using the latest ci_image (influxdb/rust) and ensures various targets compile successfully + build_dev: + docker: + - image: quay.io/influxdb/rust:ci + resource_class: 2xlarge # use of a smaller executor tends crashes on link + environment: + # Disable incremental compilation to avoid overhead. We are not preserving these files anyway. + CARGO_INCREMENTAL: "0" + # Disable full debug symbol generation to speed up CI build + # "1" means line tables only, which is useful for panic tracebacks. + CARGO_PROFILE_DEV_DEBUG: "1" + # https://github.com/rust-lang/cargo/issues/10280 + CARGO_NET_GIT_FETCH_WITH_CLI: "true" + # The `2xlarge` resource class that we use has 32GB RAM but also 16 CPUs. This means we have 2GB RAM per core on + # avarage. At peak this is a bit tight, so lower the CPU count for cargo a bit. + CARGO_BUILD_JOBS: "12" + steps: + - checkout + - rust_components + - run: + name: Cargo build + command: cargo build --workspace + - run: + name: Check benches compile + command: cargo check --workspace --benches + - run: + name: Check extra features (like prod image) + command: cargo check --no-default-features --features="aws,gcp,azure,jemalloc_replacing_malloc,tokio_console,pprof" + + # Compile cargo "release" profile binaries for influxdb3 & data generator + # + # Uses the latest ci_image (influxdb/rust) to build a release binary and + # copies it to a minimal container image based upon `rust:slim-buster`. This + # minimal image is then pushed to `quay.io/influxdb/influxdb3:${BRANCH}`. + build_release: + # need a machine executor to have a full-powered docker daemon (the `setup_remote_docker` system just provides a + # kinda small node) + machine: + image: default + resource_class: 2xlarge # CPU bound, so make it fast + steps: + - checkout + - run: + name: Cargo release build + command: | + COMMIT_SHA="$(git rev-parse HEAD)" + + .circleci/docker_build_release.bash \ + "influxdb3" \ + "aws,gcp,azure,jemalloc_replacing_malloc,tokio_console,pprof" \ + "quay.io/influxdb/influxdb3:$COMMIT_SHA" + + mkdir /tmp/images + docker save quay.io/influxdb/influxdb3:"$COMMIT_SHA" | gzip > /tmp/images/influxdb3.tar.gz + # linking might take a while and doesn't produce CLI output + no_output_timeout: 30m + - store_artifacts: + path: /tmp/images + - persist_to_workspace: + root: /tmp/images + paths: + - "*.tar.gz" + +parameters: + release_branch: + description: "Build and push container image for non-main branch" + type: boolean + default: false + +workflows: + version: 2 + + # CI for all pull requests. + ci: + when: + and: + - not: << pipeline.parameters.release_branch >> + jobs: + - fmt + - lint + - cargo_audit + - test + - test_heappy + - build_dev + - doc + - build_release: + filters: + branches: + only: main + + # Force build and push of container image for non-main branch. + # See instructions at the top of this file + release_branch: + when: << pipeline.parameters.release_branch >> + jobs: + - build_release diff --git a/.circleci/docker_build_release.bash b/.circleci/docker_build_release.bash new file mode 100755 index 00000000000..70c5e32fe84 --- /dev/null +++ b/.circleci/docker_build_release.bash @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -euo pipefail + +readonly PACKAGE="$1" +readonly FEATURES="$2" +readonly TAG="$3" + +RUST_VERSION="$(sed -E -ne 's/channel = "(.*)"/\1/p' rust-toolchain.toml)" +COMMIT_SHA="$(git rev-parse HEAD)" +COMMIT_TS="$(env TZ=UTC0 git show --quiet --date='format-local:%Y-%m-%dT%H:%M:%SZ' --format="%cd" HEAD)" +NOW="$(date --utc --iso-8601=seconds)" +REPO_URL="https://github.com/influxdata/influxdb_iox" + +exec docker buildx build \ + --build-arg CARGO_INCREMENTAL="no" \ + --build-arg CARGO_NET_GIT_FETCH_WITH_CLI="true" \ + --build-arg FEATURES="$FEATURES" \ + --build-arg RUST_VERSION="$RUST_VERSION" \ + --build-arg PACKAGE="$PACKAGE" \ + --label org.opencontainers.image.created="$NOW" \ + --label org.opencontainers.image.url="$REPO_URL" \ + --label org.opencontainers.image.revision="$COMMIT_SHA" \ + --label org.opencontainers.image.vendor="InfluxData Inc." \ + --label org.opencontainers.image.title="InfluxDB IOx, '$PACKAGE'" \ + --label org.opencontainers.image.description="InfluxDB IOx production image for package '$PACKAGE'" \ + --label com.influxdata.image.commit-date="$COMMIT_TS" \ + --label com.influxdata.image.package="$PACKAGE" \ + --progress plain \ + --tag "$TAG" \ + . diff --git a/.circleci/yamllint.yml b/.circleci/yamllint.yml new file mode 100644 index 00000000000..b32765b6d79 --- /dev/null +++ b/.circleci/yamllint.yml @@ -0,0 +1,3 @@ +rules: + truthy: + check-keys: false diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000000..c755c6fb398 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,13 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space + +[{Dockerfile*,*.proto}] +indent_size = 2 + +[{*.rs,*.toml,*.sh,*.bash}] +indent_size = 4 diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000000..0248cc6d2dc --- /dev/null +++ b/.gitattributes @@ -0,0 +1,4 @@ +generated_types/protos/google/ linguist-generated=true +generated_types/protos/grpc/ linguist-generated=true +generated_types/src/wal_generated.rs linguist-generated=true +trace_exporters/src/thrift/ linguist-generated=true diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 00000000000..edda9ebc12c --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,5 @@ +# This file allows teams or people to be assigned as +# automatic code-reviewers for files or directories. +# +# Here is information about how to configure this file: +# https://help.github.com/en/articles/about-code-owners diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 00000000000..5f95d77e1cd --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,50 @@ +--- +name: Bug report +about: Create a report to help us improve +--- + + + +__Steps to reproduce:__ +List the minimal actions needed to reproduce the behaviour. + +1. ... +2. ... +3. ... + +__Expected behaviour:__ +Describe what you expected to happen. + +__Actual behaviour:__ +Describe What actually happened. + +__Environment info:__ + +* Please provide the command you used to build the project, including any `RUSTFLAGS`. +* System info: Run `uname -srm` or similar and copy the output here (we want to know your OS, architecture etc). +* If you're running IOx in a containerised environment then details about that would be helpful. +* Other relevant environment details: disk info, hardware setup etc. + +__Config:__ +Copy any non-default config values here or attach the full config as a gist or file. + + + +__Logs:__ +Include snippet of errors in logs or stack traces here. +Sometimes you can get useful information by running the program with the `RUST_BACKTRACE=full` environment variable. +Finally, the IOx server has a `-vv` for verbose logging. diff --git a/.github/ISSUE_TEMPLATE/developer_experience.md b/.github/ISSUE_TEMPLATE/developer_experience.md new file mode 100644 index 00000000000..987ad619c8e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/developer_experience.md @@ -0,0 +1,99 @@ +--- +name: Developer experience problem +about: Tell us about slow builds, tests, and code editing +--- + + + +## Describe Development Experience Issue: + + + +### Steps to reproduce: + + + +1. ... +2. ... +3. ... +4. ... + +### Desired result: + + + +### Actual result: + + +## Hardware Environment: + + + +- Package: ... +- CPU: ... +- Memory: ... +- Block Device: ... + +## Operating System: + + + +## Code Editing Tool: + + + +## Build Environment: + +[ ] I'm using sccache + + diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 00000000000..08617fa8f4e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,31 @@ +--- +name: Feature request +about: Opening a feature request kicks off a discussion +--- + + +__Use case:__ +Why is this important (helps with prioritizing requests)? + +__Proposal:__ +Short summary of the feature. + +__Current behaviour:__ +Describe what currently happens. + +__Desired behaviour:__ +Describe what you want. + +__Alternatives considered:__ +Describe other solutions or features you considered. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000000..ec003d26881 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,6 @@ +Closes # + +Describe your proposed changes here. + +- [ ] I've read the contributing section of the project [README](https://github.com/influxdata/influxdb/blob/main/README.md). +- [ ] Signed [CLA](https://influxdata.com/community/cla/) (if not already signed). diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..b99dabf6154 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,22 @@ +# Configuration for https://probot.github.io/apps/stale/ +# +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 90 +# Number of days of inactivity before a stale issue is closed +daysUntilClose: 7 +# Issues with these labels will never be considered stale +exemptLabels: + - security + - stale-exempt +# Label to use when marking an issue as stale +staleLabel: wontfix +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. It will be closed if no further activity occurs. Thank you + for your contributions. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: > + This issue has been automatically closed because it has not had + recent activity. Please reopen if this issue is still + important to you. Thank you for your contributions. diff --git a/.github/workflows/semantic.yml b/.github/workflows/semantic.yml new file mode 100644 index 00000000000..5fbae6dc995 --- /dev/null +++ b/.github/workflows/semantic.yml @@ -0,0 +1,10 @@ +--- +name: "Semantic PR and Commit Messages" + +on: + pull_request: + types: [opened, reopened, synchronize, edited] + +jobs: + semantic: + uses: influxdata/validate-semantic-github-messages/.github/workflows/semantic.yml@main diff --git a/.gitignore b/.gitignore index 6985cf1bd09..16724a53a35 100644 --- a/.gitignore +++ b/.gitignore @@ -1,14 +1,20 @@ -# Generated by Cargo -# will have compiled files and executables -debug/ -target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt **/*.rs.bk - -# MSVC Windows builds of rustc generate these, which store debugging information +**/*.rs.bk +**/.DS_Store +**/.vscode +**/target *.pdb +*.pending-snap +*.tsm +.env +.gdb_history +.idea/ +Cargo.lock +debug/ +heaptrack.* +massif.out.* +perf.data* +perf.svg +perf.txt +results/ +valgrind-out.txt diff --git a/.kodiak.toml b/.kodiak.toml new file mode 100644 index 00000000000..f96092d0482 --- /dev/null +++ b/.kodiak.toml @@ -0,0 +1,2 @@ +version = 1 +merge.method = "squash" diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000000..f296fe1fc5a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,200 @@ +# Contributing + +Thank you for thinking of contributing! We very much welcome contributions from the community. +To make the process easier and more valuable for everyone involved we have a few rules and guidelines to follow. + +Anyone with a Github account is free to file issues on the project. +However, if you want to contribute documentation or code then you will need to sign InfluxData's Individual Contributor License Agreement (CLA), which can be found with more information [on our website]. + +[on our website]: https://www.influxdata.com/legal/cla/ + +## Submitting Issues and Feature Requests + +Before you file an [issue], please search existing issues in case the same or similar issues have already been filed. +If you find an existing open ticket covering your issue then please avoid adding "đź‘Ť" or "me too" comments; Github notifications can cause a lot of noise for the project maintainers who triage the back-log. +However, if you have a new piece of information for an existing ticket and you think it may help the investigation or resolution, then please do add it as a comment! +You can signal to the team that you're experiencing an existing issue with one of Github's emoji reactions (these are a good way to add "weight" to an issue from a prioritisation perspective). + +### Submitting an Issue + +The [New Issue] page has templates for both bug reports and feature requests. +Please fill one of them out! +The issue templates provide details on what information we will find useful to help us fix an issue. +In short though, the more information you can provide us about your environment and what behaviour you're seeing, the easier we can fix the issue. +If you can push a PR with test cases that trigger a defect or bug, even better! +P.S, if you have never written a bug report before, or if you want to brush up on your bug reporting skills, we recommend reading Simon Tatham's essay [How to Report Bugs Effectively]. + +As well as bug reports we also welcome feature requests (there is a dedicated issue template for these). +Typically, the maintainers will periodically review community feature requests and make decisions about if we want to add them. +For features we don't plan to support we will close the feature request ticket (so, again, please check closed tickets for feature requests before submitting them). + +[issue]: https://github.com/influxdata/influxdb/issues/new +[New Issue]: https://github.com/influxdata/influxdb/issues/new +[How to Report Bugs Effectively]: https://www.chiark.greenend.org.uk/~sgtatham/bugs.html + +## Contributing Changes + +InfluxDB IOx is written mostly in idiomatic Rust—please see the [Style Guide] for more details. +All code must adhere to the `rustfmt` format, and pass all of the `clippy` checks we run in CI (there are more details further down this README). + +[Style Guide]: docs/style_guide.md + +### Finding Issues To Work On + +The [good first issue](https://github.com/influxdata/influxdb/issues?q=is%3Aopen+is%3Aissue+label%3Agood-first-issue) and the [help wanted](https://github.com/influxdata/influxdb/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted) labels are used to identify issues where we encourage community contributions. +They both indicate issues for which we would welcome independent community contributions, but the former indicates a sub-set of these that are especially good for first-time contributors. +If you want some clarifications or guidance for working on one of these issues, or you simply want to let others know that you're working on one, please leave a comment on the ticket. + +[good first issue]: https://github.com/influxdata/influxdb/issues?q=is%3Aopen+is%3Aissue+label%3Agood-first-issue +[help wanted]: https://github.com/influxdata/influxdb/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted + +### Bigger Changes + +If you're planning to submit significant changes, even if it relates to existing tickets **please** talk to the project maintainers first! +The easiest way to do this is to open up a new ticket, describing the changes you plan to make and *why* you plan to make them. Changes that may seem obviously good to you, are not always obvious to everyone else. +Example of changes where we would encourage up-front communication: + +* new IOx features; +* significant refactors that move code between modules/crates etc; +* performance improvements involving new concurrency patterns or the use of `unsafe` code; +* API-breaking changes, or changes that require a data migration; +* any changes that risk the durability or correctness of data. + +We are always excited to have community involvement but we can't accept everything. +To avoid having your hard work rejected the best approach to start a discussion first. +Further, please don't expect us to accept significant changes without new test coverage, and/or in the case of performance changes benchmarks that show the improvements. + +### Making a PR + +To open a PR you will need to have a Github account. +Fork the `influxdb` repo and work on a branch on your fork. +When you have completed your changes, or you want some incremental feedback make a Pull Request to InfluxDB IOx [here]. + +If you want to discuss some work in progress then please prefix `[WIP]` to the +PR title. + +For PRs that you consider ready for review, verify the following locally before you submit it: + +* you have a coherent set of logical commits, with messages conforming to the [Conventional Commits] specification; +* all the tests and/or benchmarks pass, including documentation tests; +* the code is correctly formatted and all `clippy` checks pass; and +* you haven't left any "code cruft" (commented out code blocks etc). + +There are some tips on verifying the above in the [next section](#running-tests). + +**After** submitting a PR, you should: + +* verify that all CI status checks pass and the PR is đź’š; +* ask for help on the PR if any of the status checks are đź”´, and you don't know why; +* wait patiently for one of the team to review your PR, which could take a few days. + +[here]: https://github.com/influxdata/influxdb/compare +[Conventional Commits]: https://www.conventionalcommits.org/en/v1.0.0/ + +## Running Tests + +The `cargo` build tool runs tests as well. Run: + +```shell +cargo test --workspace +``` + +### Enabling logging in tests + +To enable logging to stderr during a run of `cargo test` set the Rust +`RUST_LOG` environment variable. For example, to see all INFO messages: + +```shell +RUST_LOG=info cargo test --workspace +``` + +Since this feature uses +[`EnvFilter`](https://docs.rs/tracing-subscriber/0.2.15/tracing_subscriber/filter/struct.EnvFilter.html) internally, you +can use all the features of that crate. For example, to disable the +(somewhat noisy) logs in some h2 modules, you can use a value of +`RUST_LOG` such as: + +```shell +RUST_LOG=debug,hyper::proto::h1=info,h2=info cargo test --workspace +``` + +See [logging.md](docs/logging.md) for more information on logging. + +### End-to-End Tests + +There are end-to-end tests that spin up a server and make requests via the client library and API. They can be found in `tests/end_to_end_cases` + +These require additional setup as described in [testing.md](docs/testing.md). + +### Visually showing explain plans + +Some query plans are output in the log in [graphviz](https://graphviz.org/) format. To display them you can use the `tools/iplan` helper. + +For example, if you want to display this plan: + +``` +// Begin DataFusion GraphViz Plan (see https://graphviz.org) +digraph { + subgraph cluster_1 + { + graph[label="LogicalPlan"] + 2[shape=box label="SchemaPivot"] + 3[shape=box label="Projection: "] + 2 -> 3 [arrowhead=none, arrowtail=normal, dir=back] + 4[shape=box label="Filter: Int64(0) LtEq #time And #time Lt Int64(10000) And #host Eq Utf8(_server01_)"] + 3 -> 4 [arrowhead=none, arrowtail=normal, dir=back] + 5[shape=box label="TableScan: attributes projection=None"] + 4 -> 5 [arrowhead=none, arrowtail=normal, dir=back] + } + subgraph cluster_6 + { + graph[label="Detailed LogicalPlan"] + 7[shape=box label="SchemaPivot\nSchema: [non_null_column:Utf8]"] + 8[shape=box label="Projection: \nSchema: []"] + 7 -> 8 [arrowhead=none, arrowtail=normal, dir=back] + 9[shape=box label="Filter: Int64(0) LtEq #time And #time Lt Int64(10000) And #host Eq Utf8(_server01_)\nSchema: [color:Utf8;N, time:Int64]"] + 8 -> 9 [arrowhead=none, arrowtail=normal, dir=back] + 10[shape=box label="TableScan: attributes projection=None\nSchema: [color:Utf8;N, time:Int64]"] + 9 -> 10 [arrowhead=none, arrowtail=normal, dir=back] + } +} +// End DataFusion GraphViz Plan +``` + +You can pipe it to `iplan` and render as a .pdf + + +## Running `rustfmt` and `clippy` + +CI will check the code formatting with [`rustfmt`] and Rust best practices with [`clippy`]. + +To automatically format your code according to `rustfmt` style, first make sure `rustfmt` is installed using `rustup`: + +```shell +rustup component add rustfmt +``` + +Then, whenever you make a change and want to reformat, run: + +```shell +cargo fmt --all +``` + +Similarly with `clippy`, install with: + +```shell +rustup component add clippy +``` + +And run with: + +```shell +cargo clippy --all-targets --workspace -- -D warnings +``` + +[`rustfmt`]: https://github.com/rust-lang/rustfmt +[`clippy`]: https://github.com/rust-lang/rust-clippy + +## Distributed Tracing + +See [tracing.md](docs/tracing.md) for more information on the distributed tracing functionality within IOx diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 00000000000..96c53a9c0e0 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,6994 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "ahash" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" +dependencies = [ + "cfg-if", + "const-random", + "getrandom", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "allocator-api2" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c6cb57a04249c6480766f7f7cef5467412af1490f8d1e243141daddada3264f" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" + +[[package]] +name = "arc-swap" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "arrow" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa285343fba4d829d49985bdc541e3789cf6000ed0e84be7c039438df4a4e78c" +dependencies = [ + "arrow-arith 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-array", + "arrow-buffer", + "arrow-cast 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-csv", + "arrow-data", + "arrow-ipc", + "arrow-json", + "arrow-ord 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-row 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-schema", + "arrow-select 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-string 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "arrow-arith" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "753abd0a5290c1bcade7c6623a556f7d1659c5f4148b140b5b63ce7bd1a45705" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "num", +] + +[[package]] +name = "arrow-arith" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "num", +] + +[[package]] +name = "arrow-array" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "ahash", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "chrono", + "chrono-tz", + "half", + "hashbrown 0.14.3", + "num", +] + +[[package]] +name = "arrow-buffer" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "bytes", + "half", + "num", +] + +[[package]] +name = "arrow-cast" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e448e5dd2f4113bf5b74a1f26531708f5edcacc77335b7066f9398f4bcf4cdef" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.21.7", + "chrono", + "comfy-table", + "half", + "lexical-core", + "num", +] + +[[package]] +name = "arrow-cast" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "base64 0.21.7", + "chrono", + "half", + "lexical-core", + "num", +] + +[[package]] +name = "arrow-csv" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46af72211f0712612f5b18325530b9ad1bfbdc87290d5fbfd32a7da128983781" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-data", + "arrow-schema", + "chrono", + "csv", + "csv-core", + "lazy_static", + "lexical-core", + "regex", +] + +[[package]] +name = "arrow-data" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-buffer", + "arrow-schema", + "half", + "num", +] + +[[package]] +name = "arrow-flight" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-arith 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "arrow-array", + "arrow-buffer", + "arrow-cast 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "arrow-data", + "arrow-ipc", + "arrow-ord 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "arrow-row 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "arrow-schema", + "arrow-select 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "arrow-string 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "base64 0.21.7", + "bytes", + "futures", + "once_cell", + "paste", + "prost 0.12.4", + "tokio", + "tonic 0.10.2", +] + +[[package]] +name = "arrow-ipc" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "arrow-data", + "arrow-schema", + "flatbuffers", + "lz4_flex", +] + +[[package]] +name = "arrow-json" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8950719280397a47d37ac01492e3506a8a724b3fb81001900b866637a829ee0f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-cast 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-data", + "arrow-schema", + "chrono", + "half", + "indexmap 2.2.6", + "lexical-core", + "num", + "serde", + "serde_json", +] + +[[package]] +name = "arrow-ord" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ed9630979034077982d8e74a942b7ac228f33dd93a93b615b4d02ad60c260be" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "half", + "num", +] + +[[package]] +name = "arrow-ord" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "half", + "num", +] + +[[package]] +name = "arrow-row" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007035e17ae09c4e8993e4cb8b5b96edf0afb927cd38e2dff27189b274d83dcf" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "half", + "hashbrown 0.14.3", +] + +[[package]] +name = "arrow-row" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "half", + "hashbrown 0.14.3", +] + +[[package]] +name = "arrow-schema" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" + +[[package]] +name = "arrow-select" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce20973c1912de6514348e064829e50947e35977bb9d7fb637dc99ea9ffd78c" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "num", +] + +[[package]] +name = "arrow-select" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "num", +] + +[[package]] +name = "arrow-string" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00f3b37f2aeece31a2636d1b037dabb69ef590e03bdc7eb68519b51ec86932a7" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "num", + "regex", + "regex-syntax 0.8.3", +] + +[[package]] +name = "arrow-string" +version = "50.0.0" +source = "git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0#e8ead57e97ed2edae8a5617ef45946d8d5b1d91f" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "arrow-select 50.0.0 (git+https://github.com/erratic-pattern/arrow-rs.git?branch=50.0.0)", + "num", + "regex", + "regex-syntax 0.8.3", +] + +[[package]] +name = "arrow_util" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "ahash", + "arrow", + "chrono", + "comfy-table", + "hashbrown 0.14.3", + "num-traits", + "once_cell", + "regex", + "snafu 0.8.2", + "uuid", + "workspace-hack", +] + +[[package]] +name = "assert-json-diff" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "assert_cmd" +version = "2.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed72493ac66d5804837f480ab3766c72bdfab91a65e565fc54fa9e42db0073a8" +dependencies = [ + "anstyle", + "bstr", + "doc-comment", + "predicates", + "predicates-core", + "predicates-tree", + "wait-timeout", +] + +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + +[[package]] +name = "async-channel" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d4d23bcc79e27423727b36823d86233aad06dfea531837b038394d11e9928" +dependencies = [ + "concurrent-queue", + "event-listener 5.3.0", + "event-listener-strategy 0.5.1", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-compression" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07dbbf24db18d609b1462965249abdf49129ccad073ec257da372adc83259c60" +dependencies = [ + "bzip2", + "flate2", + "futures-core", + "futures-io", + "memchr", + "pin-project-lite", + "tokio", + "xz2", + "zstd", + "zstd-safe", +] + +[[package]] +name = "async-lock" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d034b430882f8381900d3fe6f0aaa3ad94f2cb4ac519b429692a1bc2dda4ae7b" +dependencies = [ + "event-listener 4.0.3", + "event-listener-strategy 0.4.0", + "pin-project-lite", +] + +[[package]] +name = "async-stream" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" +dependencies = [ + "async-stream-impl", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "async-trait" +version = "0.1.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + +[[package]] +name = "authz" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "backoff 0.1.0", + "base64 0.22.0", + "generated_types", + "http", + "iox_time", + "metric", + "observability_deps", + "snafu 0.8.2", + "tonic 0.10.2", + "workspace-hack", +] + +[[package]] +name = "autocfg" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1fdabc7756949593fe60f30ec81974b613357de856987752631dea1e3394c80" + +[[package]] +name = "axum" +version = "0.6.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" +dependencies = [ + "async-trait", + "axum-core", + "bitflags 1.3.2", + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "sync_wrapper", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "axum-core" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "759fa577a247914fd3f7f76d62972792636412fbfd634cd452f6a385a74d2d2c" +dependencies = [ + "async-trait", + "bytes", + "futures-util", + "http", + "http-body", + "mime", + "rustversion", + "tower-layer", + "tower-service", +] + +[[package]] +name = "backoff" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "observability_deps", + "rand", + "snafu 0.8.2", + "tokio", + "workspace-hack", +] + +[[package]] +name = "backoff" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" +dependencies = [ + "getrandom", + "instant", + "rand", +] + +[[package]] +name = "backtrace" +version = "0.3.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b05800d2e817c8b3b4b54abd461726265fa9789ae34330622f2db9ee696f9d" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9475866fec1451be56a3c2400fd081ff546538961565ccb5b7142cbd22bc7a51" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" +dependencies = [ + "serde", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake3" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30cca6d3674597c30ddf2c587bf8d9d65c9a84d2326d941cc79c9842dfe0ef52" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brotli" +version = "3.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d640d25bc63c50fb1f0b545ffd80207d2e10a4c965530809b40ba3386825c391" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e2e4afe60d7dd600fdd3de8d0f08c2b7ec039712e3b6137ff98b7004e82de4f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "bstr" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05efc5cfd9110c8416e471df0e96702d58690178e206e61b7173706673c93706" +dependencies = [ + "memchr", + "regex-automata 0.4.6", + "serde", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytemuck" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d6d68c57235a3a081186990eca2867354726650f42f7516ca50c28d6281fd15" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4da9a32f3fed317401fa3c862968128267c3106685286e15d5aaa3d7389c2f60" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" + +[[package]] +name = "bzip2" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8" +dependencies = [ + "bzip2-sys", + "libc", +] + +[[package]] +name = "bzip2-sys" +version = "0.1.11+1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "catalog_cache" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "bytes", + "dashmap", + "futures", + "hyper", + "metric", + "observability_deps", + "reqwest", + "snafu 0.8.2", + "tokio", + "tokio-util", + "url", + "workspace-hack", +] + +[[package]] +name = "cc" +version = "1.0.95" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32a725bc159af97c3e629873bb9f88fb8cf8a4867175f76dc987815ea07c83b" +dependencies = [ + "jobserver", + "libc", + "once_cell", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.5", +] + +[[package]] +name = "chrono-tz" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59ae0466b83e838b81a54256c39d5d7c20b9d7daa10510a242d9b75abd5936e" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", +] + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_blocks" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "clap", + "ed25519-dalek", + "futures", + "http", + "humantime", + "iox_catalog", + "iox_time", + "itertools 0.12.1", + "metric", + "non-empty-string", + "object_store", + "observability_deps", + "parquet_cache", + "snafu 0.8.2", + "sysinfo", + "trace_exporters", + "trogging", + "url", + "uuid", + "workspace-hack", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim 0.11.1", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "client_util" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "http", + "reqwest", + "thiserror", + "tonic 0.10.2", + "tower", + "workspace-hack", +] + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "comfy-table" +version = "7.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b34115915337defe99b2aff5c2ce6771e5fbc4079f4b506301f5cf394c8452f7" +dependencies = [ + "strum", + "strum_macros", + "unicode-width", +] + +[[package]] +name = "concurrent-queue" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "console" +version = "0.15.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e1f83fc076bd6dd27517eacdf25fef6c4dfe5f1d7448bafaaf3a26f13b5e4eb" +dependencies = [ + "encode_unicode", + "lazy_static", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "console-api" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2895653b4d9f1538a83970077cb01dfc77a4810524e51a110944688e916b18e" +dependencies = [ + "prost 0.11.9", + "prost-types 0.11.9", + "tonic 0.9.2", + "tracing-core", +] + +[[package]] +name = "console-subscriber" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4cf42660ac07fcebed809cfe561dd8730bcd35b075215e6479c516bcd0d11cb" +dependencies = [ + "console-api", + "crossbeam-channel", + "crossbeam-utils", + "futures", + "hdrhistogram", + "humantime", + "parking_lot", + "prost-types 0.11.9", + "serde", + "serde_json", + "thread_local", + "tokio", + "tokio-stream", + "tonic 0.9.2", + "tracing", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "const-random" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359" +dependencies = [ + "const-random-macro", +] + +[[package]] +name = "const-random-macro" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e" +dependencies = [ + "getrandom", + "once_cell", + "tiny-keccak", +] + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cpp_demangle" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8227005286ec39567949b33df9896bcadfa6051bccca2488129f108ca23119" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "croaring" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7266f0a7275b00ce4c4f4753e8c31afdefe93828101ece83a06e2ddab1dd1010" +dependencies = [ + "byteorder", + "croaring-sys", +] + +[[package]] +name = "croaring-sys" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e47112498c394a7067949ebc07ef429b7384a413cf0efcf675846a47bcd307fb" +dependencies = [ + "cc", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab3db02a9c5b5121e1e42fbdb1aeb65f5e02624cc58c43f2884c6ccac0b82f95" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "csv" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac574ff4d437a7b5ad237ef331c17ccca63c46479e5b5453eb8e10bb99a759fe" +dependencies = [ + "csv-core", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "csv-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5efa2b3d7902f4b634a20cae3c9c4e6209dc4779feb6863329607560143efa70" +dependencies = [ + "memchr", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a677b8922c94e01bdbb12126b0bc852f00447528dee1782229af9c720c3f348" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "darling" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.60", +] + +[[package]] +name = "darling_macro" +version = "0.20.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core", +] + +[[package]] +name = "data_types" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow-buffer", + "bytes", + "chrono", + "croaring", + "generated_types", + "influxdb-line-protocol", + "iox_time", + "murmur3", + "observability_deps", + "once_cell", + "ordered-float 4.2.0", + "percent-encoding", + "prost 0.12.4", + "schema", + "serde_json", + "sha2", + "siphasher 1.0.1", + "snafu 0.8.2", + "sqlx", + "thiserror", + "uuid", + "workspace-hack", +] + +[[package]] +name = "datafusion" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "ahash", + "arrow", + "arrow-array", + "arrow-ipc", + "arrow-schema", + "async-compression", + "async-trait", + "bytes", + "bzip2", + "chrono", + "dashmap", + "datafusion-common", + "datafusion-common-runtime", + "datafusion-execution", + "datafusion-expr", + "datafusion-functions", + "datafusion-functions-array", + "datafusion-optimizer", + "datafusion-physical-expr", + "datafusion-physical-plan", + "datafusion-sql", + "flate2", + "futures", + "glob", + "half", + "hashbrown 0.14.3", + "indexmap 2.2.6", + "itertools 0.12.1", + "log", + "num_cpus", + "object_store", + "parking_lot", + "parquet", + "pin-project-lite", + "rand", + "sqlparser", + "tempfile", + "tokio", + "tokio-util", + "url", + "uuid", + "xz2", + "zstd", +] + +[[package]] +name = "datafusion-common" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "ahash", + "arrow", + "arrow-array", + "arrow-buffer", + "arrow-schema", + "chrono", + "half", + "instant", + "libc", + "num_cpus", + "object_store", + "parquet", + "sqlparser", +] + +[[package]] +name = "datafusion-common-runtime" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "tokio", +] + +[[package]] +name = "datafusion-execution" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "arrow", + "chrono", + "dashmap", + "datafusion-common", + "datafusion-expr", + "futures", + "hashbrown 0.14.3", + "log", + "object_store", + "parking_lot", + "rand", + "tempfile", + "url", +] + +[[package]] +name = "datafusion-expr" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "ahash", + "arrow", + "arrow-array", + "chrono", + "datafusion-common", + "paste", + "sqlparser", + "strum", + "strum_macros", +] + +[[package]] +name = "datafusion-functions" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "arrow", + "arrow-array", + "base64 0.22.0", + "chrono", + "datafusion-common", + "datafusion-execution", + "datafusion-expr", + "datafusion-physical-expr", + "hex", + "itertools 0.12.1", + "log", + "regex", +] + +[[package]] +name = "datafusion-functions-array" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "arrow", + "datafusion-common", + "datafusion-execution", + "datafusion-expr", + "log", + "paste", +] + +[[package]] +name = "datafusion-optimizer" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "arrow", + "async-trait", + "chrono", + "datafusion-common", + "datafusion-expr", + "datafusion-physical-expr", + "hashbrown 0.14.3", + "itertools 0.12.1", + "log", + "regex-syntax 0.8.3", +] + +[[package]] +name = "datafusion-physical-expr" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "ahash", + "arrow", + "arrow-array", + "arrow-buffer", + "arrow-ord 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-schema", + "arrow-string 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.22.0", + "blake2", + "blake3", + "chrono", + "datafusion-common", + "datafusion-execution", + "datafusion-expr", + "half", + "hashbrown 0.14.3", + "hex", + "indexmap 2.2.6", + "itertools 0.12.1", + "log", + "md-5", + "paste", + "petgraph", + "rand", + "regex", + "sha2", + "unicode-segmentation", + "uuid", +] + +[[package]] +name = "datafusion-physical-plan" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "ahash", + "arrow", + "arrow-array", + "arrow-buffer", + "arrow-schema", + "async-trait", + "chrono", + "datafusion-common", + "datafusion-common-runtime", + "datafusion-execution", + "datafusion-expr", + "datafusion-physical-expr", + "futures", + "half", + "hashbrown 0.14.3", + "indexmap 2.2.6", + "itertools 0.12.1", + "log", + "once_cell", + "parking_lot", + "pin-project-lite", + "rand", + "tokio", + "uuid", +] + +[[package]] +name = "datafusion-proto" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "arrow", + "chrono", + "datafusion", + "datafusion-common", + "datafusion-expr", + "object_store", + "prost 0.12.4", +] + +[[package]] +name = "datafusion-sql" +version = "36.0.0" +source = "git+https://github.com/influxdata/arrow-datafusion.git?rev=581e74785b876615d6a63db8c2e5ba372bf78828#581e74785b876615d6a63db8c2e5ba372bf78828" +dependencies = [ + "arrow", + "arrow-schema", + "datafusion-common", + "datafusion-expr", + "log", + "sqlparser", +] + +[[package]] +name = "datafusion_util" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "datafusion", + "futures", + "object_store", + "observability_deps", + "pin-project", + "schema", + "tokio", + "tokio-stream", + "url", + "workspace-hack", +] + +[[package]] +name = "debugid" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d" +dependencies = [ + "uuid", +] + +[[package]] +name = "delegate" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "082a24a9967533dc5d743c602157637116fc1b52806d694a5a45e6f32567fcdd" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "difflib" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dml" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow_util", + "data_types", + "hashbrown 0.14.3", + "mutable_batch", + "schema", + "trace", + "workspace-hack", +] + +[[package]] +name = "doc-comment" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dyn-clone" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6ef0072f8a535281e4876be788938b528e9a1d43900b82c2569af7da799125" + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47c1c47d2f5964e29c61246e81db715514cd532db6b5116a25ea3c03d6780a2" +dependencies = [ + "serde", +] + +[[package]] +name = "encode_unicode" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" + +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys 0.48.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b215c49b2b248c855fb73579eb1f4f26c38ffdc12973e20e07b91d78d5646e" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d9944b8ca13534cdfb2800775f8dd4902ff3fc75a50101466decadfdf322a24" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +dependencies = [ + "event-listener 4.0.3", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332f51cb23d20b0de8458b86580878211da09bcd4503cb579c225b3d124cabb3" +dependencies = [ + "event-listener 5.3.0", + "pin-project-lite", +] + +[[package]] +name = "executor" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "futures", + "libc", + "metric", + "observability_deps", + "once_cell", + "parking_lot", + "pin-project", + "snafu 0.8.2", + "tokio", + "tokio-util", + "tokio_metrics_bridge", + "tokio_watchdog", + "workspace-hack", +] + +[[package]] +name = "fastrand" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" + +[[package]] +name = "fiat-crypto" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38793c55593b33412e3ae40c2c9781ffaa6f438f6f8c10f24e71846fbd7ae01e" + +[[package]] +name = "filetime" +version = "0.2.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "windows-sys 0.52.0", +] + +[[package]] +name = "findshlibs" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40b9e59cd0f7e0806cca4be089683ecb6434e602038df21fe6bf6711b2f07f64" +dependencies = [ + "cc", + "lazy_static", + "libc", + "winapi", +] + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "fixedbitset" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" + +[[package]] +name = "flatbuffers" +version = "23.5.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dac53e22462d78c16d64a1cd22371b54cc3fe94aa15e7886a2fa6e5d1ab8640" +dependencies = [ + "bitflags 1.3.2", + "rustc_version", +] + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flightsql" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "arrow-flight", + "arrow_util", + "bytes", + "datafusion", + "futures", + "generated_types", + "iox_query", + "iox_query_params", + "observability_deps", + "once_cell", + "prost 0.12.4", + "snafu 0.8.2", + "tonic 0.10.2", + "workspace-hack", +] + +[[package]] +name = "flume" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" +dependencies = [ + "futures-core", + "futures-sink", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generated_types" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "observability_deps", + "once_cell", + "pbjson", + "pbjson-build", + "pbjson-types", + "prost 0.12.4", + "prost-build", + "prost-types 0.12.4", + "serde", + "tonic 0.10.2", + "tonic-build", + "uuid", + "workspace-hack", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94b22e06ecb0110981051723910cbf0b5f5e09a2062dd7663334ee79a9d1286c" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "h2" +version = "0.3.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.6", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dd08c532ae367adf81c312a4580bc67f1d0fe8bc9c460520283f4c0ff277888" +dependencies = [ + "bytemuck", + "cfg-if", + "crunchy", + "num-traits", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "hdrhistogram" +version = "7.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "765c9198f173dd59ce26ff9f95ef0aafd0a0fe01fb9d72841bc5066a4c06511d" +dependencies = [ + "base64 0.21.7", + "byteorder", + "flate2", + "nom", + "num-traits", +] + +[[package]] +name = "heappy" +version = "0.1.0" +source = "git+https://github.com/mkmik/heappy?rev=01a1f88e1b404c5894f89eb1a57f813f713d7ad1#01a1f88e1b404c5894f89eb1a57f813f713d7ad1" +dependencies = [ + "backtrace", + "bytes", + "lazy_static", + "libc", + "pprof", + "spin 0.9.8", + "thiserror", + "tikv-jemalloc-sys", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "http-range-header" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "log", + "rustls", + "rustls-native-certs", + "tokio", + "tokio-rustls", +] + +[[package]] +name = "hyper-timeout" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" +dependencies = [ + "hyper", + "pin-project-lite", + "tokio", + "tokio-io-timeout", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", +] + +[[package]] +name = "indexmap" +version = "2.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inferno" +version = "0.11.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "321f0f839cd44a4686e9504b0a62b4d69a50b62072144c71c68f5873c167b8d9" +dependencies = [ + "ahash", + "indexmap 2.2.6", + "is-terminal", + "itoa", + "log", + "num-format", + "once_cell", + "quick-xml 0.26.0", + "rgb", + "str_stack", +] + +[[package]] +name = "influxdb-line-protocol" +version = "1.0.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "bytes", + "log", + "nom", + "smallvec", + "snafu 0.8.2", +] + +[[package]] +name = "influxdb3" +version = "0.1.0" +dependencies = [ + "arrow", + "arrow-array", + "arrow-flight", + "arrow_util", + "assert_cmd", + "authz", + "backtrace", + "base64 0.22.0", + "clap", + "clap_blocks", + "console-subscriber", + "datafusion_util", + "dotenvy", + "futures", + "hex", + "hyper", + "influxdb3_client", + "influxdb3_process", + "influxdb3_server", + "influxdb3_write", + "influxdb_iox_client", + "iox_query", + "iox_time", + "ioxd_common", + "libc", + "metric", + "num_cpus", + "object_store", + "observability_deps", + "once_cell", + "panic_logging", + "parking_lot", + "parquet_file", + "pretty_assertions", + "rand", + "reqwest", + "secrecy", + "serde_json", + "sha2", + "test_helpers", + "thiserror", + "tokio", + "tokio-util", + "tokio_metrics_bridge", + "tonic 0.10.2", + "tower", + "trace", + "trace_exporters", + "trogging", + "url", + "uuid", +] + +[[package]] +name = "influxdb3_client" +version = "0.1.0" +dependencies = [ + "bytes", + "iox_query_params", + "mockito", + "reqwest", + "secrecy", + "serde", + "serde_json", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "influxdb3_load_generator" +version = "0.1.0" +dependencies = [ + "anyhow", + "bytes", + "chrono", + "clap", + "csv", + "dotenvy", + "humantime", + "influxdb3_client", + "influxdb3_process", + "observability_deps", + "parking_lot", + "rand", + "secrecy", + "serde", + "serde_json", + "sysinfo", + "thiserror", + "tokio", + "trogging", + "url", +] + +[[package]] +name = "influxdb3_process" +version = "0.1.0" +dependencies = [ + "iox_time", + "metric", + "once_cell", + "tikv-jemalloc-ctl", + "tikv-jemalloc-sys", + "tokio", + "tokio_metrics_bridge", + "uuid", +] + +[[package]] +name = "influxdb3_server" +version = "0.1.0" +dependencies = [ + "anyhow", + "arrow", + "arrow-csv", + "arrow-flight", + "arrow-json", + "arrow-schema", + "async-trait", + "authz", + "base64 0.22.0", + "bytes", + "chrono", + "data_types", + "datafusion", + "datafusion_util", + "flate2", + "futures", + "hex", + "http", + "hyper", + "influxdb-line-protocol", + "influxdb3_process", + "influxdb3_write", + "iox_catalog", + "iox_http", + "iox_query", + "iox_query_influxql", + "iox_query_influxql_rewrite", + "iox_query_params", + "iox_time", + "metric", + "metric_exporters", + "object_store", + "observability_deps", + "parking_lot", + "parquet", + "parquet_file", + "pin-project-lite", + "pretty_assertions", + "schema", + "secrecy", + "serde", + "serde_arrow", + "serde_json", + "serde_urlencoded", + "service_common", + "service_grpc_flight", + "sha2", + "test_helpers", + "test_helpers_end_to_end", + "thiserror", + "tokio", + "tokio-util", + "tonic 0.10.2", + "tower", + "trace", + "trace_exporters", + "trace_http", + "tracker", + "unicode-segmentation", + "urlencoding 1.3.3", +] + +[[package]] +name = "influxdb3_write" +version = "0.1.0" +dependencies = [ + "arrow", + "arrow_util", + "async-trait", + "byteorder", + "bytes", + "chrono", + "crc32fast", + "crossbeam-channel", + "data_types", + "datafusion", + "datafusion_util", + "futures-util", + "hex", + "influxdb-line-protocol", + "iox_catalog", + "iox_http", + "iox_query", + "iox_time", + "metric", + "object_store", + "observability_deps", + "parking_lot", + "parquet", + "parquet_file", + "pretty_assertions", + "schema", + "serde", + "serde_json", + "sha2", + "snap", + "test_helpers", + "thiserror", + "tokio", + "url", + "uuid", +] + +[[package]] +name = "influxdb_influxql_parser" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "chrono", + "chrono-tz", + "iox_query_params", + "nom", + "num-integer", + "num-traits", + "once_cell", + "thiserror", + "workspace-hack", +] + +[[package]] +name = "influxdb_iox_client" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "arrow-flight", + "arrow_util", + "bytes", + "client_util", + "comfy-table", + "futures", + "futures-util", + "generated_types", + "influxdb-line-protocol", + "iox_query_params", + "prost 0.12.4", + "rand", + "reqwest", + "schema", + "serde_json", + "thiserror", + "tokio", + "tokio-stream", + "tonic 0.10.2", + "tonic-reflection", +] + +[[package]] +name = "ingester_query_grpc" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "base64 0.22.0", + "bytes", + "data_types", + "datafusion", + "datafusion-proto", + "flatbuffers", + "pbjson", + "pbjson-build", + "predicate", + "prost 0.12.4", + "prost-build", + "query_functions", + "serde", + "snafu 0.8.2", + "tonic 0.10.2", + "tonic-build", + "workspace-hack", +] + +[[package]] +name = "inotify" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] +name = "insta" +version = "1.38.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eab73f58e59ca6526037208f0e98851159ec1633cf17b6cd2e1f2c3fd5d53cc" +dependencies = [ + "console", + "lazy_static", + "linked-hash-map", + "serde", + "similar", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "integer-encoding" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8bb03732005da905c88227371639bf1ad885cc712789c011c31c5fb3ab3ccf02" + +[[package]] +name = "iox_catalog" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "backoff 0.1.0", + "catalog_cache", + "client_util", + "data_types", + "futures", + "generated_types", + "hashbrown 0.14.3", + "http", + "iox_time", + "log", + "metric", + "mutable_batch", + "observability_deps", + "once_cell", + "parking_lot", + "serde", + "siphasher 1.0.1", + "snafu 0.8.2", + "sqlx", + "sqlx-hotswap-pool", + "thiserror", + "tokio", + "tonic 0.10.2", + "trace", + "trace_http", + "uuid", + "workspace-hack", +] + +[[package]] +name = "iox_http" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "authz", + "data_types", + "hyper", + "parking_lot", + "serde", + "serde_urlencoded", + "thiserror", + "workspace-hack", +] + +[[package]] +name = "iox_query" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "arrow_util", + "async-trait", + "bytes", + "chrono", + "data_types", + "datafusion", + "datafusion_util", + "executor", + "futures", + "hashbrown 0.14.3", + "indexmap 2.2.6", + "iox_query_params", + "iox_time", + "itertools 0.12.1", + "metric", + "object_store", + "observability_deps", + "once_cell", + "parking_lot", + "parquet_file", + "predicate", + "query_functions", + "schema", + "snafu 0.8.2", + "tokio", + "tokio-stream", + "trace", + "tracker", + "uuid", + "workspace-hack", +] + +[[package]] +name = "iox_query_influxql" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "chrono-tz", + "datafusion", + "datafusion_util", + "generated_types", + "influxdb_influxql_parser", + "iox_query", + "iox_query_params", + "itertools 0.12.1", + "observability_deps", + "once_cell", + "predicate", + "query_functions", + "regex", + "schema", + "serde_json", + "thiserror", + "workspace-hack", +] + +[[package]] +name = "iox_query_influxql_rewrite" +version = "0.1.0" +dependencies = [ + "influxdb_influxql_parser", + "thiserror", +] + +[[package]] +name = "iox_query_params" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "datafusion", + "generated_types", + "observability_deps", + "serde", + "serde_json", + "thiserror", + "workspace-hack", +] + +[[package]] +name = "iox_time" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "chrono", + "parking_lot", + "tokio", + "workspace-hack", +] + +[[package]] +name = "ioxd_common" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "authz", + "bytes", + "clap", + "clap_blocks", + "flate2", + "futures", + "generated_types", + "hashbrown 0.14.3", + "heappy", + "http", + "hyper", + "log", + "metric", + "metric_exporters", + "observability_deps", + "parking_lot", + "pprof", + "reqwest", + "serde", + "serde_json", + "serde_urlencoded", + "service_grpc_testing", + "snafu 0.8.2", + "tokio", + "tokio-stream", + "tokio-util", + "tonic 0.10.2", + "tonic-health", + "tonic-reflection", + "tower", + "tower-http", + "tower_trailer", + "trace", + "trace_exporters", + "trace_http", + "workspace-hack", +] + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "is-terminal" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" +dependencies = [ + "hermit-abi", + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" + +[[package]] +name = "jobserver" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2b099aaa34a9751c5bf0878add70444e1ed2dd73f347be99003d4577277de6e" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "json-patch" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55ff1e1486799e3f64129f8ccad108b38290df9cd7015cd31bed17239f0789d6" +dependencies = [ + "serde", + "serde_json", + "thiserror", + "treediff", +] + +[[package]] +name = "jsonpath-rust" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96acbc6188d3bd83519d053efec756aa4419de62ec47be7f28dec297f7dc9eb0" +dependencies = [ + "pest", + "pest_derive", + "regex", + "serde_json", + "thiserror", +] + +[[package]] +name = "k8s-openapi" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "550f99d93aa4c2b25de527bce492d772caf5e21d7ac9bd4b508ba781c8d91e30" +dependencies = [ + "base64 0.21.7", + "chrono", + "schemars", + "serde", + "serde-value", + "serde_json", +] + +[[package]] +name = "kqueue" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] +name = "kube" +version = "0.88.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "462fe330a0617b276ec864c2255810adcdf519ecb6844253c54074b2086a97bc" +dependencies = [ + "k8s-openapi", + "kube-client", + "kube-core", + "kube-derive", + "kube-runtime", +] + +[[package]] +name = "kube-client" +version = "0.88.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe0d65dd6f3adba29cfb84f19dfe55449c7f6c35425f9d8294bec40313e0b64" +dependencies = [ + "base64 0.21.7", + "bytes", + "chrono", + "either", + "futures", + "home", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-timeout", + "jsonpath-rust", + "k8s-openapi", + "kube-core", + "pem", + "pin-project", + "rustls", + "rustls-pemfile 1.0.4", + "secrecy", + "serde", + "serde_json", + "serde_yaml", + "thiserror", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tracing", +] + +[[package]] +name = "kube-core" +version = "0.88.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6b42844e9172f631b8263ea9ce003b9251da13beb1401580937ad206dd82f4c" +dependencies = [ + "chrono", + "form_urlencoded", + "http", + "json-patch", + "k8s-openapi", + "once_cell", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "kube-derive" +version = "0.88.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5b5a111ee287bd237b8190b8c39543ea9fd22f79e9c32a36c24e08234bcda22" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "serde_json", + "syn 2.0.60", +] + +[[package]] +name = "kube-runtime" +version = "0.88.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bc06275064c81056fbb28ea876b3fb339d970e8132282119359afca0835c0ea" +dependencies = [ + "ahash", + "async-trait", + "backoff 0.4.0", + "derivative", + "futures", + "hashbrown 0.14.3", + "json-patch", + "k8s-openapi", + "kube-client", + "parking_lot", + "pin-project", + "serde", + "serde_json", + "smallvec", + "thiserror", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] + +[[package]] +name = "lexical-core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cde5de06e8d4c2faabc400238f9ae1c74d5412d03a7bd067645ccbc47070e46" +dependencies = [ + "lexical-parse-float", + "lexical-parse-integer", + "lexical-util", + "lexical-write-float", + "lexical-write-integer", +] + +[[package]] +name = "lexical-parse-float" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683b3a5ebd0130b8fb52ba0bdc718cc56815b6a097e28ae5a6997d0ad17dc05f" +dependencies = [ + "lexical-parse-integer", + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-parse-integer" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d0994485ed0c312f6d965766754ea177d07f9c00c9b82a5ee62ed5b47945ee9" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "lexical-util" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5255b9ff16ff898710eb9eb63cb39248ea8a5bb036bea8085b1a767ff6c4e3fc" +dependencies = [ + "static_assertions", +] + +[[package]] +name = "lexical-write-float" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accabaa1c4581f05a3923d1b4cfd124c329352288b7b9da09e766b0668116862" +dependencies = [ + "lexical-util", + "lexical-write-integer", + "static_assertions", +] + +[[package]] +name = "lexical-write-integer" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1b6f3d1f4422866b68192d62f77bc5c700bee84f3069f2469d7bc8c77852446" +dependencies = [ + "lexical-util", + "static_assertions", +] + +[[package]] +name = "libc" +version = "0.2.153" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libsqlite3-sys" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "logfmt" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "observability_deps", + "tracing-subscriber", + "workspace-hack", +] + +[[package]] +name = "lz4_flex" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75761162ae2b0e580d7e7c390558127e5f01b4194debd6221fd8c207fc80e3f5" +dependencies = [ + "twox-hash", +] + +[[package]] +name = "lzma-sys" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fda04ab3764e6cde78b9974eec4f779acaba7c4e84b36eca3cf77c581b85d27" +dependencies = [ + "cc", + "libc", + "pkg-config", +] + +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + +[[package]] +name = "matchit" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "memchr" +version = "2.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d" + +[[package]] +name = "memmap2" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe751422e4a8caa417e13c3ea66452215d7d63e19e604f4980461212f3ae1322" +dependencies = [ + "libc", +] + +[[package]] +name = "metric" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "parking_lot", + "workspace-hack", +] + +[[package]] +name = "metric_exporters" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "metric", + "observability_deps", + "prometheus", + "workspace-hack", +] + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +dependencies = [ + "libc", + "log", + "wasi", + "windows-sys 0.48.0", +] + +[[package]] +name = "mockito" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6e023aa5bdf392aa06c78e4a4e6d498baab5138d0c993503350ebbc37bf1e" +dependencies = [ + "assert-json-diff", + "futures-core", + "hyper", + "log", + "rand", + "regex", + "serde_json", + "serde_urlencoded", + "similar", + "tokio", +] + +[[package]] +name = "moka" +version = "0.12.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e0d88686dc561d743b40de8269b26eaf0dc58781bde087b0984646602021d08" +dependencies = [ + "async-lock", + "async-trait", + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "event-listener 5.3.0", + "futures-util", + "once_cell", + "parking_lot", + "quanta", + "rustc_version", + "smallvec", + "tagptr", + "thiserror", + "triomphe", + "uuid", +] + +[[package]] +name = "mpchash" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdd8199faa645318222f8aeb383fca4216a3f75b144f1e264ac74c0835d871a9" +dependencies = [ + "num-traits", + "rand", + "xxhash-rust", +] + +[[package]] +name = "multimap" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" + +[[package]] +name = "murmur3" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9252111cf132ba0929b6f8e030cac2a24b507f3a4d6db6fb2896f27b354c714b" + +[[package]] +name = "mutable_batch" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "arrow_util", + "data_types", + "hashbrown 0.14.3", + "iox_time", + "itertools 0.12.1", + "schema", + "snafu 0.8.2", + "workspace-hack", +] + +[[package]] +name = "mutable_batch_lp" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "hashbrown 0.14.3", + "influxdb-line-protocol", + "itertools 0.12.1", + "mutable_batch", + "snafu 0.8.2", + "workspace-hack", +] + +[[package]] +name = "mutable_batch_pb" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow_util", + "dml", + "generated_types", + "hashbrown 0.14.3", + "mutable_batch", + "schema", + "snafu 0.8.2", + "workspace-hack", +] + +[[package]] +name = "nix" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b" +dependencies = [ + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[package]] +name = "nix" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4" +dependencies = [ + "bitflags 2.5.0", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "non-empty-string" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cf0f4060e345ae505219853da9ca1150564158a648a6aa6a528f0d5794bb33" +dependencies = [ + "delegate", +] + +[[package]] +name = "notify" +version = "6.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" +dependencies = [ + "bitflags 2.5.0", + "crossbeam-channel", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "walkdir", + "windows-sys 0.48.0", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135b08af27d103b0a51f2ae0f8632117b7b185ccf931445affa8df530576a41" +dependencies = [ + "num-bigint", + "num-complex", + "num-integer", + "num-iter", + "num-rational", + "num-traits", +] + +[[package]] +name = "num-bigint" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" +dependencies = [ + "byteorder", + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-complex" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23c6602fda94a57c990fe0df199a035d83576b496aa29f4e634a8ac6004e68a6" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-format" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" +dependencies = [ + "arrayvec", + "itoa", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0" +dependencies = [ + "autocfg", + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "object_store" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8718f8b65fdf67a45108d1548347d4af7d71fb81ce727bbf9e3b2535e079db3" +dependencies = [ + "async-trait", + "base64 0.21.7", + "bytes", + "chrono", + "futures", + "humantime", + "hyper", + "itertools 0.12.1", + "md-5", + "parking_lot", + "percent-encoding", + "quick-xml 0.31.0", + "rand", + "reqwest", + "ring", + "rustls-pemfile 2.1.2", + "serde", + "serde_json", + "snafu 0.7.5", + "tokio", + "tracing", + "url", + "walkdir", +] + +[[package]] +name = "observability_deps" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "tracing", + "workspace-hack", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +dependencies = [ + "parking_lot_core", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "ordered-float" +version = "2.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f19d67e5a2795c94e73e0bb1cc1a7edeb2e28efd39e2e1c9b7a40c1108b11c" +dependencies = [ + "num-traits", +] + +[[package]] +name = "ordered-float" +version = "4.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "panic_logging" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "metric", + "observability_deps", + "workspace-hack", +] + +[[package]] +name = "parking" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "parquet" +version = "50.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "547b92ebf0c1177e3892f44c8f79757ee62e678d564a9834189725f2c5b7a750" +dependencies = [ + "ahash", + "arrow-array", + "arrow-buffer", + "arrow-cast 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "arrow-data", + "arrow-ipc", + "arrow-schema", + "arrow-select 50.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "base64 0.21.7", + "brotli", + "bytes", + "chrono", + "flate2", + "futures", + "half", + "hashbrown 0.14.3", + "lz4_flex", + "num", + "num-bigint", + "object_store", + "paste", + "seq-macro", + "snap", + "thrift", + "tokio", + "twox-hash", + "zstd", +] + +[[package]] +name = "parquet_cache" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arc-swap", + "async-channel", + "async-trait", + "backoff 0.1.0", + "bytes", + "chrono", + "data_types", + "fnv", + "futures", + "http", + "hyper", + "iox_catalog", + "k8s-openapi", + "kube", + "moka", + "mpchash", + "notify", + "object_store", + "observability_deps", + "parking_lot", + "parquet", + "parquet_file", + "pin-project", + "reqwest", + "schema", + "schemars", + "serde", + "serde_json", + "thiserror", + "tokio", + "tokio-util", + "tower", + "url", + "workspace-hack", +] + +[[package]] +name = "parquet_file" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "base64 0.22.0", + "bytes", + "data_types", + "datafusion", + "datafusion_util", + "futures", + "generated_types", + "iox_time", + "object_store", + "observability_deps", + "parquet", + "pbjson-types", + "prost 0.12.4", + "schema", + "snafu 0.8.2", + "thiserror", + "thrift", + "tokio", + "uuid", + "workspace-hack", + "zstd", +] + +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbjson" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1030c719b0ec2a2d25a5df729d6cff1acf3cc230bf766f4f97833591f7577b90" +dependencies = [ + "base64 0.21.7", + "serde", +] + +[[package]] +name = "pbjson-build" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2580e33f2292d34be285c5bc3dba5259542b083cfad6037b6d70345f24dcb735" +dependencies = [ + "heck 0.4.1", + "itertools 0.11.0", + "prost 0.12.4", + "prost-types 0.12.4", +] + +[[package]] +name = "pbjson-types" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18f596653ba4ac51bdecbb4ef6773bc7f56042dc13927910de1684ad3d32aa12" +dependencies = [ + "bytes", + "chrono", + "pbjson", + "pbjson-build", + "prost 0.12.4", + "prost-build", + "serde", +] + +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64 0.22.0", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pest" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "311fb059dee1a7b802f036316d790138c613a4e8b180c822e3925a662e9f0c95" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f73541b156d32197eecda1a4014d7f868fd2bcb3c550d5386087cfba442bf69c" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c35eeed0a3fab112f75165fdc026b3913f4183133f19b49be773ac9ea966e8bd" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "pest_meta" +version = "2.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2adbf29bb9776f28caece835398781ab24435585fe0d4dc1374a61db5accedca" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "petgraph" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" +dependencies = [ + "fixedbitset", + "indexmap 2.2.6", +] + +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared", + "rand", +] + +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher 0.3.11", +] + +[[package]] +name = "pin-project" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" + +[[package]] +name = "platforms" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db23d408679286588f4d4644f965003d056e3dd5abcaaa938116871d7ce2fee7" + +[[package]] +name = "pprof" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef5c97c51bd34c7e742402e216abdeb44d415fbe6ae41d56b114723e953711cb" +dependencies = [ + "backtrace", + "cfg-if", + "findshlibs", + "inferno", + "libc", + "log", + "nix 0.26.4", + "once_cell", + "parking_lot", + "prost 0.12.4", + "prost-build", + "prost-derive 0.12.4", + "protobuf", + "sha2", + "smallvec", + "symbolic-demangle", + "tempfile", + "thiserror", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "predicate" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "chrono", + "data_types", + "datafusion", + "datafusion_util", + "itertools 0.12.1", + "observability_deps", + "query_functions", + "schema", + "snafu 0.8.2", + "sqlparser", + "workspace-hack", +] + +[[package]] +name = "predicates" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b87bfd4605926cdfefc1c3b5f8fe560e3feca9d5552cf68c466d3d8236c7e8" +dependencies = [ + "anstyle", + "difflib", + "predicates-core", +] + +[[package]] +name = "predicates-core" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174" + +[[package]] +name = "predicates-tree" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf" +dependencies = [ + "predicates-core", + "termtree", +] + +[[package]] +name = "pretty_assertions" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af7cee1a6c8a5b9208b3cb1061f10c0cb689087b3d8ce85fb9d2dd7a29b6ba66" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "prettyplease" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ac2cf0f2e4f42b49f5ffd07dae8d746508ef7526c13940e5f524012ae6c6550" +dependencies = [ + "proc-macro2", + "syn 2.0.60", +] + +[[package]] +name = "proc-macro2" +version = "1.0.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d1597b0c024618f09a9c3b8655b7e430397a36d23fdafec26d6965e9eec3eba" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prometheus" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot", + "thiserror", +] + +[[package]] +name = "proptest" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b476131c3c86cb68032fdc5cb6d5a1045e3e42d96b69fa599fd77701e1f5bf" +dependencies = [ + "bitflags 2.5.0", + "lazy_static", + "num-traits", + "rand", + "rand_chacha", + "rand_xorshift", + "regex-syntax 0.8.3", + "unarray", +] + +[[package]] +name = "prost" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b82eaa1d779e9a4bc1c3217db8ffbeabaae1dca241bf70183242128d48681cd" +dependencies = [ + "bytes", + "prost-derive 0.11.9", +] + +[[package]] +name = "prost" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f5d036824e4761737860779c906171497f6d55681139d8312388f8fe398922" +dependencies = [ + "bytes", + "prost-derive 0.12.4", +] + +[[package]] +name = "prost-build" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80b776a1b2dc779f5ee0641f8ade0125bc1298dd41a9a0c16d8bd57b42d222b1" +dependencies = [ + "bytes", + "heck 0.5.0", + "itertools 0.12.1", + "log", + "multimap", + "once_cell", + "petgraph", + "prettyplease", + "prost 0.12.4", + "prost-types 0.12.4", + "regex", + "syn 2.0.60", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5d2d8d10f3c6ded6da8b05b5fb3b8a5082514344d56c9f871412d29b4e075b4" +dependencies = [ + "anyhow", + "itertools 0.10.5", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "prost-derive" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19de2de2a00075bf566bee3bd4db014b11587e84184d3f7a791bc17f1a8e9e48" +dependencies = [ + "anyhow", + "itertools 0.12.1", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "prost-types" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213622a1460818959ac1181aaeb2dc9c7f63df720db7d788b3e24eacd1983e13" +dependencies = [ + "prost 0.11.9", +] + +[[package]] +name = "prost-types" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3235c33eb02c1f1e212abdbe34c78b264b038fb58ca612664343271e36e55ffe" +dependencies = [ + "prost 0.12.4", +] + +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + +[[package]] +name = "quanta" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e5167a477619228a0b284fac2674e3c388cba90631d7b7de620e6f1fcd08da5" +dependencies = [ + "crossbeam-utils", + "libc", + "once_cell", + "raw-cpuid", + "wasi", + "web-sys", + "winapi", +] + +[[package]] +name = "query_functions" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "chrono", + "datafusion", + "once_cell", + "regex", + "regex-syntax 0.8.3", + "schema", + "snafu 0.8.2", + "workspace-hack", +] + +[[package]] +name = "quick-xml" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f50b1c63b38611e7d4d7f68b82d3ad0cc71a2ad2e7f61fc10f1328d917c93cd" +dependencies = [ + "memchr", +] + +[[package]] +name = "quick-xml" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "quote" +version = "1.0.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + +[[package]] +name = "rand_xorshift" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d25bf25ec5ae4a3f1b92f929810509a2f53d7dca2f50b794ff57e3face536c8f" +dependencies = [ + "rand_core", +] + +[[package]] +name = "raw-cpuid" +version = "11.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d86a7c4638d42c44551f4791a20e687dbb4c3de1f33c43dd71e355cd429def1" +dependencies = [ + "bitflags 2.5.0", +] + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "regex" +version = "1.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax 0.8.3", +] + +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + +[[package]] +name = "regex-syntax" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" + +[[package]] +name = "reqwest" +version = "0.11.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls", + "rustls-native-certs", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "system-configuration", + "tokio", + "tokio-rustls", + "tokio-util", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "rgb" +version = "0.8.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05aaa8004b64fd573fc9d002f4e632d51ad4f026c2b5ba95fcb6c2f32c2c47d8" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "ring" +version = "0.17.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" +dependencies = [ + "cc", + "cfg-if", + "getrandom", + "libc", + "spin 0.9.8", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rsa" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" +dependencies = [ + "bitflags 2.5.0", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.21.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" +dependencies = [ + "log", + "ring", + "rustls-webpki", + "sct", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile 1.0.4", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-pemfile" +version = "2.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +dependencies = [ + "base64 0.22.0", + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beb461507cee2c2ff151784c52762cf4d9ff6a61f3e80968600ed24fa837fa54" + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80af6f9131f277a45a3fba6ce8e2258037bb0477a67e610d3c1fe046ab31de47" + +[[package]] +name = "ryu" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "schema" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "hashbrown 0.14.3", + "indexmap 2.2.6", + "observability_deps", + "once_cell", + "snafu 0.8.2", + "workspace-hack", +] + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "secrecy" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e" +dependencies = [ + "serde", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "770452e37cad93e0a50d5abc3990d2bc351c36d0328f86cefec2f2fb206eaef6" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f3cc463c0ef97e11c3461a9d3787412d30e8e7eb907c79180c4a57bf7c04ef" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" + +[[package]] +name = "seq-macro" +version = "0.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3f0bf26fd526d2a95683cd0f87bf103b8539e2ca1ef48ce002d67aad59aa0b4" + +[[package]] +name = "serde" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9846a40c979031340571da2545a4e5b7c4163bdae79b301d5f86d03979451fcc" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-value" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" +dependencies = [ + "ordered-float 2.10.1", + "serde", +] + +[[package]] +name = "serde_arrow" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e774f158723ad8fe05b884fd2f89355934599a11817edd0dc854cb1ef0e42a" +dependencies = [ + "arrow-array", + "arrow-buffer", + "arrow-data", + "arrow-schema", + "bytemuck", + "chrono", + "half", + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.198" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e88edab869b01783ba905e7d0153f9fc1a6505a96e4ad3018011eedb838566d9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.116" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e17db7126d17feb94eb3fad46bf1a96b034e8aacbc2e775fe81505f8b0b2813" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap 2.2.6", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "service_common" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "datafusion", + "executor", + "tonic 0.10.2", + "workspace-hack", +] + +[[package]] +name = "service_grpc_flight" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "arrow-flight", + "authz", + "bytes", + "data_types", + "datafusion", + "flightsql", + "futures", + "generated_types", + "iox_query", + "iox_query_influxql", + "iox_query_params", + "observability_deps", + "prost 0.12.4", + "serde", + "serde_json", + "service_common", + "snafu 0.8.2", + "tokio", + "tonic 0.10.2", + "tower_trailer", + "trace", + "trace_http", + "tracker", + "workspace-hack", +] + +[[package]] +name = "service_grpc_testing" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "generated_types", + "observability_deps", + "tonic 0.10.2", + "workspace-hack", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core", +] + +[[package]] +name = "similar" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa42c91313f1d05da9b26f267f931cf178d4aba455b4c4622dd7355eb80c6640" + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "siphasher" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56199f7ddabf13fe5074ce809e7d3f42b42ae711800501b5b16ea82ad029c39d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" + +[[package]] +name = "snafu" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4de37ad025c587a29e8f3f5605c00f70b98715ef90b9061a815b9e59e9042d6" +dependencies = [ + "doc-comment", + "snafu-derive 0.7.5", +] + +[[package]] +name = "snafu" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75976f4748ab44f6e5332102be424e7c2dc18daeaf7e725f2040c3ebb133512e" +dependencies = [ + "snafu-derive 0.8.2", +] + +[[package]] +name = "snafu-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990079665f075b699031e9c08fd3ab99be5029b96f3b78dc0709e8f77e4efebf" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "snafu-derive" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b19911debfb8c2fb1107bc6cb2d61868aaf53a988449213959bb1b5b1ed95f" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "snap" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b" + +[[package]] +name = "socket2" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools 0.12.1", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlparser" +version = "0.44.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aaf9c7ff146298ffda83a200f8d5084f08dcee1edfc135fcc1d646a45d50ffd6" +dependencies = [ + "log", + "sqlparser_derive", +] + +[[package]] +name = "sqlparser_derive" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b2e185515564f15375f593fb966b5718bc624ba77fe49fa4616ad619690554" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "sqlx" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "either", + "event-listener 2.5.3", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.2.6", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls", + "rustls-pemfile 1.0.4", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url", + "uuid", + "webpki-roots", +] + +[[package]] +name = "sqlx-hotswap-pool" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "either", + "futures", + "sqlx", + "workspace-hack", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +dependencies = [ + "dotenvy", + "either", + "heck 0.4.1", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.5.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array", + "hex", + "hkdf", + "hmac", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "percent-encoding", + "rand", + "rsa", + "serde", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +dependencies = [ + "atoi", + "base64 0.21.7", + "bitflags 2.5.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log", + "md-5", + "memchr", + "once_cell", + "rand", + "serde", + "serde_json", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "uuid", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log", + "percent-encoding", + "serde", + "sqlx-core", + "tracing", + "url", + "urlencoding 2.1.3", + "uuid", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "str_stack" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9091b6114800a5f2141aee1d1b9d6ca3592ac062dc5decb3764ec5895a47b4eb" + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.60", +] + +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + +[[package]] +name = "symbolic-common" +version = "12.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cccfffbc6bb3bb2d3a26cd2077f4d055f6808d266f9d4d158797a4c60510dfe" +dependencies = [ + "debugid", + "memmap2", + "stable_deref_trait", + "uuid", +] + +[[package]] +name = "symbolic-demangle" +version = "12.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a99812da4020a67e76c4eb41f08c87364c14170495ff780f30dd519c221a68" +dependencies = [ + "cpp_demangle", + "rustc-demangle", + "symbolic-common", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "909518bc7b1c9b779f1bbf07f2929d35af9f0f37e47c6e9ef7f9dddc1e1821f3" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sysinfo" +version = "0.30.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87341a165d73787554941cd5ef55ad728011566fe714e987d1b976c15dbc3a83" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tempfile" +version = "3.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" +dependencies = [ + "cfg-if", + "fastrand", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "termtree" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" + +[[package]] +name = "test_helpers" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "dotenvy", + "observability_deps", + "parking_lot", + "tempfile", + "tokio", + "tracing-log", + "tracing-subscriber", + "workspace-hack", +] + +[[package]] +name = "test_helpers_end_to_end" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "arrow", + "arrow-flight", + "arrow_util", + "assert_cmd", + "assert_matches", + "bytes", + "data_types", + "dml", + "futures", + "generated_types", + "http", + "hyper", + "influxdb_iox_client", + "ingester_query_grpc", + "insta", + "iox_catalog", + "iox_query_params", + "mutable_batch_lp", + "mutable_batch_pb", + "nix 0.28.0", + "observability_deps", + "once_cell", + "parking_lot", + "prost 0.12.4", + "rand", + "regex", + "reqwest", + "serde_json", + "snafu 0.8.2", + "sqlx", + "tempfile", + "test_helpers", + "tokio", + "tokio-util", + "tonic 0.10.2", + "workspace-hack", +] + +[[package]] +name = "thiserror" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0126ad08bff79f29fc3ae6a55cc72352056dfff61e3ff8bb7129476d44b23aa" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.59" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cd413b5d558b4c5bf3680e324a6fa5014e7b7c067a51e69dbdf47eb7148b66" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "threadpool" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa" +dependencies = [ + "num_cpus", +] + +[[package]] +name = "thrift" +version = "0.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e54bc85fc7faa8bc175c4bab5b92ba8d9a3ce893d0e9f42cc455c8ab16a9e09" +dependencies = [ + "byteorder", + "integer-encoding", + "log", + "ordered-float 2.10.1", + "threadpool", +] + +[[package]] +name = "tikv-jemalloc-ctl" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619bfed27d807b54f7f776b9430d4f8060e66ee138a28632ca898584d462c31c" +dependencies = [ + "libc", + "paste", + "tikv-jemalloc-sys", +] + +[[package]] +name = "tikv-jemalloc-sys" +version = "0.5.4+5.3.0-patched" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +dependencies = [ + "cc", + "libc", +] + +[[package]] +name = "tiny-keccak" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237" +dependencies = [ + "crunchy", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "tracing", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30b74022ada614a1b4834de765f9bb43877f910cc8ce4be40e89042c9223a8bf" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "tokio_metrics_bridge" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "metric", + "parking_lot", + "tokio", + "workspace-hack", +] + +[[package]] +name = "tokio_watchdog" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "metric", + "observability_deps", + "tokio", + "workspace-hack", +] + +[[package]] +name = "tonic" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3082666a3a6433f7f511c7192923fa1fe07c69332d3c6a2e6bb040b569199d5a" +dependencies = [ + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.11.9", + "tokio", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d560933a0de61cf715926b9cac824d4c883c2c43142f787595e48280c40a1d0e" +dependencies = [ + "async-stream", + "async-trait", + "axum", + "base64 0.21.7", + "bytes", + "h2", + "http", + "http-body", + "hyper", + "hyper-timeout", + "percent-encoding", + "pin-project", + "prost 0.12.4", + "rustls", + "rustls-native-certs", + "rustls-pemfile 1.0.4", + "tokio", + "tokio-rustls", + "tokio-stream", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tonic-build" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d021fc044c18582b9a2408cd0dd05b1596e3ecdb5c4df822bb0183545683889" +dependencies = [ + "prettyplease", + "proc-macro2", + "prost-build", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tonic-health" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f80db390246dfb46553481f6024f0082ba00178ea495dbb99e70ba9a4fafb5e1" +dependencies = [ + "async-stream", + "prost 0.12.4", + "tokio", + "tokio-stream", + "tonic 0.10.2", +] + +[[package]] +name = "tonic-reflection" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fa37c513df1339d197f4ba21d28c918b9ef1ac1768265f11ecb6b7f1cba1b76" +dependencies = [ + "prost 0.12.4", + "prost-types 0.12.4", + "tokio", + "tokio-stream", + "tonic 0.10.2", +] + +[[package]] +name = "tower" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" +dependencies = [ + "futures-core", + "futures-util", + "indexmap 1.9.3", + "pin-project", + "pin-project-lite", + "rand", + "slab", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" +dependencies = [ + "base64 0.21.7", + "bitflags 2.5.0", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-range-header", + "mime", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tower_trailer" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "futures", + "http", + "http-body", + "parking_lot", + "pin-project", + "tower", + "workspace-hack", +] + +[[package]] +name = "trace" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "chrono", + "observability_deps", + "parking_lot", + "rand", + "workspace-hack", +] + +[[package]] +name = "trace_exporters" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "async-trait", + "clap", + "futures", + "iox_time", + "observability_deps", + "snafu 0.8.2", + "thrift", + "tokio", + "trace", + "workspace-hack", +] + +[[package]] +name = "trace_http" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "bytes", + "futures", + "hashbrown 0.14.3", + "http", + "http-body", + "itertools 0.12.1", + "metric", + "observability_deps", + "parking_lot", + "pin-project", + "snafu 0.8.2", + "tower", + "trace", + "workspace-hack", +] + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "parking_lot", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + +[[package]] +name = "tracker" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "futures", + "hashbrown 0.14.3", + "iox_time", + "lock_api", + "metric", + "observability_deps", + "parking_lot", + "pin-project", + "sysinfo", + "tokio", + "tokio-util", + "trace", + "workspace-hack", +] + +[[package]] +name = "treediff" +version = "4.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d127780145176e2b5d16611cc25a900150e86e9fd79d3bde6ff3a37359c9cb5" +dependencies = [ + "serde_json", +] + +[[package]] +name = "triomphe" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "859eb650cfee7434994602c3a68b25d77ad9e68c8a6cd491616ef86661382eb3" + +[[package]] +name = "trogging" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "clap", + "logfmt", + "observability_deps", + "thiserror", + "tracing-log", + "tracing-subscriber", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "twox-hash" +version = "1.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675" +dependencies = [ + "cfg-if", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-bidi" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", +] + +[[package]] +name = "urlencoding" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb" + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "getrandom", +] + +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "wait-timeout" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" +dependencies = [ + "libc", +] + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.60", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "wasm-streams" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + +[[package]] +name = "whoami" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" +dependencies = [ + "redox_syscall", + "wasite", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core", + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.5", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" +dependencies = [ + "windows_aarch64_gnullvm 0.52.5", + "windows_aarch64_msvc 0.52.5", + "windows_i686_gnu 0.52.5", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.5", + "windows_x86_64_gnu 0.52.5", + "windows_x86_64_gnullvm 0.52.5", + "windows_x86_64_msvc 0.52.5", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "workspace-hack" +version = "0.1.0" +source = "git+https://github.com/influxdata/influxdb3_core?rev=b546e7f86ee9adbff0dd3c5e687140848397604a#b546e7f86ee9adbff0dd3c5e687140848397604a" +dependencies = [ + "ahash", + "arrow-array", + "arrow-ipc", + "base64 0.21.7", + "bitflags 2.5.0", + "byteorder", + "bytes", + "cc", + "chrono", + "crossbeam-epoch", + "crossbeam-utils", + "crypto-common", + "digest", + "either", + "fixedbitset", + "flatbuffers", + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", + "getrandom", + "hashbrown 0.14.3", + "heck 0.4.1", + "hyper", + "hyper-rustls", + "indexmap 2.2.6", + "itertools 0.11.0", + "k8s-openapi", + "kube-core", + "libc", + "lock_api", + "log", + "md-5", + "memchr", + "mio", + "nom", + "num-traits", + "object_store", + "once_cell", + "parking_lot", + "percent-encoding", + "petgraph", + "phf_shared", + "proptest", + "prost 0.12.4", + "prost-types 0.12.4", + "rand", + "rand_core", + "regex", + "regex-automata 0.4.6", + "regex-syntax 0.8.3", + "reqwest", + "ring", + "rustls", + "serde", + "serde_json", + "sha2", + "similar", + "spin 0.9.8", + "sqlparser", + "sqlx", + "sqlx-core", + "sqlx-macros", + "sqlx-macros-core", + "sqlx-postgres", + "sqlx-sqlite", + "syn 1.0.109", + "syn 2.0.60", + "thrift", + "tokio", + "tokio-stream", + "tokio-util", + "tower", + "tower-http", + "tracing", + "tracing-core", + "tracing-log", + "tracing-subscriber", + "unicode-bidi", + "unicode-normalization", + "url", + "uuid", + "winapi", + "windows-sys 0.48.0", + "windows-sys 0.52.0", +] + +[[package]] +name = "xxhash-rust" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "927da81e25be1e1a2901d59b81b37dd2efd1fc9c9345a55007f09bf5a2d3ee03" + +[[package]] +name = "xz2" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388c44dc09d76f1536602ead6d325eb532f5c122f17782bd57fb47baeeb767e2" +dependencies = [ + "lzma-sys", +] + +[[package]] +name = "yansi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" + +[[package]] +name = "zstd" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d789b1514203a1120ad2429eae43a7bd32b90976a7bb8a05f7ec02fa88cc23a" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "7.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd99b45c6bc03a018c8b8a86025678c87e55526064e38f9df301989dce7ec0a" +dependencies = [ + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.10+zstd.1.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c253a4914af5bafc8fa8c86ee400827e83cf6ec01195ec1f1ed8441bf00d65aa" +dependencies = [ + "cc", + "pkg-config", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 00000000000..820056ccd14 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,185 @@ +[workspace] +# In alphabetical order +members = [ + "influxdb3", + "influxdb3_client", + "influxdb3_load_generator", + "influxdb3_process", + "influxdb3_server", + "influxdb3_write", + "iox_query_influxql_rewrite", +] +default-members = ["influxdb3"] + +resolver = "2" + +exclude = [ + "*.md", + "*.txt", + ".circleci/", + ".editorconfig", + ".git*", + ".github/", + ".kodiak.toml", + "LICENSE*", +] + +[workspace.package] +version = "0.1.0" +authors = ["influxdata Edge Developers"] +edition = "2021" +license = "MIT OR Apache-2.0" + +[workspace.dependencies] +anyhow = "1.0" +arrow = { version = "50.0.0", features = ["prettyprint", "chrono-tz"] } +arrow-array = "50.0.0" +arrow-buffer = "50.0.0" +arrow-csv = "50.0.0" +arrow-flight = { version = "50.0.0", features = ["flight-sql-experimental"] } +arrow-json = "50.0.0" +arrow-schema = "50.0.0" +assert_cmd = "2.0.14" +async-trait = "0.1" +backtrace = "0.3" +base64 = "0.22.0" +byteorder = "1.3.4" +bytes = "1.5" +chrono = "0.4" +clap = { version = "4", features = ["derive", "env", "string"] } +crc32fast = "1.2.0" +crossbeam-channel = "0.5.11" +datafusion = { git = "https://github.com/influxdata/arrow-datafusion.git", rev = "581e74785b876615d6a63db8c2e5ba372bf78828" } +datafusion-proto = { git = "https://github.com/influxdata/arrow-datafusion.git", rev = "581e74785b876615d6a63db8c2e5ba372bf78828" } +csv = "1.3.0" +dotenvy = "0.15.7" +flate2 = "1.0.27" +futures = "0.3.28" +futures-util = "0.3.30" +hashbrown = "0.14.3" +hex = "0.4.3" +http = "0.2.9" +humantime = "2.1.0" +hyper = "0.14" +libc = { version = "0.2" } +mockito = { version = "1.2.0", default-features = false } +num_cpus = "1.16.0" +object_store = "0.9.1" +once_cell = { version = "1.18", features = ["parking_lot"] } +parking_lot = "0.12.1" +parquet = { version = "50.0.0", features = ["object_store"] } +pbjson = "0.6.0" +pbjson-build = "0.6.2" +pbjson-types = "0.6.0" +pin-project-lite = "0.2" +pretty_assertions = "1.4.0" +prost = "0.12.3" +prost-build = "0.12.2" +prost-types = "0.12.3" +rand = "0.8.5" +reqwest = { version = "0.11.24", default-features = false, features = ["rustls-tls", "stream"] } +secrecy = "0.8.0" +serde = { version = "1.0", features = ["derive"] } +serde_arrow = { version = "0.10", features = ["arrow-50"] } +serde_json = "1.0" +serde_urlencoded = "0.7.0" +sha2 = "0.10.8" +snap = "1.0.0" +sqlparser = "0.41.0" +sysinfo = "0.30.8" +thiserror = "1.0" +tokio = { version = "1.35", features = ["full"] } +tokio-util = "0.7.9" +tonic = { version = "0.10.2", features = ["tls", "tls-roots"] } +tonic-build = "0.10.2" +tonic-health = "0.10.2" +tonic-reflection = "0.10.2" +tower = "0.4.13" +unicode-segmentation = "1.11.0" +url = "2.5.0" +urlencoding = "1.1" +uuid = { version = "1", features = ["v4"] } + +# Core.git crates we depend on +arrow_util = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a"} +authz = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a", features = ["http"] } +clap_blocks = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +data_types = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +datafusion_util = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +influxdb-line-protocol = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +influxdb_influxql_parser = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +influxdb_iox_client = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +iox_catalog = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +ioxd_common = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +iox_http = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +iox_query = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +iox_query_params = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +iox_query_influxql = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +iox_time = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +metric = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +metric_exporters = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +observability_deps = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +panic_logging = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +parquet_file = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +schema = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +service_common = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +service_grpc_flight = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +test_helpers = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +test_helpers_end_to_end = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +tokio_metrics_bridge = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +trace = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +trace_exporters = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +trace_http = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +tracker = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a" } +trogging = { git = "https://github.com/influxdata/influxdb3_core", rev = "b546e7f86ee9adbff0dd3c5e687140848397604a", default-features = true, features = ["clap"] } + +[workspace.lints.rust] +rust_2018_idioms = "deny" +unreachable_pub = "deny" +missing_debug_implementations = "deny" +missing_copy_implementations = "deny" + +[workspace.lints.clippy] +dbg_macro = "deny" +todo = "deny" +clone_on_ref_ptr = "deny" +future_not_send = "deny" + +[workspace.lints.rustdoc] +broken_intra_doc_links = "deny" +bare_urls = "deny" + +# This profile optimizes for runtime performance and small binary size at the expense of longer +# build times. It's most suitable for final release builds. +[profile.release] +codegen-units = 16 +debug = true +lto = "thin" + +[profile.bench] +debug = true + +# This profile optimizes for short build times at the expense of larger binary size and slower +# runtime performance. It's most suitable for development iterations. +[profile.quick-release] +inherits = "release" +codegen-units = 16 +lto = false +incremental = true + +# Per insta docs: https://insta.rs/docs/quickstart/#optional-faster-runs +[profile.dev.package.insta] +opt-level = 3 + +[profile.dev.package.similar] +opt-level = 3 + +# patch arrow-flight crate to allow for prepared statement parameters +# see related arrow-rs PR https://github.com/apache/arrow-rs/pull/5433 +[patch.crates-io] +arrow-array = { git = "https://github.com/erratic-pattern/arrow-rs.git", branch = "50.0.0" } +arrow-schema = { git = "https://github.com/erratic-pattern/arrow-rs.git", branch = "50.0.0" } +arrow-data = { git = "https://github.com/erratic-pattern/arrow-rs.git", branch = "50.0.0" } +arrow-buffer = { git = "https://github.com/erratic-pattern/arrow-rs.git", branch = "50.0.0" } +arrow-ipc = { git = "https://github.com/erratic-pattern/arrow-rs.git", branch = "50.0.0" } +arrow-flight = { git = "https://github.com/erratic-pattern/arrow-rs.git", branch = "50.0.0" } diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000000..68382d4f61f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,61 @@ +#syntax=docker/dockerfile:1.2 +ARG RUST_VERSION=1.75 +FROM rust:${RUST_VERSION}-slim-bookworm as build + +# cache mounts below may already exist and owned by root +USER root + +RUN apt update \ + && apt install --yes binutils build-essential pkg-config libssl-dev clang lld git protobuf-compiler \ + && rm -rf /var/lib/{apt,dpkg,cache,log} + +# Build influxdb3 +COPY . /influxdb3 +WORKDIR /influxdb3 + +ARG CARGO_INCREMENTAL=yes +ARG CARGO_NET_GIT_FETCH_WITH_CLI=false +ARG PROFILE=release +ARG FEATURES=aws,gcp,azure,jemalloc_replacing_malloc +ARG PACKAGE=influxdb3 +ENV CARGO_INCREMENTAL=$CARGO_INCREMENTAL \ + CARGO_NET_GIT_FETCH_WITH_CLI=$CARGO_NET_GIT_FETCH_WITH_CLI \ + PROFILE=$PROFILE \ + FEATURES=$FEATURES \ + PACKAGE=$PACKAGE + +RUN \ + --mount=type=cache,id=influxdb3_rustup,sharing=locked,target=/usr/local/rustup \ + --mount=type=cache,id=influxdb3_registry,sharing=locked,target=/usr/local/cargo/registry \ + --mount=type=cache,id=influxdb3_git,sharing=locked,target=/usr/local/cargo/git \ + --mount=type=cache,id=influxdb3_target,sharing=locked,target=/influxdb_iox/target \ + du -cshx /usr/local/rustup /usr/local/cargo/registry /usr/local/cargo/git /influxdb_iox/target && \ + cargo build --target-dir /influxdb3/target --package="$PACKAGE" --profile="$PROFILE" --no-default-features --features="$FEATURES" && \ + objcopy --compress-debug-sections "target/$PROFILE/$PACKAGE" && \ + cp "/influxdb3/target/$PROFILE/$PACKAGE" /root/$PACKAGE && \ + du -cshx /usr/local/rustup /usr/local/cargo/registry /usr/local/cargo/git /influxdb_iox/target + + +FROM debian:bookworm-slim + +RUN apt update \ + && apt install --yes ca-certificates gettext-base libssl3 --no-install-recommends \ + && rm -rf /var/lib/{apt,dpkg,cache,log} \ + && groupadd --gid 1500 influxdb3 \ + && useradd --uid 1500 --gid influxdb3 --shell /bin/bash --create-home influxdb3 + +USER influxdb3 + +RUN mkdir ~/.influxdb3 + +ARG PACKAGE=influxdb3 +ENV PACKAGE=$PACKAGE + +COPY --from=build "/root/$PACKAGE" "/usr/bin/$PACKAGE" +COPY docker/entrypoint.sh /usr/bin/entrypoint.sh + +EXPOSE 8080 8082 + +ENTRYPOINT ["/usr/bin/entrypoint.sh"] + +CMD ["serve"] diff --git a/Dockerfile.dockerignore b/Dockerfile.dockerignore new file mode 100644 index 00000000000..34d63e928ee --- /dev/null +++ b/Dockerfile.dockerignore @@ -0,0 +1,7 @@ +.*/ +target/ +tests/ +docker/ +!.cargo/ +!.git/ +!docker/entrypoint.sh diff --git a/LICENSE-APACHE b/LICENSE-APACHE new file mode 100644 index 00000000000..16fe87b06e8 --- /dev/null +++ b/LICENSE-APACHE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/LICENSE-MIT b/LICENSE-MIT new file mode 100644 index 00000000000..42d41dfd83f --- /dev/null +++ b/LICENSE-MIT @@ -0,0 +1,25 @@ +Copyright (c) 2020 InfluxData + +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md index 1e35d4b1fe1..5c96bddb2d3 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# influxdb_pro \ No newline at end of file +# InfluxDB Pro diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000000..4e017acccc6 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,11 @@ +# Security Policy + +## Reporting a Vulnerability + +InfluxData takes security and our users' trust seriously. If you believe you +have found a security issue in any of our open source projects, please +responsibly disclose it by contacting `security@influxdata.com`. More details +about security vulnerability reporting can be found on the +[InfluxData How to Report Vulnerabilities page][InfluxData Security]. + +[InfluxData Security]: https://www.influxdata.com/how-to-report-security-vulnerabilities/ diff --git a/deny.toml b/deny.toml new file mode 100644 index 00000000000..b97e99ca532 --- /dev/null +++ b/deny.toml @@ -0,0 +1,48 @@ +# Configuration documentation: +#  https://embarkstudios.github.io/cargo-deny/index.html + +[advisories] +vulnerability = "deny" +yanked = "deny" +unmaintained = "warn" +notice = "warn" +ignore = [ +] +git-fetch-with-cli = true + +[licenses] +allow-osi-fsf-free = "either" +copyleft = "deny" +unlicensed = "deny" +default = "deny" + +exceptions = [ + # We should probably NOT bundle CA certs but use the OS ones. + { name = "webpki-roots", allow = ["MPL-2.0"] }, +] + +[[licenses.clarify]] +name = "ring" +expression = "BSD-4-Clause AND ISC AND MIT AND OpenSSL" +license-files = [ + # https://github.com/briansmith/ring/blob/95948b3977013aed16db92ae32e6b8384496a740/LICENSE + { path = "LICENSE", hash = 0xbd0eed23 }, +] + +[sources.allow-org] +github = ["influxdata", "apache"] + +[bans] +multiple-versions = "warn" +deny = [ + # We are using rustls as the TLS implementation, so we shouldn't be linking + # in OpenSSL too. + # + # If you're hitting this, you might want to take a look at what new + # dependencies you have introduced and check if there's a way to depend on + # rustls instead of OpenSSL (tip: check the crate's feature flags). + { name = "openssl-sys" }, + # We've decided to use the `humantime` crate to parse and generate friendly time formats; use + # that rather than chrono-english. + { name = "chrono-english" }, +] diff --git a/docker/Dockerfile.ci b/docker/Dockerfile.ci new file mode 100644 index 00000000000..ccb88ffaea5 --- /dev/null +++ b/docker/Dockerfile.ci @@ -0,0 +1,74 @@ +### +# Dockerfile for the image used in the InfluxDB IOx CI tests +# As of October 2020, it is rebuilt each night +# +# It expects to be run with the repo checked out locally. +# for example: +# +# cd influxdb_iox +# docker build -f docker/Dockerfile.ci \ +# --build-arg RUST_VERSION=$(sed -E -ne 's/channel = "(.*)"/\1/p' rust-toolchain.toml) . +## + +ARG RUST_VERSION +# Build actual image used for CI pipeline +FROM rust:${RUST_VERSION}-slim-bookworm + +# When https://github.com/rust-lang/rustup/issues/2686 is fixed, run the command added that +# will install everything in rust-toolchain.toml here so that components are in the container + +# make Apt non-interactive +RUN echo 'APT::Get::Assume-Yes "true";' > /etc/apt/apt.conf.d/90ci \ + && echo 'DPkg::Options "--force-confnew";' >> /etc/apt/apt.conf.d/90ci + +ENV DEBIAN_FRONTEND=noninteractive + +RUN apt-get update \ + && mkdir -p /usr/share/man/man1 \ + && apt-get install -y \ + git locales sudo openssh-client ca-certificates tar gzip parallel \ + unzip zip bzip2 gnupg curl make pkg-config libssl-dev \ + jq clang lld g++ shellcheck yamllint protobuf-compiler libprotobuf-dev \ + skopeo openjdk-17-jdk \ + --no-install-recommends \ + && curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - \ + && echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" >> /etc/apt/sources.list.d/google-cloud-sdk.list \ + && apt-get update \ + && apt-get install google-cloud-cli \ + && apt-get clean autoclean \ + && apt-get autoremove --yes \ + && rm -rf /var/lib/{apt,dpkg,cache,log} + +ENV CURL_FLAGS="--proto =https --tlsv1.2 -sSf" + +# Install InfluxDB 2.0 OSS to enable integration tests of the influxdb2_client crate +ENV INFLUXDB2_VERSION=2.0.4 +ENV INFLUXDB2_DOWNLOAD_BASE="https://dl.influxdata.com/influxdb/releases" +RUN curl ${CURL_FLAGS} https://repos.influxdata.com/influxdata-archive_compat.key | gpg --import - \ + && curl ${CURL_FLAGS} -o influxdb2.tar.gz ${INFLUXDB2_DOWNLOAD_BASE}/influxdb2-${INFLUXDB2_VERSION}-linux-amd64.tar.gz \ + && curl ${CURL_FLAGS} -O ${INFLUXDB2_DOWNLOAD_BASE}/influxdb2-${INFLUXDB2_VERSION}-linux-amd64.tar.gz.asc \ + && gpg --verify influxdb2-${INFLUXDB2_VERSION}-linux-amd64.tar.gz.asc influxdb2.tar.gz \ + && tar xvzf influxdb2.tar.gz \ + && sudo cp influxdb2-${INFLUXDB2_VERSION}-linux-amd64/influxd /usr/local/bin/ \ + && rm -rf influxdb2-${INFLUXDB2_VERSION}-linux-amd64 influxdb2-${INFLUXDB2_VERSION}-linux-amd64.tar.gz.asc + +# Set timezone to UTC by default +RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime +# Use unicode +RUN locale-gen C.UTF-8 || true +ENV LANG=C.UTF-8 + +RUN groupadd -g 1500 rust \ + && useradd -u 1500 -g rust -s /bin/bash -m rust \ + && echo 'rust ALL=NOPASSWD: ALL' >> /etc/sudoers.d/10-rust \ + && echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep + +# Ensure we are ready with cargo hakari and cargo deny +RUN cargo install cargo-hakari && \ + cargo install cargo-deny && \ + chown -R rust:rust /usr/local/cargo + +USER rust +ENV PATH /home/rust/.local/bin:/home/rust/bin:${PATH} + +CMD ["/bin/bash"] diff --git a/docker/Dockerfile.ci.dockerignore b/docker/Dockerfile.ci.dockerignore new file mode 100644 index 00000000000..484eb504ccf --- /dev/null +++ b/docker/Dockerfile.ci.dockerignore @@ -0,0 +1,2 @@ +# Ignore everything +** diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh new file mode 100755 index 00000000000..0af46f97ed1 --- /dev/null +++ b/docker/entrypoint.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +set -eu -o pipefail + +args=( "$@" ) +for i in "${!args[@]}"; do + args[$i]="$(echo "${args[$i]}" | envsubst)" +done + +exec "$PACKAGE" "${args[@]}" diff --git a/influxdb3/Cargo.toml b/influxdb3/Cargo.toml new file mode 100644 index 00000000000..c0c68d1ba08 --- /dev/null +++ b/influxdb3/Cargo.toml @@ -0,0 +1,95 @@ +[package] +name = "influxdb3" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +# Core Crates +authz.workspace = true +clap_blocks.workspace = true +datafusion_util.workspace = true +iox_query.workspace = true +iox_time.workspace = true +ioxd_common.workspace = true +metric.workspace = true +object_store.workspace = true +observability_deps.workspace = true +panic_logging.workspace = true +parquet_file.workspace = true +tokio_metrics_bridge.workspace = true +trace.workspace = true +trace_exporters.workspace = true +trogging.workspace = true + +# Local Crates +influxdb3_client = { path = "../influxdb3_client" } +influxdb3_process = { path = "../influxdb3_process", default-features = false } +influxdb3_server = { path = "../influxdb3_server" } +influxdb3_write = { path = "../influxdb3_write" } + +# Crates.io dependencies +backtrace.workspace = true +base64.workspace = true +clap.workspace = true +dotenvy.workspace = true +hex.workspace = true +libc.workspace = true +num_cpus.workspace = true +once_cell.workspace = true +parking_lot.workspace = true +rand.workspace = true +secrecy.workspace = true +sha2.workspace = true +thiserror.workspace = true +tokio.workspace = true +tokio-util.workspace = true +url.workspace = true +uuid.workspace = true + +# Optional Dependencies +console-subscriber = { version = "0.1.10", optional = true, features = ["parking_lot"] } + +[features] +default = ["jemalloc_replacing_malloc", "azure", "gcp", "aws"] + +azure = ["clap_blocks/azure"] # Optional Azure Object store support +gcp = ["clap_blocks/gcp"] # Optional GCP object store support +aws = ["clap_blocks/aws"] # Optional AWS / S3 object store support +pprof = ["ioxd_common/pprof"] # Optional http://localhost:8080/debug/pprof/profile support +heappy = ["ioxd_common/heappy", "influxdb3_process/heappy"] # Optional http://localhost:8080/debug/pproc/alloc support + +# Enable tokio_console support (https://github.com/tokio-rs/console) +# +# Requires enabling trace level tracing events for [tokio,runtime]. +tokio_console = ["console-subscriber", "tokio/tracing", "observability_deps/release_max_level_trace"] + +# heappy is an optional feature; Not on by default as it +# runtime overhead on all allocations (calls to malloc). +# Cargo cannot currently implement mutually exclusive features so let's force every build +# to pick either heappy or jemalloc_replacing_malloc feature at least until we figure out something better. +jemalloc_replacing_malloc = ["influxdb3_process/jemalloc_replacing_malloc"] + +# Implicit feature selected when running under `clippy --all-features` to accept mutable exclusive features during +# linting +clippy = [] + +[dev-dependencies] +# Core Crates +arrow_util.workspace = true +influxdb_iox_client.workspace = true + +# Crates.io dependencies in alphabetical order: +arrow.workspace = true +arrow-array.workspace = true +arrow-flight.workspace = true +assert_cmd.workspace = true +futures.workspace = true +hyper.workspace = true +pretty_assertions.workspace = true +reqwest.workspace = true +serde_json.workspace = true +test_helpers.workspace = true +tonic.workspace = true +tower.workspace = true diff --git a/influxdb3/src/commands/common.rs b/influxdb3/src/commands/common.rs new file mode 100644 index 00000000000..7a443fd9e25 --- /dev/null +++ b/influxdb3/src/commands/common.rs @@ -0,0 +1,23 @@ +use clap::Parser; +use secrecy::Secret; +use url::Url; + +#[derive(Debug, Parser)] +pub struct InfluxDb3Config { + /// The host URL of the running InfluxDB 3.0 server + #[clap( + short = 'h', + long = "host", + env = "INFLUXDB3_HOST_URL", + default_value = "http://127.0.0.1:8181" + )] + pub host_url: Url, + + /// The database name to run the query against + #[clap(short = 'd', long = "dbname", env = "INFLUXDB3_DATABASE_NAME")] + pub database_name: String, + + /// The token for authentication with the InfluxDB 3.0 server + #[clap(long = "token", env = "INFLUXDB3_AUTH_TOKEN")] + pub auth_token: Option>, +} diff --git a/influxdb3/src/commands/create.rs b/influxdb3/src/commands/create.rs new file mode 100644 index 00000000000..3252b5b88af --- /dev/null +++ b/influxdb3/src/commands/create.rs @@ -0,0 +1,44 @@ +use base64::engine::general_purpose::URL_SAFE_NO_PAD as B64; +use base64::Engine as _; +use rand::rngs::OsRng; +use rand::RngCore; +use sha2::Digest; +use sha2::Sha512; +use std::error::Error; +use std::str; + +#[derive(Debug, clap::Parser)] +pub struct Config { + #[clap(subcommand)] + cmd: SubCommand, +} + +#[derive(Debug, clap::Parser)] +pub enum SubCommand { + Token, +} + +pub fn command(config: Config) -> Result<(), Box> { + match config.cmd { + SubCommand::Token => { + let token = { + let mut token = String::from("apiv3_"); + let mut key = [0u8; 64]; + OsRng.fill_bytes(&mut key); + token.push_str(&B64.encode(key)); + token + }; + println!( + "\ + Token: {token}\n\ + Hashed Token: {hashed}\n\n\ + Start the server with `influxdb3 serve --bearer-token {hashed}`\n\n\ + HTTP requests require the following header: \"Authorization: Bearer {token}\"\n\ + This will grant you access to every HTTP endpoint or deny it otherwise + ", + hashed = hex::encode(&Sha512::digest(&token)[..]) + ); + } + } + Ok(()) +} diff --git a/influxdb3/src/commands/query.rs b/influxdb3/src/commands/query.rs new file mode 100644 index 00000000000..500c3427bf6 --- /dev/null +++ b/influxdb3/src/commands/query.rs @@ -0,0 +1,170 @@ +use std::str::Utf8Error; + +use clap::{Parser, ValueEnum}; +use secrecy::ExposeSecret; +use tokio::{ + fs::OpenOptions, + io::{self, AsyncWriteExt}, +}; + +use super::common::InfluxDb3Config; + +#[derive(Debug, thiserror::Error)] +pub(crate) enum Error { + #[error(transparent)] + Client(#[from] influxdb3_client::Error), + + #[error(transparent)] + Query(#[from] QueryError), + + #[error("invlid UTF8 received from server: {0}")] + Utf8(#[from] Utf8Error), + + #[error("io error: {0}")] + Io(#[from] io::Error), + + #[error( + "must specify an output file path with `--output` parameter when formatting\ + the output as `parquet`" + )] + NoOutputFileForParquet, +} + +pub type Result = std::result::Result; + +#[derive(Debug, Parser)] +#[clap(visible_alias = "q", trailing_var_arg = true)] +pub struct Config { + /// Common InfluxDB 3.0 config + #[clap(flatten)] + influxdb3_config: InfluxDb3Config, + + /// The query language used to format the provided query string + #[clap( + value_enum, + long = "lang", + short = 'l', + default_value_t = QueryLanguage::Sql, + )] + language: QueryLanguage, + + /// The format in which to output the query + /// + /// If `--fmt` is set to `parquet`, then you must also specify an output + /// file path with `--output`. + #[clap(value_enum, long = "fmt", default_value = "pretty")] + output_format: Format, + + /// Put all query output into `output` + #[clap(short = 'o', long = "output")] + output_file_path: Option, + + /// The query string to execute + query: Vec, +} + +#[derive(Debug, ValueEnum, Clone)] +#[clap(rename_all = "snake_case")] +enum Format { + Pretty, + Json, + Csv, + Parquet, +} + +impl Format { + fn is_parquet(&self) -> bool { + matches!(self, Self::Parquet) + } +} + +impl From for influxdb3_client::Format { + fn from(this: Format) -> Self { + match this { + Format::Pretty => Self::Pretty, + Format::Json => Self::Json, + Format::Csv => Self::Csv, + Format::Parquet => Self::Parquet, + } + } +} + +#[derive(Debug, ValueEnum, Clone)] +enum QueryLanguage { + Sql, + Influxql, +} + +pub(crate) async fn command(config: Config) -> Result<()> { + let InfluxDb3Config { + host_url, + database_name, + auth_token, + } = config.influxdb3_config; + let mut client = influxdb3_client::Client::new(host_url)?; + if let Some(t) = auth_token { + client = client.with_auth_token(t.expose_secret()); + } + + let query = parse_query(config.query)?; + + // make the query using the client + let mut resp_bytes = match config.language { + QueryLanguage::Sql => { + client + .api_v3_query_sql(database_name, query) + .format(config.output_format.clone().into()) + .send() + .await? + } + QueryLanguage::Influxql => { + client + .api_v3_query_influxql(database_name, query) + .format(config.output_format.clone().into()) + .send() + .await? + } + }; + + // write to file if output path specified + if let Some(path) = &config.output_file_path { + let mut f = OpenOptions::new() + .write(true) + .create(true) + .truncate(true) + .open(path) + .await?; + f.write_all_buf(&mut resp_bytes).await?; + } else { + if config.output_format.is_parquet() { + Err(Error::NoOutputFileForParquet)? + } + println!("{}", std::str::from_utf8(&resp_bytes)?); + } + + Ok(()) +} + +#[derive(Debug, thiserror::Error)] +pub(crate) enum QueryError { + #[error("no query provided")] + NoQuery, + + #[error( + "ensure that a single query string is provided as the final \ + argument, enclosed in quotes" + )] + MoreThanOne, +} + +/// Parse the user-inputted query string +fn parse_query(mut input: Vec) -> Result { + if input.is_empty() { + Err(QueryError::NoQuery)? + } + if input.len() > 1 { + Err(QueryError::MoreThanOne)? + } else { + Ok(input.remove(0)) + } +} diff --git a/influxdb3/src/commands/serve.rs b/influxdb3/src/commands/serve.rs new file mode 100644 index 00000000000..f2dd26566dc --- /dev/null +++ b/influxdb3/src/commands/serve.rs @@ -0,0 +1,308 @@ +//! Entrypoint for InfluxDB 3.0 Edge Server + +use clap_blocks::{ + memory_size::MemorySize, + object_store::{make_object_store, ObjectStoreConfig}, + socket_addr::SocketAddr, +}; +use datafusion_util::config::register_iox_object_store; +use influxdb3_process::{ + build_malloc_conf, setup_metric_registry, INFLUXDB3_GIT_HASH, INFLUXDB3_VERSION, PROCESS_UUID, +}; +use influxdb3_server::{ + auth::AllOrNothingAuthorizer, builder::ServerBuilder, query_executor::QueryExecutorImpl, serve, + CommonServerState, +}; +use influxdb3_write::persister::PersisterImpl; +use influxdb3_write::wal::WalImpl; +use influxdb3_write::write_buffer::WriteBufferImpl; +use influxdb3_write::SegmentDuration; +use iox_query::exec::{Executor, ExecutorConfig}; +use iox_time::SystemProvider; +use ioxd_common::reexport::trace_http::ctx::TraceHeaderParser; +use object_store::DynObjectStore; +use observability_deps::tracing::*; +use panic_logging::SendPanicsToTracing; +use parquet_file::storage::{ParquetStorage, StorageId}; +use std::collections::HashMap; +use std::{ + num::NonZeroUsize, + path::{Path, PathBuf}, + sync::Arc, +}; +use thiserror::Error; +use tokio_util::sync::CancellationToken; +use trace_exporters::TracingConfig; +use trogging::cli::LoggingConfig; + +/// The default name of the influxdb_iox data directory +#[allow(dead_code)] +pub const DEFAULT_DATA_DIRECTORY_NAME: &str = ".influxdb3"; + +/// The default bind address for the HTTP API. +pub const DEFAULT_HTTP_BIND_ADDR: &str = "127.0.0.1:8181"; + +#[derive(Debug, Error)] +pub enum Error { + #[error("Cannot parse object store config: {0}")] + ObjectStoreParsing(#[from] clap_blocks::object_store::ParseError), + + #[error("Tracing config error: {0}")] + TracingConfig(#[from] trace_exporters::Error), + + #[error("Server error: {0}")] + Server(#[from] influxdb3_server::Error), + + #[error("Wal error: {0}")] + Wal(#[from] influxdb3_write::wal::Error), + + #[error("Write buffer error: {0}")] + WriteBuffer(#[from] influxdb3_write::write_buffer::Error), + + #[error("invalid token: {0}")] + InvalidToken(#[from] hex::FromHexError), +} + +pub type Result = std::result::Result; + +#[derive(Debug, clap::Parser)] +pub struct Config { + /// Maximum size of HTTP requests. + #[clap( + long = "max-http-request-size", + env = "INFLUXDB3_MAX_HTTP_REQUEST_SIZE", + default_value = "10485760", // 10 MiB + action, + )] + pub max_http_request_size: usize, + + #[clap(flatten)] + object_store_config: ObjectStoreConfig, + + /// The directory to store the write ahead log + /// + /// If not specified, defaults to INFLUXDB3_DB_DIR/wal + #[clap(long = "wal-directory", env = "INFLUXDB3_WAL_DIRECTORY", action)] + pub wal_directory: Option, + + /// The address on which InfluxDB will serve HTTP API requests + #[clap( + long = "http-bind", + env = "INFLUXDB3_HTTP_BIND_ADDR", + default_value = DEFAULT_HTTP_BIND_ADDR, + action, + )] + pub http_bind_address: SocketAddr, + + /// Size of the RAM cache used to store data in bytes. + /// + /// Can be given as absolute value or in percentage of the total available memory (e.g. `10%`). + #[clap( + long = "ram-pool-data-bytes", + env = "INFLUXDB3_RAM_POOL_DATA_BYTES", + default_value = "1073741824", // 1GB + action + )] + pub ram_pool_data_bytes: MemorySize, + + /// Size of memory pool used during query exec, in bytes. + /// + /// Can be given as absolute value or in percentage of the total available memory (e.g. `10%`). + #[clap( + long = "exec-mem-pool-bytes", + env = "INFLUXDB3_EXEC_MEM_POOL_BYTES", + default_value = "8589934592", // 8GB + action + )] + pub exec_mem_pool_bytes: MemorySize, + + /// logging options + #[clap(flatten)] + pub(crate) logging_config: LoggingConfig, + + /// tracing options + #[clap(flatten)] + pub(crate) tracing_config: TracingConfig, + + /// DataFusion config. + #[clap( + long = "datafusion-config", + env = "INFLUXDB_IOX_DATAFUSION_CONFIG", + default_value = "", + value_parser = parse_datafusion_config, + action + )] + pub datafusion_config: HashMap, + + /// bearer token to be set for requests + #[clap(long = "bearer-token", env = "INFLUXDB3_BEARER_TOKEN", action)] + pub bearer_token: Option, + + /// Duration of wal segments that are persisted to object storage. Valid values: 1m, 5m, 10m, + /// 15m, 30m, 1h, 2h, 4h. + #[clap( + long = "segment-duration", + env = "INFLUXDB3_SEGMENT_DURATION", + default_value = "1h", + action + )] + pub segment_duration: SegmentDuration, +} + +/// If `p` does not exist, try to create it as a directory. +/// +/// panic's if the directory does not exist and can not be created +#[allow(dead_code)] +fn ensure_directory_exists(p: &Path) { + if !p.exists() { + info!( + p=%p.display(), + "Creating directory", + ); + std::fs::create_dir_all(p).expect("Could not create default directory"); + } +} + +pub async fn command(config: Config) -> Result<()> { + let num_cpus = num_cpus::get(); + let build_malloc_conf = build_malloc_conf(); + info!( + git_hash = %INFLUXDB3_GIT_HASH as &str, + version = %INFLUXDB3_VERSION.as_ref() as &str, + uuid = %PROCESS_UUID.as_ref() as &str, + num_cpus, + %build_malloc_conf, + "InfluxDB3 Edge server starting", + ); + + let metrics = setup_metric_registry(); + + // Install custom panic handler and forget about it. + // + // This leaks the handler and prevents it from ever being dropped during the + // lifetime of the program - this is actually a good thing, as it prevents + // the panic handler from being removed while unwinding a panic (which in + // turn, causes a panic - see #548) + let f = SendPanicsToTracing::new_with_metrics(&metrics); + std::mem::forget(f); + + // Construct a token to trigger clean shutdown + let frontend_shutdown = CancellationToken::new(); + + let object_store: Arc = + make_object_store(&config.object_store_config).map_err(Error::ObjectStoreParsing)?; + + let trace_exporter = config.tracing_config.build()?; + + // TODO: make this a parameter + let num_threads = + NonZeroUsize::new(num_cpus::get()).unwrap_or_else(|| NonZeroUsize::new(1).unwrap()); + + info!(%num_threads, "Creating shared query executor"); + let parquet_store = + ParquetStorage::new(Arc::clone(&object_store), StorageId::from("influxdb3")); + let exec = Arc::new(Executor::new_with_config( + "datafusion", + ExecutorConfig { + num_threads, + target_query_partitions: num_threads, + object_stores: [&parquet_store] + .into_iter() + .map(|store| (store.id(), Arc::clone(store.object_store()))) + .collect(), + metric_registry: Arc::clone(&metrics), + mem_pool_size: config.exec_mem_pool_bytes.bytes(), + }, + )); + let runtime_env = exec.new_context().inner().runtime_env(); + register_iox_object_store(runtime_env, parquet_store.id(), Arc::clone(&object_store)); + + let trace_header_parser = TraceHeaderParser::new() + .with_jaeger_trace_context_header_name( + config + .tracing_config + .traces_jaeger_trace_context_header_name, + ) + .with_jaeger_debug_name(config.tracing_config.traces_jaeger_debug_name); + + let common_state = CommonServerState::new( + Arc::clone(&metrics), + trace_exporter, + trace_header_parser, + *config.http_bind_address, + )?; + let persister = Arc::new(PersisterImpl::new(Arc::clone(&object_store))); + let wal: Option> = config + .wal_directory + .map(|dir| WalImpl::new(dir).map(Arc::new)) + .transpose()?; + + let time_provider = Arc::new(SystemProvider::new()); + let write_buffer = Arc::new( + WriteBufferImpl::new( + Arc::clone(&persister), + wal, + Arc::clone(&time_provider), + config.segment_duration, + Arc::clone(&exec), + ) + .await?, + ); + let query_executor = Arc::new(QueryExecutorImpl::new( + write_buffer.catalog(), + Arc::clone(&write_buffer), + Arc::clone(&exec), + Arc::clone(&metrics), + Arc::new(config.datafusion_config), + 10, + )); + + let builder = ServerBuilder::new(common_state) + .max_request_size(config.max_http_request_size) + .write_buffer(write_buffer) + .query_executor(query_executor) + .time_provider(time_provider) + .persister(persister); + + let server = if let Some(token) = config.bearer_token.map(hex::decode).transpose()? { + builder + .authorizer(Arc::new(AllOrNothingAuthorizer::new(token))) + .build() + } else { + builder.build() + }; + serve(server, frontend_shutdown).await?; + + Ok(()) +} + +fn parse_datafusion_config( + s: &str, +) -> Result, Box> { + let s = s.trim(); + if s.is_empty() { + return Ok(HashMap::with_capacity(0)); + } + + let mut out = HashMap::new(); + for part in s.split(',') { + let kv = part.trim().splitn(2, ':').collect::>(); + match kv.as_slice() { + [key, value] => { + let key_owned = key.trim().to_owned(); + let value_owned = value.trim().to_owned(); + let existed = out.insert(key_owned, value_owned).is_some(); + if existed { + return Err(format!("key '{key}' passed multiple times").into()); + } + } + _ => { + return Err( + format!("Invalid key value pair - expected 'KEY:VALUE' got '{s}'").into(), + ); + } + } + } + + Ok(out) +} diff --git a/influxdb3/src/commands/write.rs b/influxdb3/src/commands/write.rs new file mode 100644 index 00000000000..ad7556e98f6 --- /dev/null +++ b/influxdb3/src/commands/write.rs @@ -0,0 +1,65 @@ +use clap::Parser; +use secrecy::ExposeSecret; +use tokio::{ + fs::File, + io::{self, AsyncReadExt}, +}; + +use super::common::InfluxDb3Config; + +#[derive(Debug, thiserror::Error)] +pub(crate) enum Error { + #[error(transparent)] + Client(#[from] influxdb3_client::Error), + + #[error("error reading file: {0}")] + Io(#[from] io::Error), +} + +pub(crate) type Result = std::result::Result; + +#[derive(Debug, Parser)] +#[clap(visible_alias = "w", trailing_var_arg = true)] +pub struct Config { + /// Common InfluxDB 3.0 config + #[clap(flatten)] + influxdb3_config: InfluxDb3Config, + + /// File path to load the write data from + /// + /// Currently, only files containing line protocol are supported. + #[clap(short = 'f', long = "file")] + file_path: String, + + /// Flag to request the server accept partial writes + /// + /// Invalid lines in the input data will be ignored by the server. + #[clap(long = "accept-partial")] + accept_partial_writes: bool, +} + +pub(crate) async fn command(config: Config) -> Result<()> { + let InfluxDb3Config { + host_url, + database_name, + auth_token, + } = config.influxdb3_config; + let mut client = influxdb3_client::Client::new(host_url)?; + if let Some(t) = auth_token { + client = client.with_auth_token(t.expose_secret()); + } + + let mut f = File::open(config.file_path).await?; + let mut writes = Vec::new(); + f.read_to_end(&mut writes).await?; + + let mut req = client.api_v3_write_lp(database_name); + if config.accept_partial_writes { + req = req.accept_partial(true); + } + req.body(writes).send().await?; + + println!("success"); + + Ok(()) +} diff --git a/influxdb3/src/main.rs b/influxdb3/src/main.rs new file mode 100644 index 00000000000..8e00d4457da --- /dev/null +++ b/influxdb3/src/main.rs @@ -0,0 +1,279 @@ +//! Entrypoint of InfluxDB IOx binary +#![recursion_limit = "512"] // required for print_cpu +#![deny(rustdoc::broken_intra_doc_links, rustdoc::bare_urls, rust_2018_idioms)] +#![warn( +missing_debug_implementations, +clippy::explicit_iter_loop, +clippy::use_self, +clippy::clone_on_ref_ptr, +// See https://github.com/influxdata/influxdb_iox/pull/1671 +clippy::future_not_send +)] + +use dotenvy::dotenv; +use influxdb3_process::VERSION_STRING; +use observability_deps::tracing::warn; +use std::sync::{ + atomic::{AtomicUsize, Ordering}, + Arc, +}; +use tokio::runtime::Runtime; +use trogging::{ + cli::LoggingConfigBuilderExt, + tracing_subscriber::{prelude::*, Registry}, + TroggingGuard, +}; + +mod commands { + pub(crate) mod common; + pub mod create; + pub mod query; + pub mod serve; + pub mod write; +} + +enum ReturnCode { + Failure = 1, +} + +#[cfg(all( + feature = "heappy", + feature = "jemalloc_replacing_malloc", + not(feature = "clippy") +))] +compile_error!("heappy and jemalloc_replacing_malloc features are mutually exclusive"); + +#[derive(Debug, clap::Parser)] +#[clap( +name = "influxdb3", +version = &VERSION_STRING[..], +disable_help_flag = true, +arg( +clap::Arg::new("help") +.long("help") +.help("Print help information") +.action(clap::ArgAction::Help) +.global(true) +), +about = "InfluxDB 3.0 Edge server and command line tools", +long_about = r#"InfluxDB 3.0 Edge server and command line tools + +Examples: + # Run the InfluxDB 3.0 Edge server + influxdb3 serve + + # Display all commands + influxdb3 --help + + # Run the InfluxDB 3.0 Edge server in all-in-one mode with extra verbose logging + influxdb3 serve -v + + # Run InfluxDB 3.0 Edge with full debug logging specified with LOG_FILTER + LOG_FILTER=debug influxdb3 serve +"# +)] +struct Config { + #[clap(subcommand)] + command: Option, +} + +// Ignoring clippy here since this enum is just used for running +// the CLI command +#[allow(clippy::large_enum_variant)] +#[derive(Debug, clap::Parser)] +#[allow(clippy::large_enum_variant)] +enum Command { + /// Run the InfluxDB 3.0 server + Serve(commands::serve::Config), + + /// Perform a query against a running InfluxDB 3.0 server + Query(commands::query::Config), + + /// Perform a set of writes to a running InfluxDB 3.0 server + Write(commands::write::Config), + + /// Create new resources + Create(commands::create::Config), +} + +fn main() -> Result<(), std::io::Error> { + install_crash_handler(); // attempt to render a useful stacktrace to stderr + + // load all environment variables from .env before doing anything + load_dotenv(); + + let config: Config = clap::Parser::parse(); + + let tokio_runtime = get_runtime(None)?; + tokio_runtime.block_on(async move { + fn handle_init_logs(r: Result) -> TroggingGuard { + match r { + Ok(guard) => guard, + Err(e) => { + eprintln!("Initializing logs failed: {e}"); + std::process::exit(ReturnCode::Failure as _); + } + } + } + + match config.command { + None => println!("command required, --help for help"), + Some(Command::Serve(config)) => { + let _tracing_guard = + handle_init_logs(init_logs_and_tracing(&config.logging_config)); + if let Err(e) = commands::serve::command(config).await { + eprintln!("Serve command failed: {e}"); + std::process::exit(ReturnCode::Failure as _) + } + } + Some(Command::Query(config)) => { + if let Err(e) = commands::query::command(config).await { + eprintln!("Query command failed: {e}"); + std::process::exit(ReturnCode::Failure as _) + } + } + Some(Command::Write(config)) => { + if let Err(e) = commands::write::command(config).await { + eprintln!("Write command failed: {e}"); + std::process::exit(ReturnCode::Failure as _) + } + } + Some(Command::Create(config)) => { + if let Err(e) = commands::create::command(config) { + eprintln!("Create command failed: {e}"); + std::process::exit(ReturnCode::Failure as _) + } + } + } + }); + + Ok(()) +} + +/// Creates the tokio runtime for executing IOx +/// +/// if nthreads is none, uses the default scheduler +/// otherwise, creates a scheduler with the number of threads +fn get_runtime(num_threads: Option) -> Result { + // NOTE: no log macros will work here! + // + // That means use eprintln!() instead of error!() and so on. The log emitter + // requires a running tokio runtime and is initialised after this function. + + use tokio::runtime::Builder; + let kind = std::io::ErrorKind::Other; + match num_threads { + None => Runtime::new(), + Some(num_threads) => { + println!("Setting number of threads to '{num_threads}' per command line request"); + + let thread_counter = Arc::new(AtomicUsize::new(1)); + match num_threads { + 0 => { + let msg = + format!("Invalid num-threads: '{num_threads}' must be greater than zero"); + Err(std::io::Error::new(kind, msg)) + } + 1 => Builder::new_current_thread().enable_all().build(), + _ => Builder::new_multi_thread() + .enable_all() + .thread_name_fn(move || { + format!("IOx main {}", thread_counter.fetch_add(1, Ordering::SeqCst)) + }) + .worker_threads(num_threads) + .build(), + } + } + } +} + +/// Source the .env file before initialising the Config struct - this sets +/// any envs in the file, which the Config struct then uses. +/// +/// Precedence is given to existing env variables. +fn load_dotenv() { + match dotenv() { + Ok(_) => {} + Err(dotenvy::Error::Io(err)) if err.kind() == std::io::ErrorKind::NotFound => { + // Ignore this - a missing env file is not an error, defaults will + // be applied when initialising the Config struct. + } + Err(e) => { + eprintln!("FATAL Error loading config from: {e}"); + eprintln!("Aborting"); + std::process::exit(1); + } + }; +} + +// Based on ideas from +// https://github.com/servo/servo/blob/f03ddf6c6c6e94e799ab2a3a89660aea4a01da6f/ports/servo/main.rs#L58-L79 +fn install_crash_handler() { + unsafe { + set_signal_handler(libc::SIGSEGV, signal_handler); // handle segfaults + set_signal_handler(libc::SIGILL, signal_handler); // handle stack overflow and unsupported CPUs + set_signal_handler(libc::SIGBUS, signal_handler); // handle invalid memory access + } +} + +unsafe extern "C" fn signal_handler(sig: i32) { + use backtrace::Backtrace; + use std::process::abort; + let name = std::thread::current() + .name() + .map(|n| format!(" for thread \"{n}\"")) + .unwrap_or_else(|| "".to_owned()); + eprintln!( + "Signal {}, Stack trace{}\n{:?}", + sig, + name, + Backtrace::new() + ); + abort(); +} + +// based on https://github.com/adjivas/sig/blob/master/src/lib.rs#L34-L52 +unsafe fn set_signal_handler(signal: libc::c_int, handler: unsafe extern "C" fn(libc::c_int)) { + use libc::{sigaction, sigfillset, sighandler_t}; + let mut sigset = std::mem::zeroed(); + + // Block all signals during the handler. This is the expected behavior, but + // it's not guaranteed by `signal()`. + if sigfillset(&mut sigset) != -1 { + // Done because sigaction has private members. + // This is safe because sa_restorer and sa_handlers are pointers that + // might be null (that is, zero). + let mut action: sigaction = std::mem::zeroed(); + + // action.sa_flags = 0; + action.sa_mask = sigset; + action.sa_sigaction = handler as sighandler_t; + + sigaction(signal, &action, std::ptr::null_mut()); + } +} + +fn init_logs_and_tracing( + config: &trogging::cli::LoggingConfig, +) -> Result { + let log_layer = trogging::Builder::new() + .with_default_log_filter("info") + .with_logging_config(config) + .build()?; + + let layers = log_layer; + + // Optionally enable the tokio console exporter layer, if enabled. + // + // This spawns a background tokio task to serve the instrumentation data, + // and hooks the instrumentation into the tracing pipeline. + #[cfg(feature = "tokio_console")] + let layers = { + use console_subscriber::ConsoleLayer; + let console_layer = ConsoleLayer::builder().with_default_env().spawn(); + layers.and_then(console_layer) + }; + + let subscriber = Registry::default().with(layers); + trogging::install_global(subscriber) +} diff --git a/influxdb3/tests/server/auth.rs b/influxdb3/tests/server/auth.rs new file mode 100644 index 00000000000..2d8a7516f69 --- /dev/null +++ b/influxdb3/tests/server/auth.rs @@ -0,0 +1,325 @@ +use arrow_flight::error::FlightError; +use arrow_util::assert_batches_sorted_eq; +use influxdb3_client::Precision; +use reqwest::StatusCode; + +use crate::{collect_stream, TestServer}; + +#[tokio::test] +async fn auth() { + const HASHED_TOKEN: &str = "5315f0c4714537843face80cca8c18e27ce88e31e9be7a5232dc4dc8444f27c0227a9bd64831d3ab58f652bd0262dd8558dd08870ac9e5c650972ce9e4259439"; + const TOKEN: &str = "apiv3_mp75KQAhbqv0GeQXk8MPuZ3ztaLEaR5JzS8iifk1FwuroSVyXXyrJK1c4gEr1kHkmbgzDV-j3MvQpaIMVJBAiA"; + + let server = TestServer::configure() + .auth_token(HASHED_TOKEN, TOKEN) + .spawn() + .await; + + let client = reqwest::Client::new(); + let base = server.client_addr(); + let write_lp_url = format!("{base}/api/v3/write_lp"); + let write_lp_params = [("db", "foo")]; + let query_sql_url = format!("{base}/api/v3/query_sql"); + let query_sql_params = [("db", "foo"), ("q", "select * from cpu")]; + + assert_eq!( + client + .post(&write_lp_url) + .query(&write_lp_params) + .body("cpu,host=a val=1i 123") + .send() + .await + .unwrap() + .status(), + StatusCode::UNAUTHORIZED + ); + assert_eq!( + client + .get(&query_sql_url) + .query(&query_sql_params) + .send() + .await + .unwrap() + .status(), + StatusCode::UNAUTHORIZED + ); + assert_eq!( + client + .post(&write_lp_url) + .query(&write_lp_params) + .body("cpu,host=a val=1i 123") + .bearer_auth(TOKEN) + .send() + .await + .unwrap() + .status(), + StatusCode::OK + ); + assert_eq!( + client + .get(&query_sql_url) + .query(&query_sql_params) + .bearer_auth(TOKEN) + .send() + .await + .unwrap() + .status(), + StatusCode::OK + ); + // Malformed Header Tests + // Test that there is an extra string after the token foo + assert_eq!( + client + .get(&query_sql_url) + .query(&query_sql_params) + .header("Authorization", format!("Bearer {TOKEN} whee")) + .send() + .await + .unwrap() + .status(), + StatusCode::BAD_REQUEST + ); + assert_eq!( + client + .get(&query_sql_url) + .query(&query_sql_params) + .header("Authorization", format!("bearer {TOKEN}")) + .send() + .await + .unwrap() + .status(), + StatusCode::BAD_REQUEST + ); + assert_eq!( + client + .get(&query_sql_url) + .query(&query_sql_params) + .header("Authorization", "Bearer") + .send() + .await + .unwrap() + .status(), + StatusCode::BAD_REQUEST + ); + assert_eq!( + client + .get(&query_sql_url) + .query(&query_sql_params) + .header("auth", format!("Bearer {TOKEN}")) + .send() + .await + .unwrap() + .status(), + StatusCode::UNAUTHORIZED + ); +} + +#[tokio::test] +async fn auth_grpc() { + const HASHED_TOKEN: &str = "5315f0c4714537843face80cca8c18e27ce88e31e9be7a5232dc4dc8444f27c0227a9bd64831d3ab58f652bd0262dd8558dd08870ac9e5c650972ce9e4259439"; + const TOKEN: &str = "apiv3_mp75KQAhbqv0GeQXk8MPuZ3ztaLEaR5JzS8iifk1FwuroSVyXXyrJK1c4gEr1kHkmbgzDV-j3MvQpaIMVJBAiA"; + + let server = TestServer::configure() + .auth_token(HASHED_TOKEN, TOKEN) + .spawn() + .await; + + // Write some data to the server, this will be authorized through the HTTP API + server + .write_lp_to_db( + "foo", + "cpu,host=s1,region=us-east usage=0.9 1\n\ + cpu,host=s1,region=us-east usage=0.89 2\n\ + cpu,host=s1,region=us-east usage=0.85 3", + Precision::Nanosecond, + ) + .await + .unwrap(); + + // Check that with a valid authorization header, it succeeds: + for header in ["authorization", "Authorization"] { + // Spin up a FlightSQL client + let mut client = server.flight_sql_client("foo").await; + + // Set the authorization header on the client: + client + .add_header(header, &format!("Bearer {TOKEN}")) + .unwrap(); + + // Make the query again, this time it should work: + let response = client + .query("SELECT host, region, time, usage FROM cpu") + .await + .unwrap(); + let batches = collect_stream(response).await; + assert_batches_sorted_eq!( + [ + "+------+---------+--------------------------------+-------+", + "| host | region | time | usage |", + "+------+---------+--------------------------------+-------+", + "| s1 | us-east | 1970-01-01T00:00:00.000000001Z | 0.9 |", + "| s1 | us-east | 1970-01-01T00:00:00.000000002Z | 0.89 |", + "| s1 | us-east | 1970-01-01T00:00:00.000000003Z | 0.85 |", + "+------+---------+--------------------------------+-------+", + ], + &batches + ); + } + + // Check that without providing an Authentication header, it gives back + // an Unauthenticated error: + { + let mut client = server.flight_sql_client("foo").await; + let error = client.query("SELECT * FROM cpu").await.unwrap_err(); + assert!(matches!(error, FlightError::Tonic(s) if s.code() == tonic::Code::Unauthenticated)); + } + + // Create some new clients that set the authorization header incorrectly to + // ensure errors are returned: + + // Misspelled "Bearer" + { + let mut client = server.flight_sql_client("foo").await; + client + .add_header("authorization", &format!("bearer {TOKEN}")) + .unwrap(); + let error = client.query("SELECT * FROM cpu").await.unwrap_err(); + assert!(matches!(error, FlightError::Tonic(s) if s.code() == tonic::Code::Unauthenticated)); + } + + // Invalid token, this actually gives Permission denied + { + let mut client = server.flight_sql_client("foo").await; + client + .add_header("authorization", "Bearer invalid-token") + .unwrap(); + let error = client.query("SELECT * FROM cpu").await.unwrap_err(); + assert!( + matches!(error, FlightError::Tonic(s) if s.code() == tonic::Code::PermissionDenied) + ); + } + + // Misspelled header key + { + let mut client = server.flight_sql_client("foo").await; + client + .add_header("auth", &format!("Bearer {TOKEN}")) + .unwrap(); + let error = client.query("SELECT * FROM cpu").await.unwrap_err(); + assert!(matches!(error, FlightError::Tonic(s) if s.code() == tonic::Code::Unauthenticated)); + } +} + +#[tokio::test] +async fn v1_password_parameter() { + const HASHED_TOKEN: &str = "5315f0c4714537843face80cca8c18e27ce88e31e9be7a5232dc4dc8444f27c0227a9bd64831d3ab58f652bd0262dd8558dd08870ac9e5c650972ce9e4259439"; + const TOKEN: &str = "apiv3_mp75KQAhbqv0GeQXk8MPuZ3ztaLEaR5JzS8iifk1FwuroSVyXXyrJK1c4gEr1kHkmbgzDV-j3MvQpaIMVJBAiA"; + + let server = TestServer::configure() + .auth_token(HASHED_TOKEN, TOKEN) + .spawn() + .await; + + let client = reqwest::Client::new(); + let query_url = format!("{base}/query", base = server.client_addr()); + let write_url = format!("{base}/write", base = server.client_addr()); + // Send requests without any authentication: + assert_eq!( + client + .get(&query_url) + .send() + .await + .expect("send request") + .status(), + StatusCode::UNAUTHORIZED, + ); + assert_eq!( + client + .get(&write_url) + .send() + .await + .expect("send request") + .status(), + StatusCode::UNAUTHORIZED, + ); + + // Ensure that an invalid token passed in the `p` parameter is still unauthorized: + assert_eq!( + client + .get(&query_url) + .query(&[("p", "not-the-token-you-were-looking-for")]) + .send() + .await + .expect("send request") + .status(), + StatusCode::UNAUTHORIZED, + ); + assert_eq!( + client + .get(&write_url) + .query(&[("p", "not-the-token-you-were-looking-for")]) + .send() + .await + .expect("send request") + .status(), + StatusCode::UNAUTHORIZED, + ); + + // make some writes so that the query API will work below: + server + .write_lp_to_db("foo", "cpu,host=a usage=0.9", Precision::Second) + .await + .unwrap(); + + // Send request to query API with the token in the v1 `p` parameter: + assert_eq!( + client + .get(&query_url) + .query(&[("p", TOKEN), ("q", "SELECT * FROM cpu"), ("db", "foo")]) + .send() + .await + .expect("send request") + .status(), + StatusCode::OK, + ); + // Send request to query API with the token in auth header: + assert_eq!( + client + .get(&query_url) + .query(&[("q", "SELECT * FROM cpu"), ("db", "foo")]) + .bearer_auth(TOKEN) + .send() + .await + .expect("send request") + .status(), + StatusCode::OK, + ); + + let valid_write_body = "cpu,host=val usage=0.5"; + + // Send request to write API with the token in the v1 `p` parameter: + assert_eq!( + client + .post(&write_url) + .query(&[("p", TOKEN), ("db", "foo")]) + .body(valid_write_body) + .send() + .await + .expect("send request") + .status(), + StatusCode::OK, + ); + // Send request to write API with the token in auth header: + assert_eq!( + client + .post(&write_url) + .bearer_auth(TOKEN) + .query(&[("db", "foo")]) + .body(valid_write_body) + .send() + .await + .expect("send request") + .status(), + StatusCode::OK, + ); +} diff --git a/influxdb3/tests/server/flight.rs b/influxdb3/tests/server/flight.rs new file mode 100644 index 00000000000..53811644893 --- /dev/null +++ b/influxdb3/tests/server/flight.rs @@ -0,0 +1,228 @@ +use arrow_flight::sql::SqlInfo; +use arrow_flight::Ticket; +use arrow_util::assert_batches_sorted_eq; +use influxdb3_client::Precision; +use test_helpers::assert_contains; + +use crate::collect_stream; +use crate::TestServer; + +#[tokio::test] +async fn flight() -> Result<(), influxdb3_client::Error> { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=s1,region=us-east usage=0.9 1\n\ + cpu,host=s1,region=us-east usage=0.89 2\n\ + cpu,host=s1,region=us-east usage=0.85 3", + Precision::Nanosecond, + ) + .await?; + + let mut client = server.flight_sql_client("foo").await; + + // Ad-hoc Query: + { + let response = client + .query("SELECT host, region, time, usage FROM cpu") + .await + .unwrap(); + + let batches = collect_stream(response).await; + assert_batches_sorted_eq!( + [ + "+------+---------+--------------------------------+-------+", + "| host | region | time | usage |", + "+------+---------+--------------------------------+-------+", + "| s1 | us-east | 1970-01-01T00:00:00.000000001Z | 0.9 |", + "| s1 | us-east | 1970-01-01T00:00:00.000000002Z | 0.89 |", + "| s1 | us-east | 1970-01-01T00:00:00.000000003Z | 0.85 |", + "+------+---------+--------------------------------+-------+", + ], + &batches + ); + } + + // Ad-hoc Query error: + { + let error = client + .query("SELECT * FROM invalid_table") + .await + .unwrap_err(); + + assert!(error + .to_string() + .contains("table 'public.iox.invalid_table' not found")); + } + + // Prepared query: + { + let handle = client + .prepare("SELECT host, region, time, usage FROM cpu".into(), None) + .await + .unwrap(); + let stream = client.execute(handle).await.unwrap(); + + let batches = collect_stream(stream).await; + assert_batches_sorted_eq!( + [ + "+------+---------+--------------------------------+-------+", + "| host | region | time | usage |", + "+------+---------+--------------------------------+-------+", + "| s1 | us-east | 1970-01-01T00:00:00.000000001Z | 0.9 |", + "| s1 | us-east | 1970-01-01T00:00:00.000000002Z | 0.89 |", + "| s1 | us-east | 1970-01-01T00:00:00.000000003Z | 0.85 |", + "+------+---------+--------------------------------+-------+", + ], + &batches + ); + } + + // Get SQL Infos: + { + let infos = vec![SqlInfo::FlightSqlServerName as u32]; + let stream = client.get_sql_info(infos).await.unwrap(); + let batches = collect_stream(stream).await; + assert_batches_sorted_eq!( + [ + "+-----------+-----------------------------+", + "| info_name | value |", + "+-----------+-----------------------------+", + "| 0 | {string_value=InfluxDB IOx} |", + "+-----------+-----------------------------+", + ], + &batches + ); + } + + // Get Tables + { + type OptStr = std::option::Option<&'static str>; + let stream = client + .get_tables(OptStr::None, OptStr::None, OptStr::None, vec![], false) + .await + .unwrap(); + let batches = collect_stream(stream).await; + + assert_batches_sorted_eq!( + [ + "+--------------+--------------------+-------------+------------+", + "| catalog_name | db_schema_name | table_name | table_type |", + "+--------------+--------------------+-------------+------------+", + "| public | information_schema | columns | VIEW |", + "| public | information_schema | df_settings | VIEW |", + "| public | information_schema | schemata | VIEW |", + "| public | information_schema | tables | VIEW |", + "| public | information_schema | views | VIEW |", + "| public | iox | cpu | BASE TABLE |", + "+--------------+--------------------+-------------+------------+", + ], + &batches + ); + } + + // Get Catalogs + { + let stream = client.get_catalogs().await.unwrap(); + let batches = collect_stream(stream).await; + assert_batches_sorted_eq!( + [ + "+--------------+", + "| catalog_name |", + "+--------------+", + "| public |", + "+--------------+", + ], + &batches + ); + } + + Ok(()) +} + +#[tokio::test] +async fn flight_influxql() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=s1,region=us-east usage=0.9 1\n\ + cpu,host=s1,region=us-east usage=0.89 2\n\ + cpu,host=s1,region=us-east usage=0.85 3", + Precision::Nanosecond, + ) + .await + .unwrap(); + + let mut client = server.flight_client().await; + + // Ad-hoc query, using qualified measurement name: + { + let ticket = Ticket::new( + r#"{ + "database": "foo", + "sql_query": "SELECT time, host, region, usage FROM foo.autogen.cpu", + "query_type": "influxql" + }"#, + ); + let response = client.do_get(ticket).await.unwrap(); + + let batches = collect_stream(response).await; + assert_batches_sorted_eq!( + [ + "+------------------+--------------------------------+------+---------+-------+", + "| iox::measurement | time | host | region | usage |", + "+------------------+--------------------------------+------+---------+-------+", + "| cpu | 1970-01-01T00:00:00.000000001Z | s1 | us-east | 0.9 |", + "| cpu | 1970-01-01T00:00:00.000000002Z | s1 | us-east | 0.89 |", + "| cpu | 1970-01-01T00:00:00.000000003Z | s1 | us-east | 0.85 |", + "+------------------+--------------------------------+------+---------+-------+", + ], + &batches + ); + } + + // InfluxQL-specific query to show measurements: + { + let ticket = Ticket::new( + r#"{ + "database": "foo", + "sql_query": "SHOW MEASUREMENTS", + "query_type": "influxql" + }"#, + ); + let response = client.do_get(ticket).await.unwrap(); + + let batches = collect_stream(response).await; + assert_batches_sorted_eq!( + [ + "+------------------+------+", + "| iox::measurement | name |", + "+------------------+------+", + "| measurements | cpu |", + "+------------------+------+", + ], + &batches + ); + } + + // An InfluxQL query that is not supported over Flight: + { + let ticket = Ticket::new( + r#"{ + "database": "foo", + "sql_query": "SHOW DATABASES", + "query_type": "influxql" + }"#, + ); + let response = client.do_get(ticket).await.unwrap_err(); + + assert_contains!( + response.to_string(), + "This feature is not implemented: SHOW DATABASES" + ); + } +} diff --git a/influxdb3/tests/server/limits.rs b/influxdb3/tests/server/limits.rs new file mode 100644 index 00000000000..2aca62f077d --- /dev/null +++ b/influxdb3/tests/server/limits.rs @@ -0,0 +1,82 @@ +use crate::TestServer; +use hyper::StatusCode; +use influxdb3_client::Error; +use influxdb3_client::Precision; + +#[tokio::test] +async fn limits() -> Result<(), Error> { + let server = TestServer::spawn().await; + + // Test that a server can't have more than 5 DBs + for db in ["one", "two", "three", "four", "five"] { + server + .write_lp_to_db( + db, + "cpu,host=s1,region=us-east usage=0.9 1\n", + Precision::Nanosecond, + ) + .await?; + } + + let Err(Error::ApiError { code, .. }) = server + .write_lp_to_db( + "six", + "cpu,host=s1,region=us-east usage=0.9 1\n", + Precision::Nanosecond, + ) + .await + else { + panic!("Did not error when adding 6th db"); + }; + assert_eq!(code, StatusCode::UNPROCESSABLE_ENTITY); + + // Test that the server can't have more than 2000 tables + // First create the other needed 1995 tables + let table_lp = (0..1995).fold(String::new(), |mut acc, i| { + acc.push_str("cpu"); + acc.push_str(&i.to_string()); + acc.push_str(",host=s1,region=us-east usage=0.9 1\n"); + acc + }); + + server + .write_lp_to_db("one", &table_lp, Precision::Nanosecond) + .await?; + + let Err(Error::ApiError { code, .. }) = server + .write_lp_to_db( + "six", + "cpu2000,host=s1,region=us-east usage=0.9 1\n", + Precision::Nanosecond, + ) + .await + else { + panic!("Did not error when adding 2001st table"); + }; + assert_eq!(code, StatusCode::UNPROCESSABLE_ENTITY); + + // Test that we can't add a row 500 columns long + let mut lp_500 = String::from("cpu,host=foo,region=bar usage=2"); + let mut lp_501 = String::from("cpu,host=foo,region=bar usage=2"); + for i in 5..=500 { + let column = format!(",column{}=1", i); + lp_500.push_str(&column); + lp_501.push_str(&column); + } + lp_500.push_str(" 0\n"); + lp_501.push_str(",column501=1 0\n"); + + server + .write_lp_to_db("one", &lp_500, Precision::Nanosecond) + .await?; + + let Err(Error::ApiError { code, .. }) = server + .write_lp_to_db("one", &lp_501, Precision::Nanosecond) + .await + else { + panic!("Did not error when adding 501st column"); + }; + assert_eq!(code, StatusCode::UNPROCESSABLE_ENTITY); + + Ok(()) +} diff --git a/influxdb3/tests/server/main.rs b/influxdb3/tests/server/main.rs new file mode 100644 index 00000000000..775012b67eb --- /dev/null +++ b/influxdb3/tests/server/main.rs @@ -0,0 +1,242 @@ +use std::{ + net::{SocketAddr, SocketAddrV4, TcpListener}, + process::{Child, Command, Stdio}, + time::Duration, +}; + +use arrow::record_batch::RecordBatch; +use arrow_flight::{decode::FlightRecordBatchStream, FlightClient}; +use assert_cmd::cargo::CommandCargoExt; +use futures::TryStreamExt; +use influxdb3_client::Precision; +use influxdb_iox_client::flightsql::FlightSqlClient; +use reqwest::Response; + +mod auth; +mod flight; +mod limits; +mod ping; +mod query; +mod write; + +/// Configuration for a [`TestServer`] +#[derive(Debug, Default)] +pub struct TestConfig { + auth_token: Option<(String, String)>, +} + +impl TestConfig { + /// Set the auth token for this [`TestServer`] + pub fn auth_token, R: Into>( + mut self, + hashed_token: S, + raw_token: R, + ) -> Self { + self.auth_token = Some((hashed_token.into(), raw_token.into())); + self + } + + /// Spawn a new [`TestServer`] with this configuration + /// + /// This will run the `influxdb3 serve` command, and bind its HTTP + /// address to a random port on localhost. + pub async fn spawn(self) -> TestServer { + TestServer::spawn_inner(self).await + } + + fn as_args(&self) -> Vec<&str> { + let mut args = vec![]; + if let Some((token, _)) = &self.auth_token { + args.append(&mut vec!["--bearer-token", token]); + } + args + } +} + +/// A running instance of the `influxdb3 serve` process +/// +/// Logs will be emitted to stdout/stderr if the TEST_LOG environment +/// variable is set, e.g., +/// ``` +/// TEST_LOG= cargo test +/// ``` +pub struct TestServer { + config: TestConfig, + bind_addr: SocketAddr, + server_process: Child, + http_client: reqwest::Client, +} + +impl TestServer { + /// Spawn a new [`TestServer`] + /// + /// This will run the `influxdb3 serve` command, and bind its HTTP + /// address to a random port on localhost. + pub async fn spawn() -> Self { + Self::spawn_inner(Default::default()).await + } + + /// Configure a [`TestServer`] before spawning + pub fn configure() -> TestConfig { + TestConfig::default() + } + + async fn spawn_inner(config: TestConfig) -> Self { + let bind_addr = get_local_bind_addr(); + let mut command = Command::cargo_bin("influxdb3").expect("create the influxdb3 command"); + let mut command = command + .arg("serve") + .args(["--http-bind", &bind_addr.to_string()]) + .args(["--object-store", "memory"]) + .args(config.as_args()); + + // If TEST_LOG env var is not defined, discard stdout/stderr + if std::env::var("TEST_LOG").is_err() { + command = command.stdout(Stdio::null()).stderr(Stdio::null()); + } + + let server_process = command.spawn().expect("spawn the influxdb3 server process"); + + let server = Self { + config, + bind_addr, + server_process, + http_client: reqwest::Client::new(), + }; + + server.wait_until_ready().await; + server + } + + /// Get the URL of the running service for use with an HTTP client + pub fn client_addr(&self) -> String { + format!("http://{addr}", addr = self.bind_addr) + } + + /// Get a [`FlightSqlClient`] for making requests to the running service over gRPC + pub async fn flight_sql_client(&self, database: &str) -> FlightSqlClient { + let channel = tonic::transport::Channel::from_shared(self.client_addr()) + .expect("create tonic channel") + .connect() + .await + .expect("connect to gRPC client"); + let mut client = FlightSqlClient::new(channel); + client.add_header("database", database).unwrap(); + client.add_header("iox-debug", "true").unwrap(); + client + } + + /// Get a raw [`FlightClient`] for performing Flight actions directly + pub async fn flight_client(&self) -> FlightClient { + let channel = tonic::transport::Channel::from_shared(self.client_addr()) + .expect("create tonic channel") + .connect() + .await + .expect("connect to gRPC client"); + FlightClient::new(channel) + } + + fn kill(&mut self) { + self.server_process.kill().expect("kill the server process"); + } + + async fn wait_until_ready(&self) { + while self + .http_client + .get(format!("{base}/health", base = self.client_addr())) + .send() + .await + .is_err() + { + tokio::time::sleep(Duration::from_millis(10)).await; + } + } +} + +impl Drop for TestServer { + fn drop(&mut self) { + self.kill(); + } +} + +impl TestServer { + /// Write some line protocol to the server + pub async fn write_lp_to_db( + &self, + database: &str, + lp: impl ToString, + precision: Precision, + ) -> Result<(), influxdb3_client::Error> { + let mut client = influxdb3_client::Client::new(self.client_addr()).unwrap(); + if let Some((_, token)) = &self.config.auth_token { + client = client.with_auth_token(token); + } + client + .api_v3_write_lp(database) + .body(lp.to_string()) + .precision(precision) + .send() + .await + } + + pub async fn api_v3_query_influxql(&self, params: &[(&str, &str)]) -> Response { + self.http_client + .get(format!( + "{base}/api/v3/query_influxql", + base = self.client_addr() + )) + .query(params) + .send() + .await + .expect("send /api/v3/query_influxql request to server") + } + + pub async fn api_v1_query(&self, params: &[(&str, &str)]) -> Response { + self.http_client + .get(format!("{base}/query", base = self.client_addr(),)) + .query(params) + .send() + .await + .expect("send /query request to server") + } +} + +/// Get an available bind address on localhost +/// +/// This binds a [`TcpListener`] to 127.0.0.1:0, which will randomly +/// select an available port, and produces the resulting local address. +/// The [`TcpListener`] is dropped at the end of the function, thus +/// freeing the port for use by the caller. +fn get_local_bind_addr() -> SocketAddr { + let ip = std::net::Ipv4Addr::new(127, 0, 0, 1); + let port = 0; + let addr = SocketAddrV4::new(ip, port); + TcpListener::bind(addr) + .expect("bind to a socket address") + .local_addr() + .expect("get local address") +} + +/// Write to the server with the line protocol +pub async fn write_lp_to_db( + server: &TestServer, + database: &str, + lp: &str, + precision: Precision, +) -> Result<(), influxdb3_client::Error> { + let client = influxdb3_client::Client::new(server.client_addr()).unwrap(); + client + .api_v3_write_lp(database) + .body(lp.to_string()) + .precision(precision) + .send() + .await +} + +#[allow(dead_code)] +pub async fn collect_stream(stream: FlightRecordBatchStream) -> Vec { + stream + .try_collect() + .await + .expect("gather record batch stream") +} diff --git a/influxdb3/tests/server/ping.rs b/influxdb3/tests/server/ping.rs new file mode 100644 index 00000000000..837232a6c0a --- /dev/null +++ b/influxdb3/tests/server/ping.rs @@ -0,0 +1,42 @@ +use hyper::Method; +use serde_json::Value; + +use crate::TestServer; + +#[tokio::test] +async fn test_ping() { + let server = TestServer::spawn().await; + let client = reqwest::Client::new(); + + struct TestCase<'a> { + url: &'a str, + method: Method, + } + + let ping_url = format!("{base}/ping", base = server.client_addr()); + + let test_cases = [ + TestCase { + url: &ping_url, + method: Method::GET, + }, + TestCase { + url: &ping_url, + method: Method::POST, + }, + ]; + + for t in test_cases { + let resp = client + .request(t.method.clone(), t.url) + .send() + .await + .unwrap(); + let json = resp.json::().await.unwrap(); + println!("Method: {}, URL: {}", t.method, t.url); + println!("{json:#}"); + let map = json.as_object().unwrap(); + assert!(map.contains_key("version")); + assert!(map.contains_key("revision")); + } +} diff --git a/influxdb3/tests/server/query.rs b/influxdb3/tests/server/query.rs new file mode 100644 index 00000000000..933e07f3016 --- /dev/null +++ b/influxdb3/tests/server/query.rs @@ -0,0 +1,920 @@ +use crate::TestServer; +use futures::StreamExt; +use influxdb3_client::Precision; +use pretty_assertions::assert_eq; +use serde_json::{json, Value}; +use test_helpers::assert_contains; + +#[tokio::test] +async fn api_v3_query_sql() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=s1,region=us-east usage=0.9 1\n\ + cpu,host=s1,region=us-east usage=0.89 2\n\ + cpu,host=s1,region=us-east usage=0.85 3", + Precision::Nanosecond, + ) + .await + .unwrap(); + + let client = reqwest::Client::new(); + + let resp = client + .get(format!( + "{base}/api/v3/query_sql", + base = server.client_addr() + )) + .query(&[ + ("db", "foo"), + ("q", "SELECT host, region, time, usage FROM cpu"), + ("format", "pretty"), + ]) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + assert_eq!( + "+------+---------+-------------------------------+-------+\n\ + | host | region | time | usage |\n\ + +------+---------+-------------------------------+-------+\n\ + | s1 | us-east | 1970-01-01T00:00:00.000000001 | 0.9 |\n\ + | s1 | us-east | 1970-01-01T00:00:00.000000002 | 0.89 |\n\ + | s1 | us-east | 1970-01-01T00:00:00.000000003 | 0.85 |\n\ + +------+---------+-------------------------------+-------+", + resp, + ); +} + +#[tokio::test] +async fn api_v3_query_sql_params() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=a,region=us-east usage=0.9 1 + cpu,host=b,region=us-east usage=0.50 1 + cpu,host=a,region=us-east usage=0.80 2 + cpu,host=b,region=us-east usage=0.60 2 + cpu,host=a,region=us-east usage=0.70 3 + cpu,host=b,region=us-east usage=0.70 3 + cpu,host=a,region=us-east usage=0.50 4 + cpu,host=b,region=us-east usage=0.80 4", + Precision::Second, + ) + .await + .unwrap(); + + let client = reqwest::Client::new(); + let url = format!("{base}/api/v3/query_sql", base = server.client_addr()); + + // Use a POST request + { + let resp = client + .post(&url) + .json(&json!({ + "db": "foo", + "q": "SELECT host, region, time, usage FROM cpu WHERE host = $host AND usage > $usage ORDER BY time", + "params": { + "host": "b", + "usage": 0.60, + }, + "format": "pretty", + })) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + assert_eq!( + "+------+---------+---------------------+-------+\n\ + | host | region | time | usage |\n\ + +------+---------+---------------------+-------+\n\ + | b | us-east | 1970-01-01T00:00:03 | 0.7 |\n\ + | b | us-east | 1970-01-01T00:00:04 | 0.8 |\n\ + +------+---------+---------------------+-------+", + resp + ); + } + + // Use a GET request + { + let params = serde_json::to_string(&json!({ + "host": "b", + "usage": 0.60, + })) + .unwrap(); + let resp = client + .get(&url) + .query(&[ + ("db", "foo"), + ( + "q", + "SELECT host, region, time, usage FROM cpu WHERE host = $host AND usage > $usage ORDER BY time", + ), + ("format", "pretty"), + ("params", params.as_str()), + ]) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + assert_eq!( + "+------+---------+---------------------+-------+\n\ + | host | region | time | usage |\n\ + +------+---------+---------------------+-------+\n\ + | b | us-east | 1970-01-01T00:00:03 | 0.7 |\n\ + | b | us-east | 1970-01-01T00:00:04 | 0.8 |\n\ + +------+---------+---------------------+-------+", + resp + ); + } + + // Check for errors + { + let resp = client + .post(&url) + .json(&json!({ + "db": "foo", + "q": "SELECT * FROM cpu WHERE host = $host", + "params": { + "not_host": "a" + }, + "format": "pretty", + })) + .send() + .await + .unwrap(); + let status = resp.status(); + let body = resp.text().await.unwrap(); + + // TODO - it would be nice if this was a 4xx error, because this is really + // a user error; however, the underlying error that occurs when Logical + // planning is DatafusionError::Internal, and is not so convenient to deal + // with. This may get addressed in: + // + // https://github.com/apache/arrow-datafusion/issues/9738 + assert!(status.is_server_error()); + assert_contains!(body, "No value found for placeholder with name $host"); + } +} + +#[tokio::test] +async fn api_v3_query_influxql() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=s1,region=us-east usage=0.9 1\n\ + cpu,host=s1,region=us-east usage=0.89 2\n\ + cpu,host=s1,region=us-east usage=0.85 3\n\ + mem,host=s1,region=us-east usage=0.5 4\n\ + mem,host=s1,region=us-east usage=0.6 5\n\ + mem,host=s1,region=us-east usage=0.7 6", + Precision::Nanosecond, + ) + .await + .unwrap(); + + // write to another database for `SHOW DATABASES` and `SHOW RETENTION POLICIES` + server + .write_lp_to_db( + "bar", + "cpu,host=s1,region=us-east usage=0.9 1\n\ + cpu,host=s1,region=us-east usage=0.89 2\n\ + cpu,host=s1,region=us-east usage=0.85 3\n\ + mem,host=s1,region=us-east usage=0.5 4\n\ + mem,host=s1,region=us-east usage=0.6 5\n\ + mem,host=s1,region=us-east usage=0.7 6", + Precision::Nanosecond, + ) + .await + .unwrap(); + + struct TestCase<'a> { + database: Option<&'a str>, + query: &'a str, + expected: &'a str, + } + + let test_cases = [ + TestCase { + database: Some("foo"), + query: "SELECT time, host, region, usage FROM cpu", + expected: + "+------------------+-------------------------------+------+---------+-------+\n\ + | iox::measurement | time | host | region | usage |\n\ + +------------------+-------------------------------+------+---------+-------+\n\ + | cpu | 1970-01-01T00:00:00.000000001 | s1 | us-east | 0.9 |\n\ + | cpu | 1970-01-01T00:00:00.000000002 | s1 | us-east | 0.89 |\n\ + | cpu | 1970-01-01T00:00:00.000000003 | s1 | us-east | 0.85 |\n\ + +------------------+-------------------------------+------+---------+-------+", + }, + TestCase { + database: None, + query: "SELECT time, host, region, usage FROM foo.autogen.cpu", + expected: + "+------------------+-------------------------------+------+---------+-------+\n\ + | iox::measurement | time | host | region | usage |\n\ + +------------------+-------------------------------+------+---------+-------+\n\ + | cpu | 1970-01-01T00:00:00.000000001 | s1 | us-east | 0.9 |\n\ + | cpu | 1970-01-01T00:00:00.000000002 | s1 | us-east | 0.89 |\n\ + | cpu | 1970-01-01T00:00:00.000000003 | s1 | us-east | 0.85 |\n\ + +------------------+-------------------------------+------+---------+-------+", + }, + TestCase { + database: Some("foo"), + query: "SELECT host, region, usage FROM cpu, mem", + expected: + "+------------------+-------------------------------+------+---------+-------+\n\ + | iox::measurement | time | host | region | usage |\n\ + +------------------+-------------------------------+------+---------+-------+\n\ + | cpu | 1970-01-01T00:00:00.000000001 | s1 | us-east | 0.9 |\n\ + | cpu | 1970-01-01T00:00:00.000000002 | s1 | us-east | 0.89 |\n\ + | cpu | 1970-01-01T00:00:00.000000003 | s1 | us-east | 0.85 |\n\ + | mem | 1970-01-01T00:00:00.000000004 | s1 | us-east | 0.5 |\n\ + | mem | 1970-01-01T00:00:00.000000005 | s1 | us-east | 0.6 |\n\ + | mem | 1970-01-01T00:00:00.000000006 | s1 | us-east | 0.7 |\n\ + +------------------+-------------------------------+------+---------+-------+", + }, + TestCase { + database: Some("foo"), + query: "SHOW MEASUREMENTS", + expected: "+------------------+------+\n\ + | iox::measurement | name |\n\ + +------------------+------+\n\ + | measurements | cpu |\n\ + | measurements | mem |\n\ + +------------------+------+", + }, + TestCase { + database: None, + query: "SHOW MEASUREMENTS ON foo", + expected: "+------------------+------+\n\ + | iox::measurement | name |\n\ + +------------------+------+\n\ + | measurements | cpu |\n\ + | measurements | mem |\n\ + +------------------+------+", + }, + TestCase { + database: Some("foo"), + query: "SHOW FIELD KEYS", + expected: "+------------------+------------+-----------+\n\ + | iox::measurement | fieldKey | fieldType |\n\ + +------------------+------------+-----------+\n\ + | cpu | _series_id | string |\n\ + | cpu | usage | float |\n\ + | mem | _series_id | string |\n\ + | mem | usage | float |\n\ + +------------------+------------+-----------+", + }, + TestCase { + database: None, + query: "SHOW FIELD KEYS ON foo", + expected: "+------------------+------------+-----------+\n\ + | iox::measurement | fieldKey | fieldType |\n\ + +------------------+------------+-----------+\n\ + | cpu | _series_id | string |\n\ + | cpu | usage | float |\n\ + | mem | _series_id | string |\n\ + | mem | usage | float |\n\ + +------------------+------------+-----------+", + }, + TestCase { + database: Some("foo"), + query: "SHOW TAG KEYS", + expected: "+------------------+--------+\n\ + | iox::measurement | tagKey |\n\ + +------------------+--------+\n\ + | cpu | host |\n\ + | cpu | region |\n\ + | mem | host |\n\ + | mem | region |\n\ + +------------------+--------+", + }, + TestCase { + database: None, + query: "SHOW TAG KEYS ON foo", + expected: "+------------------+--------+\n\ + | iox::measurement | tagKey |\n\ + +------------------+--------+\n\ + | cpu | host |\n\ + | cpu | region |\n\ + | mem | host |\n\ + | mem | region |\n\ + +------------------+--------+", + }, + TestCase { + database: Some("foo"), + query: "SHOW TAG VALUES WITH KEY = \"host\" WHERE time < 1970-01-02", + expected: "+------------------+------+-------+\n\ + | iox::measurement | key | value |\n\ + +------------------+------+-------+\n\ + | cpu | host | s1 |\n\ + | mem | host | s1 |\n\ + +------------------+------+-------+", + }, + TestCase { + database: None, + query: "SHOW TAG VALUES ON foo WITH KEY = \"host\" WHERE time < 1970-01-02", + expected: "+------------------+------+-------+\n\ + | iox::measurement | key | value |\n\ + +------------------+------+-------+\n\ + | cpu | host | s1 |\n\ + | mem | host | s1 |\n\ + +------------------+------+-------+", + }, + TestCase { + database: None, + query: "SHOW DATABASES", + expected: "+---------------+\n\ + | iox::database |\n\ + +---------------+\n\ + | bar |\n\ + | foo |\n\ + +---------------+", + }, + TestCase { + database: None, + query: "SHOW RETENTION POLICIES", + expected: "+---------------+---------+----------+\n\ + | iox::database | name | duration |\n\ + +---------------+---------+----------+\n\ + | bar | autogen | |\n\ + | foo | autogen | |\n\ + +---------------+---------+----------+", + }, + TestCase { + database: None, + query: "SHOW RETENTION POLICIES ON foo", + expected: "+---------------+---------+----------+\n\ + | iox::database | name | duration |\n\ + +---------------+---------+----------+\n\ + | foo | autogen | |\n\ + +---------------+---------+----------+", + }, + TestCase { + database: Some("foo"), + query: "SHOW RETENTION POLICIES", + expected: "+---------------+---------+----------+\n\ + | iox::database | name | duration |\n\ + +---------------+---------+----------+\n\ + | foo | autogen | |\n\ + +---------------+---------+----------+", + }, + ]; + + for t in test_cases { + let mut params = vec![("q", t.query), ("format", "pretty")]; + if let Some(db) = t.database { + params.push(("db", db)) + } + let resp = server + .api_v3_query_influxql(¶ms) + .await + .text() + .await + .unwrap(); + println!("\n{q}", q = t.query); + println!("{resp}"); + assert_eq!(t.expected, resp, "query failed: {q}", q = t.query); + } +} + +#[tokio::test] +async fn api_v3_query_influxql_params() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=a,region=us-east usage=0.9 1 + cpu,host=b,region=us-east usage=0.50 1 + cpu,host=a,region=us-east usage=0.80 2 + cpu,host=b,region=us-east usage=0.60 2 + cpu,host=a,region=us-east usage=0.70 3 + cpu,host=b,region=us-east usage=0.70 3 + cpu,host=a,region=us-east usage=0.50 4 + cpu,host=b,region=us-east usage=0.80 4", + Precision::Second, + ) + .await + .unwrap(); + + let client = reqwest::Client::new(); + let url = format!("{base}/api/v3/query_influxql", base = server.client_addr()); + + // Use a POST request + { + let resp = client + .post(&url) + .json(&json!({ + "db": "foo", + "q": "SELECT time, host, region, usage FROM cpu WHERE host = $host AND usage > $usage", + "params": { + "host": "b", + "usage": 0.60, + }, + "format": "pretty", + })) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + assert_eq!( + "+------------------+---------------------+------+---------+-------+\n\ + | iox::measurement | time | host | region | usage |\n\ + +------------------+---------------------+------+---------+-------+\n\ + | cpu | 1970-01-01T00:00:03 | b | us-east | 0.7 |\n\ + | cpu | 1970-01-01T00:00:04 | b | us-east | 0.8 |\n\ + +------------------+---------------------+------+---------+-------+", + resp + ); + } + + // Use a GET request + { + let params = serde_json::to_string(&json!({ + "host": "b", + "usage": 0.60, + })) + .unwrap(); + let resp = client + .get(&url) + .query(&[ + ("db", "foo"), + ( + "q", + "SELECT time, host, region, usage FROM cpu WHERE host = $host AND usage > $usage", + ), + ("format", "pretty"), + ("params", params.as_str()), + ]) + .send() + .await + .unwrap() + .text() + .await + .unwrap(); + + assert_eq!( + "+------------------+---------------------+------+---------+-------+\n\ + | iox::measurement | time | host | region | usage |\n\ + +------------------+---------------------+------+---------+-------+\n\ + | cpu | 1970-01-01T00:00:03 | b | us-east | 0.7 |\n\ + | cpu | 1970-01-01T00:00:04 | b | us-east | 0.8 |\n\ + +------------------+---------------------+------+---------+-------+", + resp + ); + } + + // Check for errors + { + let resp = client + .post(&url) + .json(&json!({ + "db": "foo", + "q": "SELECT * FROM cpu WHERE host = $host", + "params": { + "not_host": "a" + }, + "format": "pretty", + })) + .send() + .await + .unwrap(); + let status = resp.status(); + let body = resp.text().await.unwrap(); + + // TODO - it would be nice if this was a 4xx error, because this is really + // a user error; however, the underlying error that occurs when Logical + // planning is DatafusionError::Internal, and is not so convenient to deal + // with. This may get addressed in: + // + // https://github.com/apache/arrow-datafusion/issues/9738 + assert!(status.is_server_error()); + assert_contains!( + body, + "Bind parameter '$host' was referenced in the InfluxQL \ + statement but its value is undefined" + ); + } +} + +#[tokio::test] +async fn api_v1_query() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=a usage=0.9 1\n\ + cpu,host=a usage=0.89 2\n\ + cpu,host=a usage=0.85 3\n\ + mem,host=a usage=0.5 4\n\ + mem,host=a usage=0.6 5\n\ + mem,host=a usage=0.7 6", + Precision::Second, + ) + .await + .unwrap(); + + struct TestCase<'a> { + database: Option<&'a str>, + epoch: Option<&'a str>, + query: &'a str, + expected: Value, + } + + let test_cases = [ + // Basic Query: + TestCase { + database: Some("foo"), + epoch: None, + query: "SELECT time, host, usage FROM cpu", + expected: json!({ + "results": [ + { + "series": [ + { + "columns": [ + "time", + "host", + "usage" + ], + "name": "cpu", + "values": [ + ["1970-01-01T00:00:01", "a", 0.9], + ["1970-01-01T00:00:02", "a", 0.89], + ["1970-01-01T00:00:03", "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + }, + // Basic Query with multiple measurements: + TestCase { + database: Some("foo"), + epoch: None, + query: "SELECT time, host, usage FROM cpu, mem", + expected: json!({ + "results": [ + { + "series": [ + { + "columns": [ + "time", + "host", + "usage" + ], + "name": "mem", + "values": [ + ["1970-01-01T00:00:04", "a", 0.5], + ["1970-01-01T00:00:05", "a", 0.6], + ["1970-01-01T00:00:06", "a", 0.7] + ] + }, + { + "columns": [ + "time", + "host", + "usage" + ], + "name": "cpu", + "values": [ + ["1970-01-01T00:00:01", "a", 0.9], + ["1970-01-01T00:00:02", "a", 0.89], + ["1970-01-01T00:00:03", "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + }, + // Basic Query with db in query string: + TestCase { + database: None, + epoch: None, + query: "SELECT time, host, usage FROM foo.autogen.cpu", + expected: json!({ + "results": [ + { + "series": [ + { + "columns": [ + "time", + "host", + "usage" + ], + "name": "cpu", + "values": [ + ["1970-01-01T00:00:01", "a", 0.9], + ["1970-01-01T00:00:02", "a", 0.89], + ["1970-01-01T00:00:03", "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + }, + // Basic Query epoch parameter set: + TestCase { + database: Some("foo"), + epoch: Some("s"), + query: "SELECT time, host, usage FROM cpu", + expected: json!({ + "results": [ + { + "series": [ + { + "columns": [ + "time", + "host", + "usage" + ], + "name": "cpu", + "values": [ + [1, "a", 0.9], + [2, "a", 0.89], + [3, "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + }, + ]; + + for t in test_cases { + let mut params = vec![("q", t.query)]; + if let Some(db) = t.database { + params.push(("db", db)); + } + if let Some(epoch) = t.epoch { + params.push(("epoch", epoch)); + } + let resp = server + .api_v1_query(¶ms) + .await + .json::() + .await + .unwrap(); + println!("\n{q}", q = t.query); + println!("{resp:#}"); + assert_eq!(t.expected, resp, "query failed: {q}", q = t.query); + } +} + +#[tokio::test] +async fn api_v1_query_chunked() { + let server = TestServer::spawn().await; + + server + .write_lp_to_db( + "foo", + "cpu,host=a usage=0.9 1\n\ + cpu,host=a usage=0.89 2\n\ + cpu,host=a usage=0.85 3\n\ + mem,host=a usage=0.5 4\n\ + mem,host=a usage=0.6 5\n\ + mem,host=a usage=0.7 6", + Precision::Second, + ) + .await + .unwrap(); + + struct TestCase<'a> { + chunk_size: Option<&'a str>, + query: &'a str, + expected: Vec, + } + + let test_cases = [ + // Basic Query with default chunking: + TestCase { + chunk_size: None, + query: "SELECT time, host, usage FROM cpu", + expected: vec![json!({ + "results": [ + { + "series": [ + { + "name": "cpu", + "columns": ["time","host","usage"], + "values": [ + [1, "a", 0.9], + [2, "a", 0.89], + [3, "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + })], + }, + // Basic Query with chunk size: + TestCase { + chunk_size: Some("2"), + query: "SELECT time, host, usage FROM cpu", + expected: vec![ + json!({ + "results": [ + { + "series": [ + { + "name": "cpu", + "columns": ["time","host","usage"], + "values": [ + [1, "a", 0.9], + [2, "a", 0.89], + ] + } + ], + "statement_id": 0 + } + ] + }), + json!({ + "results": [ + { + "series": [ + { + "name": "cpu", + "columns": ["time","host","usage"], + "values": [ + [3, "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + ], + }, + // Query with multiple measurements and default chunking: + TestCase { + chunk_size: None, + query: "SELECT time, host, usage FROM cpu, mem", + expected: vec![ + json!({ + "results": [ + { + "series": [ + { + "name": "cpu", + "columns": ["time","host","usage"], + "values": [ + [1, "a", 0.9], + [2, "a", 0.89], + [3, "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + json!({ + "results": [ + { + "series": [ + { + "name": "mem", + "columns": ["time","host","usage"], + "values": [ + [4, "a", 0.5], + [5, "a", 0.6], + [6, "a", 0.7] + ] + } + ], + "statement_id": 0 + } + ] + }), + ], + }, + // Query with multiple measurements and chunk_size specified: + TestCase { + chunk_size: Some("2"), + query: "SELECT time, host, usage FROM cpu, mem", + expected: vec![ + json!({ + "results": [ + { + "series": [ + { + "name": "cpu", + "columns": ["time","host","usage"], + "values": [ + [1, "a", 0.9], + [2, "a", 0.89], + ] + } + ], + "statement_id": 0 + } + ] + }), + json!({ + "results": [ + { + "series": [ + { + "name": "cpu", + "columns": ["time","host","usage"], + "values": [ + [3, "a", 0.85] + ] + } + ], + "statement_id": 0 + } + ] + }), + json!({ + "results": [ + { + "series": [ + { + "name": "mem", + "columns": ["time","host","usage"], + "values": [ + [4, "a", 0.5], + [5, "a", 0.6], + ] + } + ], + "statement_id": 0 + } + ] + }), + json!({ + "results": [ + { + "series": [ + { + "name": "mem", + "columns": ["time","host","usage"], + "values": [ + [6, "a", 0.7] + ] + } + ], + "statement_id": 0 + } + ] + }), + ], + }, + ]; + + for t in test_cases { + let mut params = vec![ + ("db", "foo"), + ("q", t.query), + ("epoch", "s"), + ("chunked", "true"), + ]; + if let Some(chunk_size) = t.chunk_size { + params.push(("chunk_size", chunk_size)); + } + let stream = server.api_v1_query(¶ms).await.bytes_stream(); + let values = stream + .map(|chunk| { + println!("{chunk:?}"); + serde_json::from_slice(chunk.unwrap().as_ref()).unwrap() + }) + .collect::>() + .await; + println!("\n{q}", q = t.query); + assert_eq!(t.expected, values, "query failed: {q}", q = t.query); + } +} diff --git a/influxdb3/tests/server/write.rs b/influxdb3/tests/server/write.rs new file mode 100644 index 00000000000..161564ae286 --- /dev/null +++ b/influxdb3/tests/server/write.rs @@ -0,0 +1,274 @@ +use hyper::StatusCode; +use pretty_assertions::assert_eq; + +use crate::TestServer; + +#[tokio::test] +async fn api_v1_write_request_parsing() { + let server = TestServer::spawn().await; + let client = reqwest::Client::new(); + let write_url = format!("{base}/write", base = server.client_addr()); + let write_body = "cpu,host=a usage=0.5"; + + #[derive(Debug)] + struct TestCase { + db: Option<&'static str>, + precision: Option<&'static str>, + rp: Option<&'static str>, + expected: StatusCode, + } + + let test_cases = [ + TestCase { + db: None, + precision: None, + rp: None, + expected: StatusCode::BAD_REQUEST, + }, + TestCase { + db: Some("foo"), + precision: None, + rp: None, + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: Some("s"), + rp: None, + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: Some("ms"), + rp: None, + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: Some("us"), + rp: None, + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: Some("ns"), + rp: None, + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: Some("invalid"), + rp: None, + expected: StatusCode::BAD_REQUEST, + }, + TestCase { + db: Some("foo"), + precision: None, + rp: Some("bar"), + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: None, + rp: Some("default"), + expected: StatusCode::OK, + }, + TestCase { + db: Some("foo"), + precision: None, + rp: Some("autogen"), + expected: StatusCode::OK, + }, + ]; + + for t in test_cases { + println!("Test Case: {t:?}"); + let mut params = vec![]; + if let Some(db) = t.db { + params.push(("db", db)); + } + if let Some(rp) = t.rp { + params.push(("rp", rp)); + } + if let Some(precision) = t.precision { + params.push(("precision", precision)); + } + let resp = client + .post(&write_url) + .query(¶ms) + .body(write_body) + .send() + .await + .expect("send /write request"); + let status = resp.status(); + let body = resp.text().await.expect("response body as text"); + println!("Response [{status}]:\n{body}"); + assert_eq!(t.expected, status); + } +} + +#[tokio::test] +async fn api_v1_write_round_trip() { + let server = TestServer::spawn().await; + let client = reqwest::Client::new(); + let write_url = format!("{base}/write", base = server.client_addr()); + + client + .post(write_url) + .query(&[("db", "foo")]) + .body( + "cpu,host=a usage=0.5 1 + cpu,host=a usage=0.6 2 + cpu,host=a usage=0.7 3", + ) + .send() + .await + .expect("send /write request"); + + let resp = server + .api_v3_query_influxql(&[ + ("q", "SELECT time, host, usage FROM foo.autogen.cpu"), + ("format", "pretty"), + ]) + .await + .text() + .await + .unwrap(); + + assert_eq!( + resp, + "+------------------+-------------------------------+------+-------+\n\ + | iox::measurement | time | host | usage |\n\ + +------------------+-------------------------------+------+-------+\n\ + | cpu | 1970-01-01T00:00:00.000000001 | a | 0.5 |\n\ + | cpu | 1970-01-01T00:00:00.000000002 | a | 0.6 |\n\ + | cpu | 1970-01-01T00:00:00.000000003 | a | 0.7 |\n\ + +------------------+-------------------------------+------+-------+" + ); +} + +#[tokio::test] +async fn api_v2_write_request_parsing() { + let server = TestServer::spawn().await; + let client = reqwest::Client::new(); + let write_url = format!("{base}/api/v2/write", base = server.client_addr()); + let write_body = "cpu,host=a usage=0.5"; + + #[derive(Debug)] + struct TestCase { + org: Option<&'static str>, + bucket: Option<&'static str>, + precision: Option<&'static str>, + expected: StatusCode, + } + + let test_cases = [ + TestCase { + org: None, + bucket: None, + precision: None, + expected: StatusCode::BAD_REQUEST, + }, + TestCase { + org: None, + bucket: Some("foo"), + precision: None, + expected: StatusCode::OK, + }, + TestCase { + org: Some("bar"), + bucket: Some("foo"), + precision: None, + expected: StatusCode::OK, + }, + TestCase { + org: None, + bucket: Some("foo"), + precision: Some("s"), + expected: StatusCode::OK, + }, + TestCase { + org: None, + bucket: Some("foo"), + precision: Some("ms"), + expected: StatusCode::OK, + }, + TestCase { + org: None, + bucket: Some("foo"), + precision: Some("us"), + expected: StatusCode::OK, + }, + TestCase { + org: None, + bucket: Some("foo"), + precision: Some("ns"), + expected: StatusCode::OK, + }, + ]; + + for t in test_cases { + println!("Test Case: {t:?}"); + let mut params = vec![]; + if let Some(bucket) = t.bucket { + params.push(("bucket", bucket)); + } + if let Some(org) = t.org { + params.push(("org", org)); + } + if let Some(precision) = t.precision { + params.push(("precision", precision)); + } + let resp = client + .post(&write_url) + .query(¶ms) + .body(write_body) + .send() + .await + .expect("send /write request"); + let status = resp.status(); + let body = resp.text().await.expect("response body as text"); + println!("Response [{status}]:\n{body}"); + assert_eq!(t.expected, status); + } +} + +#[tokio::test] +async fn api_v2_write_round_trip() { + let server = TestServer::spawn().await; + let client = reqwest::Client::new(); + let write_url = format!("{base}/api/v2/write", base = server.client_addr()); + + client + .post(write_url) + .query(&[("bucket", "foo")]) + .body( + "cpu,host=a usage=0.5 1 + cpu,host=a usage=0.6 2 + cpu,host=a usage=0.7 3", + ) + .send() + .await + .expect("send /write request"); + + let resp = server + .api_v3_query_influxql(&[ + ("q", "SELECT time, host, usage FROM foo.autogen.cpu"), + ("format", "pretty"), + ]) + .await + .text() + .await + .unwrap(); + + assert_eq!( + resp, + "+------------------+-------------------------------+------+-------+\n\ + | iox::measurement | time | host | usage |\n\ + +------------------+-------------------------------+------+-------+\n\ + | cpu | 1970-01-01T00:00:00.000000001 | a | 0.5 |\n\ + | cpu | 1970-01-01T00:00:00.000000002 | a | 0.6 |\n\ + | cpu | 1970-01-01T00:00:00.000000003 | a | 0.7 |\n\ + +------------------+-------------------------------+------+-------+" + ); +} diff --git a/influxdb3_client/Cargo.toml b/influxdb3_client/Cargo.toml new file mode 100644 index 00000000000..d3dd6211cdb --- /dev/null +++ b/influxdb3_client/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "influxdb3_client" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +# core dependencies +iox_query_params.workspace = true + +# crates.io dependencies +bytes.workspace = true +reqwest.workspace = true +secrecy.workspace = true +serde.workspace = true +thiserror.workspace = true +url.workspace = true + +[dev-dependencies] +# crates.io dependencies +mockito.workspace = true +serde_json.workspace = true +tokio.workspace = true + +[lints] +workspace = true diff --git a/influxdb3_client/src/lib.rs b/influxdb3_client/src/lib.rs new file mode 100644 index 00000000000..eb10ceb9052 --- /dev/null +++ b/influxdb3_client/src/lib.rs @@ -0,0 +1,787 @@ +use std::{collections::HashMap, fmt::Display, string::FromUtf8Error}; + +use bytes::Bytes; +use iox_query_params::StatementParam; +use reqwest::{Body, IntoUrl, StatusCode}; +use secrecy::{ExposeSecret, Secret}; +use serde::{Deserialize, Serialize}; +use url::Url; + +/// Primary error type for the [`Client`] +#[derive(Debug, thiserror::Error)] +pub enum Error { + #[error("base URL error: {0}")] + BaseUrl(#[source] reqwest::Error), + + #[error("request URL error: {0}")] + RequestUrl(#[from] url::ParseError), + + #[error("failed to send /api/v3/write_lp request: {0}")] + WriteLpSend(#[source] reqwest::Error), + + #[error("failed to send /ping request: {0}")] + PingSend(#[source] reqwest::Error), + + #[error("failed to read the API response bytes: {0}")] + Bytes(#[source] reqwest::Error), + + #[error("failed to send /api/v3/query_{kind} request: {source}")] + QuerySend { + kind: QueryKind, + #[source] + source: reqwest::Error, + }, + + #[error( + "provided parameter ('{name}') could not be converted \ + to a statment parameter" + )] + ConvertQueryParam { + name: String, + #[source] + source: iox_query_params::Error, + }, + + #[error("invalid UTF8 in response: {0}")] + InvalidUtf8(#[from] FromUtf8Error), + + #[error("failed to parse JSON response: {0}")] + Json(#[source] reqwest::Error), + + #[error("failed to parse plaintext response: {0}")] + Text(#[source] reqwest::Error), + + #[error("server responded with error [{code}]: {message}")] + ApiError { code: StatusCode, message: String }, +} + +pub type Result = std::result::Result; + +/// The InfluxDB 3.0 Client +/// +/// For programmatic access to the HTTP API of InfluxDB 3.0 +#[derive(Debug, Clone)] +pub struct Client { + /// The base URL for making requests to a running InfluxDB 3.0 server + base_url: Url, + /// The `Bearer` token to use for authenticating on each request to the server + auth_token: Option>, + /// A [`reqwest::Client`] for handling HTTP requests + http_client: reqwest::Client, +} + +impl Client { + /// Create a new [`Client`] + pub fn new(base_url: U) -> Result { + Ok(Self { + base_url: base_url.into_url().map_err(Error::BaseUrl)?, + auth_token: None, + http_client: reqwest::Client::new(), + }) + } + + /// Set the `Bearer` token that will be sent with each request to the server + /// + /// # Example + /// ``` + /// # use influxdb3_client::Client; + /// # use influxdb3_client::Precision; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let token = "secret-token-string"; + /// let client = Client::new("http://localhost:8181")? + /// .with_auth_token(token); + /// # Ok(()) + /// # } + /// ``` + pub fn with_auth_token>(mut self, auth_token: S) -> Self { + self.auth_token = Some(Secret::new(auth_token.into())); + self + } + + /// Compose a request to the `/api/v3/write_lp` API + /// + /// # Example + /// ```no_run + /// # use influxdb3_client::Client; + /// # use influxdb3_client::Precision; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("http://localhost:8181")?; + /// client + /// .api_v3_write_lp("db_name") + /// .precision(Precision::Millisecond) + /// .accept_partial(true) + /// .body("cpu,host=s1 usage=0.5") + /// .send() + /// .await + /// .expect("send write_lp request"); + /// # Ok(()) + /// # } + /// ``` + pub fn api_v3_write_lp>(&self, db: S) -> WriteRequestBuilder<'_, NoBody> { + WriteRequestBuilder { + client: self, + db: db.into(), + precision: None, + accept_partial: None, + body: NoBody, + } + } + + /// Compose a request to the `/api/v3/query_sql` API + /// + /// # Example + /// ```no_run + /// # use influxdb3_client::Client; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("http://localhost:8181")?; + /// let response_bytes = client + /// .api_v3_query_sql("db_name", "SELECT * FROM foo") + /// .send() + /// .await + /// .expect("send query_sql request"); + /// # Ok(()) + /// # } + /// ``` + pub fn api_v3_query_sql, Q: Into>( + &self, + db: D, + query: Q, + ) -> QueryRequestBuilder<'_> { + QueryRequestBuilder { + client: self, + kind: QueryKind::Sql, + db: db.into(), + query: query.into(), + format: None, + params: None, + } + } + + /// Compose a request to the `/api/v3/query_influxql` API + /// + /// # Example + /// ```no_run + /// # use influxdb3_client::Client; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("http://localhost:8181")?; + /// let response_bytes = client + /// .api_v3_query_influxql("db_name", "SELECT * FROM foo") + /// .send() + /// .await + /// .expect("send query_influxql request"); + /// # Ok(()) + /// # } + /// ``` + pub fn api_v3_query_influxql, Q: Into>( + &self, + db: D, + query: Q, + ) -> QueryRequestBuilder<'_> { + QueryRequestBuilder { + client: self, + kind: QueryKind::InfluxQl, + db: db.into(), + query: query.into(), + format: None, + params: None, + } + } + + /// Send a `/ping` request to the target `influxdb3` server to check its + /// status and gather `version` and `revision` information + pub async fn ping(&self) -> Result { + let url = self.base_url.join("/ping")?; + let mut req = self.http_client.get(url); + if let Some(t) = &self.auth_token { + req = req.bearer_auth(t.expose_secret()); + } + let resp = req.send().await.map_err(Error::PingSend)?; + if resp.status().is_success() { + resp.json().await.map_err(Error::Json) + } else { + Err(Error::ApiError { + code: resp.status(), + message: resp.text().await.map_err(Error::Text)?, + }) + } + } +} + +/// The response of the `/ping` API on `influxdb3` +#[derive(Debug, Serialize, Deserialize)] +pub struct PingResponse { + version: String, + revision: String, +} + +impl PingResponse { + /// Get the `version` from the response + pub fn version(&self) -> &str { + &self.version + } + + /// Get the `revision` from the response + pub fn revision(&self) -> &str { + &self.revision + } +} + +/// The URL parameters of the request to the `/api/v3/write_lp` API +// TODO - this should re-use a type defined in the server code, or a separate crate, +// central to both. +#[derive(Debug, Serialize)] +struct WriteParams<'a> { + db: &'a str, + precision: Option, + accept_partial: Option, +} + +impl<'a, B> From<&'a WriteRequestBuilder<'a, B>> for WriteParams<'a> { + fn from(builder: &'a WriteRequestBuilder<'a, B>) -> Self { + Self { + db: &builder.db, + precision: builder.precision, + accept_partial: builder.accept_partial, + } + } +} + +/// Time series precision +// TODO - this should re-use a type defined in the server code, or a separate crate, +// central to both. +#[derive(Debug, Copy, Clone, Serialize)] +#[serde(rename_all = "lowercase")] +pub enum Precision { + Second, + Millisecond, + Microsecond, + Nanosecond, +} + +/// Builder type for composing a request to `/api/v3/write_lp` +/// +/// Produced by [`Client::api_v3_write_lp`] +#[derive(Debug)] +pub struct WriteRequestBuilder<'c, B> { + client: &'c Client, + db: String, + precision: Option, + accept_partial: Option, + body: B, +} + +impl<'c, B> WriteRequestBuilder<'c, B> { + /// Set the precision + pub fn precision(mut self, set_to: Precision) -> Self { + self.precision = Some(set_to); + self + } + + /// Set the `accept_partial` parameter + pub fn accept_partial(mut self, set_to: bool) -> Self { + self.accept_partial = Some(set_to); + self + } +} + +impl<'c> WriteRequestBuilder<'c, NoBody> { + /// Set the body of the request to the `/api/v3/write_lp` API + /// + /// This essentially wraps `reqwest`'s [`body`][reqwest::RequestBuilder::body] + /// method, and puts the responsibility on the caller for now. + pub fn body>(self, body: T) -> WriteRequestBuilder<'c, Body> { + WriteRequestBuilder { + client: self.client, + db: self.db, + precision: self.precision, + accept_partial: self.accept_partial, + body: body.into(), + } + } +} + +impl<'c> WriteRequestBuilder<'c, Body> { + /// Send the request to the server + pub async fn send(self) -> Result<()> { + let url = self.client.base_url.join("/api/v3/write_lp")?; + let params = WriteParams::from(&self); + let mut req = self.client.http_client.post(url).query(¶ms); + if let Some(token) = &self.client.auth_token { + req = req.bearer_auth(token.expose_secret()); + } + let resp = req + .body(self.body) + .send() + .await + .map_err(Error::WriteLpSend)?; + let status = resp.status(); + let content = resp.bytes().await.map_err(Error::Bytes)?; + match status { + // TODO - handle the OK response content, return to caller, etc. + StatusCode::OK => Ok(()), + code => Err(Error::ApiError { + code, + message: String::from_utf8(content.to_vec())?, + }), + } + } +} + +#[doc(hidden)] +/// Typestate type for [`WriteRequestBuilder`] +#[derive(Debug, Copy, Clone)] +pub struct NoBody; + +/// Used to compose a request to the `/api/v3/query_sql` API +/// +/// Produced by [`Client::api_v3_query_sql`] method. +#[derive(Debug)] +pub struct QueryRequestBuilder<'c> { + client: &'c Client, + kind: QueryKind, + db: String, + query: String, + format: Option, + params: Option>, +} + +// TODO - for now the send method just returns the bytes from the response. +// It may be nicer to have the format parameter dictate how we return from +// send, e.g., using types more specific to the format selected. +impl<'c> QueryRequestBuilder<'c> { + /// Specify the format, `json`, `csv`, `pretty`, or `parquet` + pub fn format(mut self, format: Format) -> Self { + self.format = Some(format); + self + } + + /// Set a query parameter value with the given `name` + /// + /// # Example + /// ```no_run + /// # use influxdb3_client::Client; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// let client = Client::new("http://localhost:8181")?; + /// let response_bytes = client + /// .api_v3_query_sql("db_name", "SELECT * FROM foo WHERE bar = $bar AND baz > $baz") + /// .with_param("bar", "bop") + /// .with_param("baz", 0.5) + /// .send() + /// .await + /// .expect("send query_sql request"); + /// # Ok(()) + /// # } + /// ``` + pub fn with_param, P: Into>( + mut self, + name: S, + param: P, + ) -> Self { + self.params + .get_or_insert_with(Default::default) + .insert(name.into(), param.into()); + self + } + + /// Set a query parameters from the given collection of pairs + /// + /// # Example + /// ```no_run + /// # use influxdb3_client::Client; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// use serde_json::json; + /// use std::collections::HashMap; + /// + /// let client = Client::new("http://localhost:8181")?; + /// let response_bytes = client + /// .api_v3_query_sql("db_name", "SELECT * FROM foo WHERE bar = $bar AND foo > $fooz") + /// .with_params_from([ + /// ("bar", json!(false)), + /// ("foo", json!(10)), + /// ])? + /// .send() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + pub fn with_params_from(mut self, params: C) -> Result + where + S: Into, + P: TryInto, + C: IntoIterator, + { + for (name, param) in params.into_iter() { + let name = name.into(); + let param = param + .try_into() + .map_err(|source| Error::ConvertQueryParam { + name: name.clone(), + source, + })?; + + self.params + .get_or_insert_with(Default::default) + .insert(name, param); + } + Ok(self) + } + + /// Try to set a query parameter value with the given `name` + /// + /// # Example + /// ```no_run + /// # use influxdb3_client::Client; + /// # #[tokio::main] + /// # async fn main() -> Result<(), Box> { + /// use serde_json::json; + /// + /// let client = Client::new("http://localhost:8181")?; + /// let response_bytes = client + /// .api_v3_query_sql("db_name", "SELECT * FROM foo WHERE bar = $bar AND baz > $baz") + /// .with_try_param("bar", json!("baz"))? + /// .send() + /// .await?; + /// # Ok(()) + /// # } + /// ``` + pub fn with_try_param(mut self, name: S, param: P) -> Result + where + S: Into, + P: TryInto, + { + let name = name.into(); + let param = param + .try_into() + .map_err(|source| Error::ConvertQueryParam { + name: name.clone(), + source, + })?; + self.params + .get_or_insert_with(Default::default) + .insert(name, param); + Ok(self) + } + + /// Send the request to `/api/v3/query_sql` or `/api/v3/query_influxql` + pub async fn send(self) -> Result { + let url = match self.kind { + QueryKind::Sql => self.client.base_url.join("/api/v3/query_sql")?, + QueryKind::InfluxQl => self.client.base_url.join("/api/v3/query_influxql")?, + }; + let params = QueryParams::from(&self); + let mut req = self.client.http_client.post(url).json(¶ms); + if let Some(token) = &self.client.auth_token { + req = req.bearer_auth(token.expose_secret()); + } + let resp = req.send().await.map_err(|source| Error::QuerySend { + kind: self.kind, + source, + })?; + let status = resp.status(); + let content = resp.bytes().await.map_err(Error::Bytes)?; + + match status { + StatusCode::OK => Ok(content), + code => Err(Error::ApiError { + code, + message: String::from_utf8(content.to_vec()).map_err(Error::InvalidUtf8)?, + }), + } + } +} + +/// Query parameters for the `/api/v3/query_sql` API +#[derive(Debug, Serialize)] +pub struct QueryParams<'a> { + db: &'a str, + #[serde(rename = "q")] + query: &'a str, + format: Option, + params: Option<&'a HashMap>, +} + +impl<'a> From<&'a QueryRequestBuilder<'a>> for QueryParams<'a> { + fn from(builder: &'a QueryRequestBuilder<'a>) -> Self { + Self { + db: &builder.db, + query: &builder.query, + format: builder.format, + params: builder.params.as_ref(), + } + } +} + +/// The type of query, SQL or InfluxQL +#[derive(Debug, Copy, Clone)] +pub enum QueryKind { + Sql, + InfluxQl, +} + +impl Display for QueryKind { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + QueryKind::Sql => write!(f, "sql"), + QueryKind::InfluxQl => write!(f, "influxql"), + } + } +} + +/// Output format to request from the server in the `/api/v3/query_sql` API +#[derive(Debug, Serialize, Copy, Clone)] +#[serde(rename_all = "snake_case")] +pub enum Format { + Json, + Csv, + Parquet, + Pretty, +} + +#[cfg(test)] +mod tests { + use mockito::{Matcher, Server}; + use serde_json::json; + + use crate::{Client, Format, Precision}; + + #[tokio::test] + async fn api_v3_write_lp() { + let token = "super-secret-token"; + let db = "stats"; + let body = "\ + cpu,host=s1 usage=0.5 + cpu,host=s1,region=us-west usage=0.7"; + + let mut mock_server = Server::new_async().await; + let mock = mock_server + .mock("POST", "/api/v3/write_lp") + .match_header("Authorization", format!("Bearer {token}").as_str()) + .match_query(Matcher::AllOf(vec![ + Matcher::UrlEncoded("precision".into(), "millisecond".into()), + Matcher::UrlEncoded("db".into(), db.into()), + Matcher::UrlEncoded("accept_partial".into(), "true".into()), + ])) + .match_body(body) + .create_async() + .await; + + let client = Client::new(mock_server.url()) + .expect("create client") + .with_auth_token(token); + + client + .api_v3_write_lp(db) + .precision(Precision::Millisecond) + .accept_partial(true) + .body(body) + .send() + .await + .expect("send write_lp request"); + + mock.assert_async().await; + } + + #[tokio::test] + async fn api_v3_query_sql() { + let token = "super-secret-token"; + let db = "stats"; + let query = "SELECT * FROM foo"; + let body = r#"[{"host": "foo", "time": "1990-07-23T06:00:00:000", "val": 1}]"#; + + let mut mock_server = Server::new_async().await; + let mock = mock_server + .mock("POST", "/api/v3/query_sql") + .match_header("Authorization", format!("Bearer {token}").as_str()) + .match_body(Matcher::Json(serde_json::json!({ + "db": db, + "q": query, + "format": "json", + "params": null, + }))) + .with_status(200) + // TODO - could add content-type header but that may be too brittle + // at the moment + // - this will be JSON Lines at some point + .with_body(body) + .create_async() + .await; + + let client = Client::new(mock_server.url()) + .expect("create client") + .with_auth_token(token); + + let r = client + .api_v3_query_sql(db, query) + .format(Format::Json) + .send() + .await + .expect("send request to server"); + + assert_eq!(&r, body); + + mock.assert_async().await; + } + + #[tokio::test] + async fn api_v3_query_sql_params() { + let db = "stats"; + let query = "SELECT * FROM foo WHERE bar = $bar"; + let body = r#"[{"host": "foo", "time": "1990-07-23T06:00:00:000", "val": 1}]"#; + + let mut mock_server = Server::new_async().await; + let mock = mock_server + .mock("POST", "/api/v3/query_sql") + .match_body(Matcher::Json(serde_json::json!({ + "db": db, + "q": query, + "params": { + "bar": "baz", + "baz": false, + }, + "format": null + }))) + .with_status(200) + .with_body(body) + .create_async() + .await; + + let client = Client::new(mock_server.url()).expect("create client"); + + let r = client + .api_v3_query_sql(db, query) + .with_param("bar", "baz") + .with_param("baz", false) + .send() + .await; + + mock.assert_async().await; + + r.expect("sent request successfully"); + } + + #[tokio::test] + async fn api_v3_query_influxql() { + let db = "stats"; + let query = "SELECT * FROM foo"; + let body = r#"[{"host": "foo", "time": "1990-07-23T06:00:00:000", "val": 1}]"#; + + let mut mock_server = Server::new_async().await; + let mock = mock_server + .mock("POST", "/api/v3/query_influxql") + .match_body(Matcher::Json(serde_json::json!({ + "db": db, + "q": query, + "format": "json", + "params": null, + }))) + .with_status(200) + .with_body(body) + .create_async() + .await; + + let client = Client::new(mock_server.url()).expect("create client"); + + let r = client + .api_v3_query_influxql(db, query) + .format(Format::Json) + .send() + .await + .expect("send request to server"); + + assert_eq!(&r, body); + + mock.assert_async().await; + } + #[tokio::test] + async fn api_v3_query_influxql_params() { + let db = "stats"; + let query = "SELECT * FROM foo WHERE a = $a AND b < $b AND c > $c AND d = $d"; + let body = r#"[{"host": "foo", "time": "1990-07-23T06:00:00:000", "val": 1}]"#; + + let mut mock_server = Server::new_async().await; + let mock = mock_server + .mock("POST", "/api/v3/query_influxql") + .match_body(Matcher::Json(serde_json::json!({ + "db": db, + "q": query, + "params": { + "a": "bar", + "b": 123, + "c": 1.5, + "d": false + }, + "format": null + }))) + .with_status(200) + .with_body(body) + .create_async() + .await; + + let client = Client::new(mock_server.url()).expect("create client"); + + let mut builder = client.api_v3_query_influxql(db, query); + + for (name, value) in [ + ("a", json!("bar")), + ("b", json!(123)), + ("c", json!(1.5)), + ("d", json!(false)), + ] { + builder = builder.with_try_param(name, value).unwrap(); + } + let r = builder.send().await; + + mock.assert_async().await; + + r.expect("sent request successfully"); + } + #[tokio::test] + async fn api_v3_query_influxql_with_params_from() { + let db = "stats"; + let query = "SELECT * FROM foo WHERE a = $a AND b < $b AND c > $c AND d = $d"; + let body = r#"[{"host": "foo", "time": "1990-07-23T06:00:00:000", "val": 1}]"#; + + let mut mock_server = Server::new_async().await; + let mock = mock_server + .mock("POST", "/api/v3/query_influxql") + .match_body(Matcher::Json(serde_json::json!({ + "db": db, + "q": query, + "params": { + "a": "bar", + "b": 123, + "c": 1.5, + "d": false + }, + "format": null + }))) + .with_status(200) + .with_body(body) + .create_async() + .await; + + let client = Client::new(mock_server.url()).expect("create client"); + + let r = client + .api_v3_query_influxql(db, query) + .with_params_from([ + ("a", json!("bar")), + ("b", json!(123)), + ("c", json!(1.5)), + ("d", json!(false)), + ]) + .unwrap() + .send() + .await; + + mock.assert_async().await; + + r.expect("sent request successfully"); + } +} diff --git a/influxdb3_load_generator/Cargo.toml b/influxdb3_load_generator/Cargo.toml new file mode 100644 index 00000000000..3f71d86b5bd --- /dev/null +++ b/influxdb3_load_generator/Cargo.toml @@ -0,0 +1,36 @@ +[package] +name = "influxdb3_load_generator" +version.workspace = true +authors.workspace = true +edition.workspace = true +license.workspace = true + +[dependencies] +# Core Crates +observability_deps.workspace = true +trogging.workspace = true + +# Local Deps +influxdb3_client = { path = "../influxdb3_client" } +influxdb3_process = { path = "../influxdb3_process", default-features = false } + +# crates.io Dependencies +anyhow.workspace = true +bytes.workspace = true +chrono.workspace = true +clap.workspace = true +csv.workspace = true +dotenvy.workspace = true +humantime.workspace = true +parking_lot.workspace = true +rand.workspace = true +secrecy.workspace = true +serde.workspace = true +serde_json.workspace = true +sysinfo.workspace = true +tokio.workspace = true +thiserror.workspace = true +url.workspace = true + +[lints] +workspace = true diff --git a/influxdb3_load_generator/analysis/README.md b/influxdb3_load_generator/analysis/README.md new file mode 100644 index 00000000000..17cfd94a2f3 --- /dev/null +++ b/influxdb3_load_generator/analysis/README.md @@ -0,0 +1,21 @@ +# Load Generator Analysis + +This directory contains a lightweight Flask app to compare two runs of the load generator. The app is designed to be run locally and is not intended for production use. + +## Setup + +Make sure you have python and flask installed. You can install flask by running: + +```bash +pip install flask +``` + +## Running the app + +To run the app, navigate to the `analysis` directory and run: + +```bash +python app.py +``` + +Then open your browser to http://127.0.0.1:5000/ to view the app. \ No newline at end of file diff --git a/influxdb3_load_generator/analysis/app.py b/influxdb3_load_generator/analysis/app.py new file mode 100644 index 00000000000..ccd4455e3f0 --- /dev/null +++ b/influxdb3_load_generator/analysis/app.py @@ -0,0 +1,119 @@ +from flask import Flask, jsonify, render_template, request +import os +import csv +import math +import sys +import re + +app = Flask(__name__) + +# Directory path (provided as a command-line argument) +RESULTS_DIRECTORY = 'results/' + +@app.route('/') +def index(): + return render_template('index.html') + +@app.route('/api/test-names') +def get_test_names(): + test_names = [name for name in os.listdir(RESULTS_DIRECTORY) if os.path.isdir(os.path.join(RESULTS_DIRECTORY, name))] + return jsonify(test_names) + +@app.route('/api/config-names') +def get_config_names(): + test_name = request.args.get('test_name') + test_path = os.path.join(RESULTS_DIRECTORY, test_name) + config_names = {} + + for config_name in os.listdir(test_path): + config_path = os.path.join(test_path, config_name) + if os.path.isdir(config_path): + run_times = set() + for file_name in os.listdir(config_path): + match = re.search(r'_(\d{4}-\d{2}-\d{2}T\d{2}-\d{2}-\d{2})', file_name) + if match: + run_time = match.group(1) + run_times.add(run_time) + config_names[config_name] = sorted(run_times) + + return jsonify(config_names) + +@app.route('/api/aggregated-data') +def get_aggregated_data(): + test_name = request.args.get('test_name') + config_name = request.args.get('config_name') + run_time = request.args.get('run_time') + + config_path = os.path.join(RESULTS_DIRECTORY, test_name, config_name) + write_file = os.path.join(config_path, f'write_{run_time}.csv') + query_file = os.path.join(config_path, f'query_{run_time}.csv') + system_file = os.path.join(config_path, f'system_{run_time}.csv') + + if not os.path.isfile(write_file) and not os.path.isfile(query_file) and not os.path.isfile(system_file): + return jsonify({'error': 'Files not found for the specified configuration and run time'}) + + write_data = None + if os.path.isfile(write_file): + write_data = aggregate_data(write_file, 'lines', 'latency_ms') + query_data = None + if os.path.isfile(query_file): + query_data = aggregate_data(query_file, 'rows', 'response_ms') + system_data = None + if os.path.isfile(system_file): + system_data = aggregate_system_data(system_file) + + + aggregated_data = { + 'config_name': config_name, + 'run_time': run_time, + 'write_data': write_data, + 'query_data': query_data, + 'system_data': system_data + } + + return jsonify(aggregated_data) + +def aggregate_data(file_path, lines_field, latency_field): + aggregated_data = [] + + with open(file_path, 'r') as file: + reader = csv.DictReader(file) + data = list(reader) + + for row in data: + test_time = int(row['test_time_ms']) + lines = int(row[lines_field]) + latency = int(row[latency_field]) + + aggregated_data.append({ + 'test_time': test_time, + 'lines': lines, + 'latency': latency + }) + + return aggregated_data + +def aggregate_system_data(file_path): + aggregated_data = [] + + with open(file_path, 'r') as file: + reader = csv.DictReader(file) + data = list(reader) + + for row in data: + aggregated_data.append({ + 'test_time': int(row['test_time_ms']), + 'cpu_usage': float(row['cpu_usage']), + 'memory_bytes': int(row['memory_bytes']) / 1024 / 1024 + }) + + return aggregated_data + +if __name__ == '__main__': + if len(sys.argv) != 2: + print('Usage: python app.py ') + print('results directory not provided, defaulting to "results/"') + else: + RESULTS_DIRECTORY = sys.argv[1] + + app.run() diff --git a/influxdb3_load_generator/analysis/templates/index.html b/influxdb3_load_generator/analysis/templates/index.html new file mode 100644 index 00000000000..d2bfdce9b72 --- /dev/null +++ b/influxdb3_load_generator/analysis/templates/index.html @@ -0,0 +1,237 @@ + + + + Benchmark Results Comparison + + + + +

Benchmark Results Comparison

+
+ + +
+
+ + +
+
+ + +
+ +
+ + + diff --git a/influxdb3_load_generator/src/commands/common.rs b/influxdb3_load_generator/src/commands/common.rs new file mode 100644 index 00000000000..d768664d757 --- /dev/null +++ b/influxdb3_load_generator/src/commands/common.rs @@ -0,0 +1,461 @@ +use std::{fs::File, path::PathBuf, str::FromStr, sync::Arc}; + +use anyhow::{anyhow, bail, Context}; +use chrono::{DateTime, Local}; +use clap::Parser; +use influxdb3_client::Client; +use secrecy::{ExposeSecret, Secret}; +use url::Url; + +use crate::{ + report::{QueryReporter, SystemStatsReporter, WriteReporter}, + specification::{DataSpec, QuerierSpec}, +}; + +#[derive(Debug, Parser)] +pub(crate) struct InfluxDb3Config { + /// The host URL of the running InfluxDB 3.0 server + #[clap( + short = 'h', + long = "host", + env = "INFLUXDB3_HOST_URL", + default_value = "http://127.0.0.1:8181" + )] + pub(crate) host_url: Url, + + /// The database name to generate load against + #[clap( + short = 'd', + long = "dbname", + env = "INFLUXDB3_DATABASE_NAME", + default_value = "load_test" + )] + pub(crate) database_name: String, + + /// The token for authentication with the InfluxDB 3.0 server + #[clap(long = "token", env = "INFLUXDB3_AUTH_TOKEN")] + pub(crate) auth_token: Option>, + + /// The name of the builtin spec to run. Use this instead of spec_path if you want to run + /// one of the builtin specs as is. + #[clap(long = "builtin-spec", env = "INFLUXDB3_LOAD_BUILTIN_SPEC")] + pub(crate) builtin_spec: Option, + + /// The name of the builtin spec to print to stdout. This is useful for seeing the structure + /// of the builtin as a starting point for creating your own. + #[clap(long = "print-spec", default_value_t = false)] + pub(crate) print_spec: bool, + + /// The directory to save results to. + /// + /// If not specified, this will default to `results` in the current directory. + /// + /// Files saved here will be organized in a directory structure as follows: + /// ```text + /// results///_