databricks-sql-kernel 0.1.2__tar.gz → 0.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- databricks_sql_kernel-0.2.0/.github/scripts/check-napi-loader-drift.sh +197 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/napi-checks.yml +22 -0
- databricks_sql_kernel-0.2.0/CHANGELOG.md +50 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/Cargo.lock +1 -1
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/Cargo.toml +1 -1
- databricks_sql_kernel-0.2.0/NEXT_CHANGELOG.md +23 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/PKG-INFO +1 -1
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/extract-changelog.sh +4 -1
- databricks_sql_kernel-0.2.0/pyo3/CHANGELOG.md +28 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/Cargo.lock +2 -2
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/Cargo.toml +1 -1
- databricks_sql_kernel-0.2.0/pyo3/NEXT_CHANGELOG.md +35 -0
- databricks_sql_kernel-0.2.0/pyo3/release-notes.txt +26 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/auth.rs +97 -18
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/session.rs +32 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/statement.rs +17 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyproject.toml +1 -1
- databricks_sql_kernel-0.2.0/release-notes.txt +27 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/http.rs +276 -39
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/mod.rs +1 -1
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/retry.rs +96 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/sea.rs +131 -23
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/transport.rs +33 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/config.rs +74 -14
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/lib.rs +1 -1
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/thrift_shape.rs +342 -1
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata_v0.rs +68 -24
- databricks_sql_kernel-0.2.0/src/reader/cloudfetch/arrow_parser.rs +498 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/link_fetcher.rs +8 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/mod.rs +148 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/result_stream.rs +48 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/session.rs +161 -14
- databricks_sql_kernel-0.2.0/src/statement/dml_count.rs +301 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/executed.rs +9 -10
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/executed_async.rs +120 -6
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/mod.rs +2 -1
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/mutable.rs +207 -35
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/spec.rs +160 -28
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/types/sea.rs +58 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_async_execute_wiremock.rs +226 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_execute_e2e.rs +151 -2
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_metadata_e2e.rs +37 -34
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_metadata_wiremock.rs +135 -18
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_query_tags_headers_e2e.rs +10 -7
- databricks_sql_kernel-0.1.2/src/reader/cloudfetch/arrow_parser.rs +0 -272
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/CODEOWNERS +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/actions/setup-jfrog/action.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/dependabot.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/cargo-publish.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/close-stale.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/coverage.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/dco-check.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/license-check.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/pr-checks.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/pyo3-checks.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/rust-e2e.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/securityScan.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/trigger-integration-tests.yml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.gitignore +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/CLAUDE.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/LICENSE +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/Makefile +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/NOTICE.txt +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/README.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/appkit/download-release.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/appkit/poll-release.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-cargo.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-coursier.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-maven.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-npm.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-pip.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/deco-dispatch-tagging-single.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/deco-dispatch-tagging.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/deco-load-maven-creds.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/download-artifact.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/jfrog-oidc-token.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/jfrog-oidc-token.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/maven-central-publish.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/mlflow/ts_publish.ts +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/mlflow/validate_ts_release.ts +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/npm-oidc-publish.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/pypi-oidc-publish.sh +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/CODEOWNERS +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/about.toml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/ci/proxy/htpasswd +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/ci/proxy/squid-auth.conf +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/clippy.toml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/deny.toml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/PECOBLR-2091-retry-logic-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/client-refactor-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/cloudfetch-implementation-plan.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/cloudfetch-pipeline-redesign.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/complex-types-json-stringify.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/connection-metadata-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/fix-duplicate-link-prefetch.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/inline-arrow-results-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/oauth-sprint-plan.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/oauth-u2m-m2m-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/odbc-batch-optimization.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/odbc-metadata-ffi-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/prepared-statement-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/proxy-support-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/result-metadata-propagation.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/tls-config-design.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/migration-plan.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/pr-4-plan.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/pr-5-plan.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/spec-v0.md +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/include/legacy/databricks_metadata_ffi.h +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/license.tpl +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/osv-scanner.toml +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/pytest.ini +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/errors.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/executed_async.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/fetch.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/lib.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/logging.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/macros.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/metadata.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/params.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/result_stream.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/conftest.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_async.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_auth.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_execute.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_metadata.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_module.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_session.py +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/config.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/cache.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/callback.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/m2m.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/oidc.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/token.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/token_store.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/u2m.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/pat.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/error.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/metadata.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/result.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/session.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/statement.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/kernel_error.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/klog.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/logging.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/schemas.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/sql.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/static_data.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/type_mapping.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/chunk_downloader.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/streaming_provider.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/inline/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/inline/provider.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/inline/streaming.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/post_processor/json.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/post_processor/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/test_utils.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/result/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/handle.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/params.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/params_codec.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/validity.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/telemetry/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/types/cloudfetch.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/types/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/util/mod.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/util/runtime.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/oauth_u2m_integration.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_async_execute_e2e.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_execute_wiremock.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_session_e2e.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_session_wiremock.rs +0 -0
- {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_tls_e2e.rs +0 -0
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Drift guard for the committed napi loader.
|
|
3
|
+
#
|
|
4
|
+
# napi/index.js + napi/index.d.ts are GENERATED by `@napi-rs/cli@2.18.4`
|
|
5
|
+
# from the `#[napi]` surface in napi/src/. We commit them because the
|
|
6
|
+
# release workflow uses `@napi-rs/cli@3`, which doesn't emit the loader.
|
|
7
|
+
# This is the only mechanism keeping them in sync — there is no
|
|
8
|
+
# `cargo build` step that would catch staleness.
|
|
9
|
+
#
|
|
10
|
+
# This script catches the most common drift class: a contributor adds a
|
|
11
|
+
# new top-level `#[napi]` function or class in napi/src/ and forgets to
|
|
12
|
+
# regenerate the loader. It parses the Rust source for top-level
|
|
13
|
+
# `#[napi]` items, parses the loader's destructure / module.exports,
|
|
14
|
+
# and fails CI if the symbol sets diverge.
|
|
15
|
+
#
|
|
16
|
+
# Scope:
|
|
17
|
+
# - Detects: missing exports for new `#[napi]` top-level fn / class /
|
|
18
|
+
# enum (with js_name override honored).
|
|
19
|
+
# - Does NOT detect: formatting drift in index.d.ts, type-only changes
|
|
20
|
+
# in `#[napi(object)]` shapes, or signature changes to existing
|
|
21
|
+
# functions. A full regenerate-and-diff (the reviewer's preferred
|
|
22
|
+
# shape) would catch those, but it requires an npm proxy that this
|
|
23
|
+
# repo doesn't yet have on the protected runners.
|
|
24
|
+
#
|
|
25
|
+
# Run from repo root.
|
|
26
|
+
|
|
27
|
+
set -euo pipefail
|
|
28
|
+
|
|
29
|
+
cd "$(git rev-parse --show-toplevel)"
|
|
30
|
+
|
|
31
|
+
# ──────────────────────────────────────────────────────────────────
|
|
32
|
+
# Collect the expected surface from napi/src/**.rs.
|
|
33
|
+
#
|
|
34
|
+
# Rules (matching @napi-rs/cli@2.18.4 behavior):
|
|
35
|
+
# - `#[napi]` on a top-level `pub fn` / `pub async fn` / `pub struct`
|
|
36
|
+
# / `pub enum` exports under the item name (snake_case → camelCase
|
|
37
|
+
# conversion happens for fns; classes / enums keep their name).
|
|
38
|
+
# - `#[napi(js_name = "...")]` overrides the JS name.
|
|
39
|
+
# - `#[napi(object)]` / `#[napi(string_enum)]` items are emitted as
|
|
40
|
+
# TypeScript interfaces / const enums; for index.js they only
|
|
41
|
+
# matter if they're classes — strict objects/string_enums don't
|
|
42
|
+
# appear in the runtime destructure. We collect them separately
|
|
43
|
+
# for the .d.ts check.
|
|
44
|
+
# - Methods inside `impl` blocks (`#[napi]` inside a `#[napi] impl`)
|
|
45
|
+
# are NOT separate exports; the parent class covers them.
|
|
46
|
+
# - Items inside `#[napi]\nimpl Foo` blocks have a column-indented
|
|
47
|
+
# `#[napi]` attribute (column 4+). Top-level items live at column 0.
|
|
48
|
+
# ──────────────────────────────────────────────────────────────────
|
|
49
|
+
|
|
50
|
+
# Parse top-level Rust items: read each .rs file, find `#[napi...]`
|
|
51
|
+
# attributes that start at column 0 (top-level), and look at the next
|
|
52
|
+
# `pub ...` declaration on the next non-blank line. Emits TSV:
|
|
53
|
+
# kind<TAB>js_name
|
|
54
|
+
collect_rust_surface() {
|
|
55
|
+
python3 - <<'PY'
|
|
56
|
+
import re
|
|
57
|
+
import sys
|
|
58
|
+
from pathlib import Path
|
|
59
|
+
|
|
60
|
+
js_name_re = re.compile(r'js_name\s*=\s*"([^"]+)"')
|
|
61
|
+
ATTR_RE = re.compile(r'^#\[napi(?:\(([^)]*)\))?\]$')
|
|
62
|
+
ITEM_RE = re.compile(
|
|
63
|
+
r'^pub\s+(?:async\s+)?(?:fn\s+(\w+)|struct\s+(\w+)|enum\s+(\w+))'
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
def snake_to_camel(s: str) -> str:
|
|
67
|
+
parts = s.split("_")
|
|
68
|
+
return parts[0] + "".join(p.title() for p in parts[1:])
|
|
69
|
+
|
|
70
|
+
for path in sorted(Path("napi/src").rglob("*.rs")):
|
|
71
|
+
lines = path.read_text().splitlines()
|
|
72
|
+
i = 0
|
|
73
|
+
while i < len(lines):
|
|
74
|
+
line = lines[i]
|
|
75
|
+
# Only top-level attributes (column 0).
|
|
76
|
+
m = ATTR_RE.match(line)
|
|
77
|
+
if not m:
|
|
78
|
+
i += 1
|
|
79
|
+
continue
|
|
80
|
+
attr_args = m.group(1) or ""
|
|
81
|
+
# Find the next pub item — skip blank lines, comments, and
|
|
82
|
+
# other attribute lines (e.g. `#[derive(...)]`, `#[serde(...)]`
|
|
83
|
+
# that often sit between the `#[napi]` attribute and the item).
|
|
84
|
+
j = i + 1
|
|
85
|
+
while j < len(lines):
|
|
86
|
+
stripped = lines[j].lstrip()
|
|
87
|
+
if (
|
|
88
|
+
not lines[j].strip()
|
|
89
|
+
or stripped.startswith("//")
|
|
90
|
+
or stripped.startswith("/*")
|
|
91
|
+
or stripped.startswith("*")
|
|
92
|
+
or stripped.startswith("#[")
|
|
93
|
+
):
|
|
94
|
+
j += 1
|
|
95
|
+
continue
|
|
96
|
+
break
|
|
97
|
+
if j >= len(lines):
|
|
98
|
+
i += 1
|
|
99
|
+
continue
|
|
100
|
+
# The pub item must also be column 0 (top-level).
|
|
101
|
+
next_line = lines[j]
|
|
102
|
+
if next_line.startswith(" ") or next_line.startswith("\t"):
|
|
103
|
+
i += 1
|
|
104
|
+
continue
|
|
105
|
+
im = ITEM_RE.match(next_line)
|
|
106
|
+
if not im:
|
|
107
|
+
# Could be `impl Foo` — skip (methods are exported via
|
|
108
|
+
# the parent class).
|
|
109
|
+
i += 1
|
|
110
|
+
continue
|
|
111
|
+
fn_name, struct_name, enum_name = im.groups()
|
|
112
|
+
name = fn_name or struct_name or enum_name
|
|
113
|
+
# Determine the JS name.
|
|
114
|
+
js_match = js_name_re.search(attr_args)
|
|
115
|
+
if js_match:
|
|
116
|
+
js_name = js_match.group(1)
|
|
117
|
+
elif fn_name:
|
|
118
|
+
js_name = snake_to_camel(name)
|
|
119
|
+
else:
|
|
120
|
+
js_name = name # classes/enums keep their PascalCase name
|
|
121
|
+
if "object" in attr_args:
|
|
122
|
+
kind = "object"
|
|
123
|
+
elif "string_enum" in attr_args:
|
|
124
|
+
kind = "string_enum"
|
|
125
|
+
elif fn_name:
|
|
126
|
+
kind = "fn"
|
|
127
|
+
elif struct_name:
|
|
128
|
+
kind = "class"
|
|
129
|
+
else:
|
|
130
|
+
kind = "enum"
|
|
131
|
+
print(f"{kind}\t{js_name}")
|
|
132
|
+
i = j + 1
|
|
133
|
+
PY
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
# ──────────────────────────────────────────────────────────────────
|
|
137
|
+
# Collect the actual destructured exports from napi/index.js.
|
|
138
|
+
# Pattern: `const { A, B, C } = nativeBinding`
|
|
139
|
+
# ──────────────────────────────────────────────────────────────────
|
|
140
|
+
collect_loader_exports() {
|
|
141
|
+
python3 - <<'PY'
|
|
142
|
+
import re
|
|
143
|
+
from pathlib import Path
|
|
144
|
+
|
|
145
|
+
src = Path("napi/index.js").read_text()
|
|
146
|
+
# Find `const { ... } = nativeBinding`
|
|
147
|
+
m = re.search(r"const\s*\{\s*([^}]*)\s*\}\s*=\s*nativeBinding", src)
|
|
148
|
+
if not m:
|
|
149
|
+
raise SystemExit("ERROR: could not find `const { ... } = nativeBinding` destructure in napi/index.js")
|
|
150
|
+
names = [n.strip() for n in m.group(1).split(",") if n.strip()]
|
|
151
|
+
for n in names:
|
|
152
|
+
print(n)
|
|
153
|
+
PY
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
# ──────────────────────────────────────────────────────────────────
|
|
157
|
+
# Compare. Anything in the expected set (fn / class) that isn't in the
|
|
158
|
+
# loader is a drift error. Reverse — names in the loader not in the
|
|
159
|
+
# Rust source — is also a drift error (something was removed).
|
|
160
|
+
# `object` and `string_enum` items aren't in the runtime destructure;
|
|
161
|
+
# they're checked separately against index.d.ts below.
|
|
162
|
+
# ──────────────────────────────────────────────────────────────────
|
|
163
|
+
|
|
164
|
+
EXPECTED_RUNTIME=$(collect_rust_surface | awk -F'\t' '$1 == "fn" || $1 == "class" || $1 == "enum" || $1 == "string_enum" {print $2}' | sort -u)
|
|
165
|
+
ACTUAL_RUNTIME=$(collect_loader_exports | sort -u)
|
|
166
|
+
|
|
167
|
+
missing=$(comm -23 <(echo "$EXPECTED_RUNTIME") <(echo "$ACTUAL_RUNTIME"))
|
|
168
|
+
extra=$(comm -13 <(echo "$EXPECTED_RUNTIME") <(echo "$ACTUAL_RUNTIME"))
|
|
169
|
+
|
|
170
|
+
fail=0
|
|
171
|
+
if [[ -n "$missing" ]]; then
|
|
172
|
+
echo "::error::napi loader is missing exports for these #[napi] symbols:" >&2
|
|
173
|
+
echo "$missing" | sed 's/^/ - /' >&2
|
|
174
|
+
fail=1
|
|
175
|
+
fi
|
|
176
|
+
if [[ -n "$extra" ]]; then
|
|
177
|
+
echo "::error::napi loader exports symbols that no longer exist in napi/src/:" >&2
|
|
178
|
+
echo "$extra" | sed 's/^/ - /' >&2
|
|
179
|
+
fail=1
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
if [[ $fail -eq 1 ]]; then
|
|
183
|
+
cat >&2 <<EOF
|
|
184
|
+
|
|
185
|
+
To fix, regenerate the loader and recommit:
|
|
186
|
+
|
|
187
|
+
cd napi && npx --yes @napi-rs/cli@2.18.4 build --platform \\
|
|
188
|
+
--js-package-name @databricks/databricks-sql-kernel --release
|
|
189
|
+
git add napi/index.js napi/index.d.ts && git commit --amend --no-edit
|
|
190
|
+
|
|
191
|
+
See napi/.gitignore for the full regen procedure note.
|
|
192
|
+
EOF
|
|
193
|
+
exit 1
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
count=$(printf '%s\n' "$EXPECTED_RUNTIME" | grep -c .)
|
|
197
|
+
echo "napi loader is in sync with #[napi] surface (${count} symbols)."
|
{databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/napi-checks.yml
RENAMED
|
@@ -133,6 +133,28 @@ jobs:
|
|
|
133
133
|
# secrets — purely cdylib + rlib in-tree tests.
|
|
134
134
|
run: cargo test --locked
|
|
135
135
|
|
|
136
|
+
# Drift guard for the committed loader (napi/index.js +
|
|
137
|
+
# napi/index.d.ts). PR #146 review feedback: nothing in CI
|
|
138
|
+
# detects when a contributor adds a top-level `#[napi]` symbol
|
|
139
|
+
# without recommitting the generated loader, and that already
|
|
140
|
+
# happened once (3 logger exports went missing in #146 before
|
|
141
|
+
# this check landed).
|
|
142
|
+
#
|
|
143
|
+
# This is a SURFACE audit, not a full regenerate-and-diff —
|
|
144
|
+
# parses napi/src/**.rs for top-level `#[napi]` items and
|
|
145
|
+
# compares against the destructured names in napi/index.js.
|
|
146
|
+
# Catches the "new export missing" bug class without needing
|
|
147
|
+
# an npm proxy on the protected runner (which doesn't yet
|
|
148
|
+
# exist; see .github/actions/setup-jfrog/action.yml — npm
|
|
149
|
+
# support is a "future" item). When npm-via-JFrog lands, this
|
|
150
|
+
# step should be replaced with the full reviewer-preferred
|
|
151
|
+
# form: `npx --yes @napi-rs/cli@2.18.4 build --platform ...`
|
|
152
|
+
# then `git diff --exit-code -- napi/index.js napi/index.d.ts`.
|
|
153
|
+
# Tracked in the PR #146 discussion.
|
|
154
|
+
- name: Check napi loader is in sync with #[napi] surface
|
|
155
|
+
working-directory: ${{ github.workspace }}
|
|
156
|
+
run: bash .github/scripts/check-napi-loader-drift.sh
|
|
157
|
+
|
|
136
158
|
# Release-profile build verifies the cdylib actually links with
|
|
137
159
|
# the production profile knobs (lto=true, codegen-units=1,
|
|
138
160
|
# strip="debuginfo"). The lto=true link is the slow part (~4 min
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Version Changelog — Rust crate (`databricks-sql-kernel`)
|
|
2
|
+
|
|
3
|
+
This changelog tracks releases of the Rust crate published to crates.io.
|
|
4
|
+
The Python (pyo3) and Node.js (napi) bindings have their own changelogs
|
|
5
|
+
under [`pyo3/CHANGELOG.md`](pyo3/CHANGELOG.md) and
|
|
6
|
+
[`napi/CHANGELOG.md`](napi/CHANGELOG.md); they ship on independent
|
|
7
|
+
cadences and may not move in lockstep with the crate.
|
|
8
|
+
|
|
9
|
+
## [v0.2.0] - 2026-06-08
|
|
10
|
+
|
|
11
|
+
**Beta release of the Databricks SQL Kernel.** Bumps the crate out
|
|
12
|
+
of its initial-public-release line into a beta-quality cut intended
|
|
13
|
+
for downstream-driver adoption (Reyden bring-up in
|
|
14
|
+
`databricks-sql-connector` and `@databricks/sql`). Public API
|
|
15
|
+
surface is stable; behaviour changes captured below.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
- `Statement::execute_direct()` — directResults execution (the
|
|
19
|
+
Thrift/JDBC model): one `ExecuteStatement` POST with the server
|
|
20
|
+
inline wait, returning `DirectStatement::Completed` (terminal,
|
|
21
|
+
result materialised inline) or `DirectStatement::Running` (a
|
|
22
|
+
poll/cancel handle) **without** an internal poll loop. Added
|
|
23
|
+
**alongside** an unchanged blocking `execute()`.
|
|
24
|
+
|
|
25
|
+
### Updated
|
|
26
|
+
- Removed `StatementSpec::query_timeout_secs` and the
|
|
27
|
+
`resolve_wait_timeout` `CANCEL` branch: it mapped a per-statement
|
|
28
|
+
timeout onto the SEA `wait_timeout` field, which is the server's
|
|
29
|
+
inline-hold window (capped 5–50s), not a statement-execution
|
|
30
|
+
timeout (use the `STATEMENT_TIMEOUT` SQL conf for that). The sync
|
|
31
|
+
path now always omits `wait_timeout`.
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
- `terminal_outcome`: `CLOSED` is now an unconditional terminal
|
|
35
|
+
**success** (parity with JDBC's `DatabricksSdkClient`); an empty
|
|
36
|
+
`CLOSED` materialises an empty result set instead of erroring
|
|
37
|
+
with `invalid_state("Statement was closed")`. Reaches all callers
|
|
38
|
+
(`execute()`, `fetch_completed_result`, `execute_direct`).
|
|
39
|
+
|
|
40
|
+
## [v0.1.2] - 2026-06-06
|
|
41
|
+
|
|
42
|
+
Initial public release of the Rust kernel core.
|
|
43
|
+
|
|
44
|
+
### Added
|
|
45
|
+
- `databricks-sql-kernel` Rust crate published to crates.io.
|
|
46
|
+
- Async public API: `Session` → `Statement` → `ExecutedStatement` /
|
|
47
|
+
`ExecutedAsyncStatement` → `ResultStream`, plus a flat `Metadata`
|
|
48
|
+
surface (see `docs/spec-v0.md`).
|
|
49
|
+
- SEA backend (Statement Execution API) with CloudFetch and inline-Arrow
|
|
50
|
+
result paths; PAT, OAuth M2M, and OAuth U2M authentication.
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# NEXT CHANGELOG — Rust crate (`databricks-sql-kernel`)
|
|
2
|
+
|
|
3
|
+
This file stages unreleased changes for the next Rust crate release.
|
|
4
|
+
The Python (pyo3) and Node.js (napi) bindings stage their own
|
|
5
|
+
unreleased changes under [`pyo3/NEXT_CHANGELOG.md`](pyo3/NEXT_CHANGELOG.md)
|
|
6
|
+
and [`napi/NEXT_CHANGELOG.md`](napi/NEXT_CHANGELOG.md). Only land entries
|
|
7
|
+
here that affect the Rust crate's public API or behaviour; binding-only
|
|
8
|
+
changes go in their respective binding's NEXT_CHANGELOG.
|
|
9
|
+
|
|
10
|
+
## [Unreleased]
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
### Updated
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
*Note: When making changes, please add your change under the appropriate
|
|
20
|
+
section with a brief description. At release time, move the entries here
|
|
21
|
+
into a new versioned section at the top of `CHANGELOG.md` (heading format
|
|
22
|
+
`## [v<version>] - <YYYY-MM-DD>`) and reset this file back to the empty
|
|
23
|
+
template above.*
|
|
@@ -18,8 +18,11 @@ set -euo pipefail
|
|
|
18
18
|
CHANGELOG="${1:?Usage: extract-changelog.sh <changelog-file> <version>}"
|
|
19
19
|
VERSION="${2:?Usage: extract-changelog.sh <changelog-file> <version>}"
|
|
20
20
|
|
|
21
|
-
# Strip leading 'v'
|
|
21
|
+
# Strip leading 'v' and any prerelease suffix (e.g. -rc.1) for matching:
|
|
22
|
+
# an RC tag (v0.1.2-rc.1) should resolve to the release version's notes
|
|
23
|
+
# (0.1.2). Match with or without the 'v'.
|
|
22
24
|
VERSION_BARE="${VERSION#v}"
|
|
25
|
+
VERSION_BARE="${VERSION_BARE%%-*}"
|
|
23
26
|
|
|
24
27
|
if [[ ! -f "$CHANGELOG" ]]; then
|
|
25
28
|
echo "::error::Changelog file not found: ${CHANGELOG}"
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Version Changelog — Python binding (`databricks-sql-kernel`)
|
|
2
|
+
|
|
3
|
+
This changelog tracks releases of the Python wheel published to PyPI as
|
|
4
|
+
`databricks-sql-kernel` (built from this `pyo3/` directory). The Rust
|
|
5
|
+
crate and Node.js binding have their own changelogs under
|
|
6
|
+
[`../CHANGELOG.md`](../CHANGELOG.md) and [`../napi/CHANGELOG.md`](../napi/CHANGELOG.md);
|
|
7
|
+
they ship on independent cadences.
|
|
8
|
+
|
|
9
|
+
## [v0.2.0] - 2026-06-08
|
|
10
|
+
|
|
11
|
+
**Beta release of the Databricks SQL Kernel (Python binding).**
|
|
12
|
+
Ships on PyPI as `databricks-sql-kernel==0.2.0`. The pyo3 surface
|
|
13
|
+
is unchanged from v0.1.2; this release picks up the
|
|
14
|
+
kernel-side v0.2.0 behaviour changes (see the root
|
|
15
|
+
[`../CHANGELOG.md`](../CHANGELOG.md) — `execute_direct`,
|
|
16
|
+
`wait_timeout` removal, `CLOSED`-as-success fix). Intended for
|
|
17
|
+
downstream-driver adoption in `databricks-sql-connector[kernel]`.
|
|
18
|
+
|
|
19
|
+
## [v0.1.2] - 2026-06-06
|
|
20
|
+
|
|
21
|
+
Initial public release of the Python binding.
|
|
22
|
+
|
|
23
|
+
### Added
|
|
24
|
+
- Python bindings published to PyPI as `databricks-sql-kernel`.
|
|
25
|
+
- abi3 wheels for Linux (manylinux_2_28 x86_64/aarch64), macOS
|
|
26
|
+
(x86_64/arm64), and Windows (x86_64), plus a source distribution.
|
|
27
|
+
- pyo3-based bridge over the Rust kernel's async public API with PyArrow
|
|
28
|
+
interop for result batches.
|
|
@@ -380,7 +380,7 @@ dependencies = [
|
|
|
380
380
|
|
|
381
381
|
[[package]]
|
|
382
382
|
name = "databricks-sql-kernel"
|
|
383
|
-
version = "0.
|
|
383
|
+
version = "0.2.0"
|
|
384
384
|
dependencies = [
|
|
385
385
|
"arrow-array",
|
|
386
386
|
"arrow-buffer",
|
|
@@ -412,7 +412,7 @@ dependencies = [
|
|
|
412
412
|
|
|
413
413
|
[[package]]
|
|
414
414
|
name = "databricks-sql-kernel-pyo3"
|
|
415
|
-
version = "0.
|
|
415
|
+
version = "0.2.0"
|
|
416
416
|
dependencies = [
|
|
417
417
|
"arrow-array",
|
|
418
418
|
"arrow-pyarrow",
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# NEXT CHANGELOG — Python binding (`databricks-sql-kernel`)
|
|
2
|
+
|
|
3
|
+
This file stages unreleased changes for the next Python wheel release.
|
|
4
|
+
The Rust crate and Node.js binding stage their own unreleased changes
|
|
5
|
+
under [`../NEXT_CHANGELOG.md`](../NEXT_CHANGELOG.md) and
|
|
6
|
+
[`../napi/NEXT_CHANGELOG.md`](../napi/NEXT_CHANGELOG.md).
|
|
7
|
+
|
|
8
|
+
Only land entries here that affect the Python wheel — pyo3 glue, the
|
|
9
|
+
Python API surface, packaging / wheel-build behaviour. Pure-kernel
|
|
10
|
+
changes go in the root `NEXT_CHANGELOG.md`.
|
|
11
|
+
|
|
12
|
+
## [Unreleased]
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
### Updated
|
|
17
|
+
|
|
18
|
+
### Fixed
|
|
19
|
+
- `auth_type="oauth-u2m"` now defaults scopes to `["sql", "offline_access"]`
|
|
20
|
+
when the caller passes neither `client_id` nor `scopes`. The Python binding
|
|
21
|
+
defaults the U2M client to `databricks-sql-python` (vs. the kernel's
|
|
22
|
+
`databricks-cli`), but that client isn't registered for the `all-apis` scope
|
|
23
|
+
the kernel intrinsically defaults to — so an out-of-the-box
|
|
24
|
+
`Session(auth_type="oauth-u2m")` failed the authorization request with
|
|
25
|
+
`access_denied — Scopes 'all-apis' are not assigned to the client
|
|
26
|
+
databricks-sql-python`. Defaults now match `PYSQL_OAUTH_SCOPES` in the
|
|
27
|
+
standalone Thrift connector, restoring `use_kernel=True` parity. A
|
|
28
|
+
caller-supplied `client_id` or `scopes` is still honoured verbatim.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
*Note: When making changes, please add your change under the appropriate
|
|
32
|
+
section with a brief description. At release time, move the entries here
|
|
33
|
+
into a new versioned section at the top of `CHANGELOG.md` (heading format
|
|
34
|
+
`## [v<version>] - <YYYY-MM-DD>`) and reset this file back to the empty
|
|
35
|
+
template above.*
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
==============================================================================
|
|
2
|
+
Databricks SQL Kernel — Python binding Release Notes
|
|
3
|
+
==============================================================================
|
|
4
|
+
|
|
5
|
+
These release notes summarize enhancements, new features, known issues,
|
|
6
|
+
and version history for the Python wheel published to PyPI as
|
|
7
|
+
`databricks-sql-kernel` (built from this directory via pyo3 + maturin).
|
|
8
|
+
|
|
9
|
+
The Rust crate and Node.js (napi) bindings ship on independent cadences;
|
|
10
|
+
their release notes live at `../release-notes.txt` and
|
|
11
|
+
`../napi/release-notes.txt`.
|
|
12
|
+
|
|
13
|
+
Version History ==============================================================
|
|
14
|
+
|
|
15
|
+
0.1.2 ========================================================================
|
|
16
|
+
Released 2026-06-06
|
|
17
|
+
|
|
18
|
+
Initial public release of the Python binding.
|
|
19
|
+
|
|
20
|
+
Enhancements & New Features
|
|
21
|
+
|
|
22
|
+
* Python bindings published to PyPI as `databricks-sql-kernel`.
|
|
23
|
+
* abi3 wheels for Linux (manylinux_2_28 x86_64/aarch64), macOS
|
|
24
|
+
(x86_64/arm64), and Windows (x86_64), plus a source distribution.
|
|
25
|
+
* pyo3-based bridge over the Rust kernel's async public API with PyArrow
|
|
26
|
+
interop for result batches.
|
|
@@ -76,6 +76,30 @@ pub(crate) struct OAuthParams {
|
|
|
76
76
|
/// OAuth app identity, not the on-disk cache.
|
|
77
77
|
const PYSQL_OAUTH_CLIENT_ID: &str = "databricks-sql-python";
|
|
78
78
|
|
|
79
|
+
/// Default U2M scopes for the **Python** binding when the caller relies
|
|
80
|
+
/// on the default `PYSQL_OAUTH_CLIENT_ID` above.
|
|
81
|
+
///
|
|
82
|
+
/// The kernel's intrinsic U2M default is `["all-apis", "offline_access"]`,
|
|
83
|
+
/// which is correct for its bare-Rust default client (`databricks-cli`).
|
|
84
|
+
/// But the Python binding overrides the default client to
|
|
85
|
+
/// `databricks-sql-python` — and *that* client is only registered for
|
|
86
|
+
/// `sql` (plus `offline_access`) on the Databricks IdP. Without a
|
|
87
|
+
/// matching scope override here, an out-of-the-box
|
|
88
|
+
/// `Session(auth_type="oauth-u2m")` from Python fails on the
|
|
89
|
+
/// authorization request with
|
|
90
|
+
/// `access_denied — Scopes 'all-apis' are not assigned to the client
|
|
91
|
+
/// databricks-sql-python`.
|
|
92
|
+
///
|
|
93
|
+
/// Matches `PYSQL_OAUTH_SCOPES` in the Thrift connector
|
|
94
|
+
/// (`databricks-sql-python` `auth/auth.py`), so `use_kernel=True` is
|
|
95
|
+
/// drop-in compatible with the standalone Thrift path.
|
|
96
|
+
///
|
|
97
|
+
/// Only applied when the caller passed neither `client_id` nor `scopes`
|
|
98
|
+
/// — a caller supplying their own `client_id` may legitimately want
|
|
99
|
+
/// `all-apis` (or anything else), and an explicit `scopes` is always
|
|
100
|
+
/// honoured verbatim.
|
|
101
|
+
const PYSQL_OAUTH_SCOPES: &[&str] = &["sql", "offline_access"];
|
|
102
|
+
|
|
79
103
|
/// Build a kernel `AuthConfig` from the Python kwargs the `Session`
|
|
80
104
|
/// constructor accepts.
|
|
81
105
|
///
|
|
@@ -157,23 +181,39 @@ fn build_auth_config_inner(
|
|
|
157
181
|
.to_owned(),
|
|
158
182
|
);
|
|
159
183
|
}
|
|
184
|
+
// Default the U2M OAuth client to the Python connector's
|
|
185
|
+
// own registered client (`databricks-sql-python`), NOT the
|
|
186
|
+
// kernel's bare-Rust fallback (`databricks-cli`). This
|
|
187
|
+
// matches the standalone Thrift connector
|
|
188
|
+
// (`PYSQL_OAUTH_CLIENT_ID` in databricks-sql-python's
|
|
189
|
+
// auth.py) so a user gets the same OAuth app identity — and
|
|
190
|
+
// the same SSO token cache entry — whether they use the
|
|
191
|
+
// Thrift backend or `use_kernel=True`. It also keeps the
|
|
192
|
+
// kernel's per-{host,client_id,scopes} token cache distinct
|
|
193
|
+
// from the napi (Node) binding's, which defaults to its own
|
|
194
|
+
// client.
|
|
195
|
+
//
|
|
196
|
+
// When BOTH defaults are in play (caller passed no
|
|
197
|
+
// `client_id` and no `scopes`), also default the scopes to
|
|
198
|
+
// the Python-binding set so the default client/scopes pair
|
|
199
|
+
// is internally consistent. The kernel's intrinsic scope
|
|
200
|
+
// default is for its `databricks-cli` client, not for
|
|
201
|
+
// `databricks-sql-python` — see `PYSQL_OAUTH_SCOPES` above.
|
|
202
|
+
let caller_set_client_id = oauth.client_id.is_some();
|
|
203
|
+
let client_id = oauth
|
|
204
|
+
.client_id
|
|
205
|
+
.or_else(|| Some(PYSQL_OAUTH_CLIENT_ID.to_owned()));
|
|
206
|
+
let scopes = match oauth.scopes {
|
|
207
|
+
Some(s) => Some(s),
|
|
208
|
+
None if !caller_set_client_id => {
|
|
209
|
+
Some(PYSQL_OAUTH_SCOPES.iter().map(|s| (*s).to_owned()).collect())
|
|
210
|
+
}
|
|
211
|
+
None => None,
|
|
212
|
+
};
|
|
160
213
|
Ok(AuthConfig::OAuthU2M {
|
|
161
|
-
|
|
162
|
-
// own registered client (`databricks-sql-python`), NOT
|
|
163
|
-
// the kernel's bare-Rust fallback (`databricks-cli`).
|
|
164
|
-
// This matches the standalone Thrift connector
|
|
165
|
-
// (`PYSQL_OAUTH_CLIENT_ID` in databricks-sql-python's
|
|
166
|
-
// auth.py) so a user gets the same OAuth app identity —
|
|
167
|
-
// and the same SSO token cache entry — whether they use
|
|
168
|
-
// the Thrift backend or `use_kernel=True`. It also keeps
|
|
169
|
-
// the kernel's per-{host,client_id,scopes} token cache
|
|
170
|
-
// distinct from the napi (Node) binding's, which defaults
|
|
171
|
-
// to its own client.
|
|
172
|
-
client_id: oauth
|
|
173
|
-
.client_id
|
|
174
|
-
.or_else(|| Some(PYSQL_OAUTH_CLIENT_ID.to_owned())),
|
|
214
|
+
client_id,
|
|
175
215
|
redirect_port: oauth.redirect_port,
|
|
176
|
-
scopes
|
|
216
|
+
scopes,
|
|
177
217
|
token_url_override: oauth.token_url,
|
|
178
218
|
callback_timeout: oauth.callback_timeout_secs.map(Duration::from_secs),
|
|
179
219
|
})
|
|
@@ -285,11 +325,16 @@ mod tests {
|
|
|
285
325
|
}
|
|
286
326
|
|
|
287
327
|
#[test]
|
|
288
|
-
fn
|
|
328
|
+
fn u2m_defaults_client_id_and_scopes_to_python_connector() {
|
|
289
329
|
// U2M takes no mandatory fields. The Python binding defaults the
|
|
290
330
|
// OAuth client_id to `databricks-sql-python` (NOT the kernel's
|
|
291
331
|
// bare `databricks-cli`) so it matches the standalone Thrift
|
|
292
332
|
// connector and the napi binding gets a distinct cache key.
|
|
333
|
+
// It also defaults the scopes to `["sql", "offline_access"]` to
|
|
334
|
+
// match the scopes registered for that client on the Databricks
|
|
335
|
+
// IdP — the kernel's intrinsic `all-apis` default is for its
|
|
336
|
+
// own `databricks-cli` client, which `databricks-sql-python`
|
|
337
|
+
// isn't allowed to request.
|
|
293
338
|
let cfg = build_auth_config_inner("oauth-u2m", None, OAuthParams::default()).unwrap();
|
|
294
339
|
match cfg {
|
|
295
340
|
AuthConfig::OAuthU2M {
|
|
@@ -301,7 +346,10 @@ mod tests {
|
|
|
301
346
|
} => {
|
|
302
347
|
assert_eq!(client_id.as_deref(), Some("databricks-sql-python"));
|
|
303
348
|
assert!(redirect_port.is_none());
|
|
304
|
-
|
|
349
|
+
assert_eq!(
|
|
350
|
+
scopes,
|
|
351
|
+
Some(vec!["sql".to_string(), "offline_access".to_string()])
|
|
352
|
+
);
|
|
305
353
|
assert!(token_url_override.is_none());
|
|
306
354
|
assert!(callback_timeout.is_none());
|
|
307
355
|
}
|
|
@@ -321,8 +369,39 @@ mod tests {
|
|
|
321
369
|
)
|
|
322
370
|
.unwrap();
|
|
323
371
|
match cfg {
|
|
324
|
-
AuthConfig::OAuthU2M {
|
|
372
|
+
AuthConfig::OAuthU2M {
|
|
373
|
+
client_id, scopes, ..
|
|
374
|
+
} => {
|
|
325
375
|
assert_eq!(client_id.as_deref(), Some("my-custom-app"));
|
|
376
|
+
// Custom client_id without scopes: don't override the
|
|
377
|
+
// kernel's default scopes — a custom client may
|
|
378
|
+
// legitimately request `all-apis` (or anything else).
|
|
379
|
+
assert!(scopes.is_none());
|
|
380
|
+
}
|
|
381
|
+
other => panic!("expected OAuthU2M, got {other:?}"),
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
#[test]
|
|
386
|
+
fn u2m_explicit_scopes_are_honoured_verbatim() {
|
|
387
|
+
// Caller-supplied scopes win over the Python-binding default,
|
|
388
|
+
// both with the default client_id and with a custom one.
|
|
389
|
+
let custom = vec!["all-apis".to_string(), "offline_access".to_string()];
|
|
390
|
+
let cfg = build_auth_config_inner(
|
|
391
|
+
"oauth-u2m",
|
|
392
|
+
None,
|
|
393
|
+
OAuthParams {
|
|
394
|
+
scopes: Some(custom.clone()),
|
|
395
|
+
..Default::default()
|
|
396
|
+
},
|
|
397
|
+
)
|
|
398
|
+
.unwrap();
|
|
399
|
+
match cfg {
|
|
400
|
+
AuthConfig::OAuthU2M {
|
|
401
|
+
client_id, scopes, ..
|
|
402
|
+
} => {
|
|
403
|
+
assert_eq!(client_id.as_deref(), Some("databricks-sql-python"));
|
|
404
|
+
assert_eq!(scopes, Some(custom));
|
|
326
405
|
}
|
|
327
406
|
other => panic!("expected OAuthU2M, got {other:?}"),
|
|
328
407
|
}
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
//! pyclass alive longer than the user keeps a reference.
|
|
22
22
|
|
|
23
23
|
use crate::auth::{build_auth_config, OAuthParams};
|
|
24
|
+
use crate::executed_async::ExecutedAsyncStatement;
|
|
24
25
|
use crate::metadata::Metadata;
|
|
25
26
|
use crate::statement::Statement;
|
|
26
27
|
use databricks_sql_kernel::Session as KSession;
|
|
@@ -341,6 +342,37 @@ impl Session {
|
|
|
341
342
|
Ok(Metadata::new(kmeta, inner.runtime.clone()))
|
|
342
343
|
}
|
|
343
344
|
|
|
345
|
+
/// Re-attach to an already-submitted server statement by its id,
|
|
346
|
+
/// returning an `ExecutedAsyncStatement` the caller can poll
|
|
347
|
+
/// (`status()`), await (`await_result()`), or cancel/close — without
|
|
348
|
+
/// having been the handle that submitted it.
|
|
349
|
+
///
|
|
350
|
+
/// This is the resume path the connector uses for
|
|
351
|
+
/// `get_query_state` / `get_async_execution_result`: server
|
|
352
|
+
/// statement state is keyed solely by the id, so a caller holding
|
|
353
|
+
/// only the id can recover a working handle bound to this session.
|
|
354
|
+
///
|
|
355
|
+
/// Issues one `GetStatementStatus` to seed the handle. Raises
|
|
356
|
+
/// `KernelError` with code `NotFound` if the server doesn't
|
|
357
|
+
/// recognise the id (never submitted, or its result TTL elapsed). A
|
|
358
|
+
/// *closed* statement is not an error — the server keeps reporting
|
|
359
|
+
/// `CLOSED` (and terminal `SUCCEEDED`/`FAILED`) until GC, so the
|
|
360
|
+
/// returned handle's `status()` surfaces the real server state.
|
|
361
|
+
fn attach_async_statement(
|
|
362
|
+
&self,
|
|
363
|
+
py: Python<'_>,
|
|
364
|
+
statement_id: String,
|
|
365
|
+
) -> PyResult<ExecutedAsyncStatement> {
|
|
366
|
+
let inner = alive!(self, "Session");
|
|
367
|
+
let runtime = inner.runtime.clone();
|
|
368
|
+
tracing::debug!(
|
|
369
|
+
target: crate::logging::PYO3_LOG_TARGET,
|
|
370
|
+
"Session.attach_async_statement: re-attaching by id (GIL released)"
|
|
371
|
+
);
|
|
372
|
+
let exec = run_kernel!(py, runtime, inner.session.attach_async_statement(statement_id))?;
|
|
373
|
+
Ok(ExecutedAsyncStatement::new(exec, runtime))
|
|
374
|
+
}
|
|
375
|
+
|
|
344
376
|
/// Explicitly close the session. Idempotent. Subsequent calls on
|
|
345
377
|
/// this `Session` raise `KernelError`.
|
|
346
378
|
fn close(&mut self, py: Python<'_>) -> PyResult<()> {
|