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.
Files changed (178) hide show
  1. databricks_sql_kernel-0.2.0/.github/scripts/check-napi-loader-drift.sh +197 -0
  2. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/napi-checks.yml +22 -0
  3. databricks_sql_kernel-0.2.0/CHANGELOG.md +50 -0
  4. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/Cargo.lock +1 -1
  5. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/Cargo.toml +1 -1
  6. databricks_sql_kernel-0.2.0/NEXT_CHANGELOG.md +23 -0
  7. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/PKG-INFO +1 -1
  8. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/extract-changelog.sh +4 -1
  9. databricks_sql_kernel-0.2.0/pyo3/CHANGELOG.md +28 -0
  10. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/Cargo.lock +2 -2
  11. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/Cargo.toml +1 -1
  12. databricks_sql_kernel-0.2.0/pyo3/NEXT_CHANGELOG.md +35 -0
  13. databricks_sql_kernel-0.2.0/pyo3/release-notes.txt +26 -0
  14. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/auth.rs +97 -18
  15. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/session.rs +32 -0
  16. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/statement.rs +17 -0
  17. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyproject.toml +1 -1
  18. databricks_sql_kernel-0.2.0/release-notes.txt +27 -0
  19. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/http.rs +276 -39
  20. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/mod.rs +1 -1
  21. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/retry.rs +96 -0
  22. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/sea.rs +131 -23
  23. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/client/transport.rs +33 -0
  24. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/config.rs +74 -14
  25. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/lib.rs +1 -1
  26. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/thrift_shape.rs +342 -1
  27. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata_v0.rs +68 -24
  28. databricks_sql_kernel-0.2.0/src/reader/cloudfetch/arrow_parser.rs +498 -0
  29. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/link_fetcher.rs +8 -0
  30. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/mod.rs +148 -0
  31. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/result_stream.rs +48 -0
  32. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/session.rs +161 -14
  33. databricks_sql_kernel-0.2.0/src/statement/dml_count.rs +301 -0
  34. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/executed.rs +9 -10
  35. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/executed_async.rs +120 -6
  36. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/mod.rs +2 -1
  37. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/mutable.rs +207 -35
  38. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/spec.rs +160 -28
  39. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/types/sea.rs +58 -0
  40. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_async_execute_wiremock.rs +226 -0
  41. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_execute_e2e.rs +151 -2
  42. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_metadata_e2e.rs +37 -34
  43. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_metadata_wiremock.rs +135 -18
  44. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_query_tags_headers_e2e.rs +10 -7
  45. databricks_sql_kernel-0.1.2/src/reader/cloudfetch/arrow_parser.rs +0 -272
  46. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/CODEOWNERS +0 -0
  47. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/actions/setup-jfrog/action.yml +0 -0
  48. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/dependabot.yml +0 -0
  49. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/cargo-publish.yml +0 -0
  50. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/close-stale.yml +0 -0
  51. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/coverage.yml +0 -0
  52. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/dco-check.yml +0 -0
  53. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/license-check.yml +0 -0
  54. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/pr-checks.yml +0 -0
  55. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/pyo3-checks.yml +0 -0
  56. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/rust-e2e.yml +0 -0
  57. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/securityScan.yml +0 -0
  58. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.github/workflows/trigger-integration-tests.yml +0 -0
  59. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/.gitignore +0 -0
  60. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/CLAUDE.md +0 -0
  61. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/LICENSE +0 -0
  62. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/Makefile +0 -0
  63. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/NOTICE.txt +0 -0
  64. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/README.md +0 -0
  65. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/appkit/download-release.sh +0 -0
  66. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/appkit/poll-release.sh +0 -0
  67. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-cargo.sh +0 -0
  68. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-coursier.sh +0 -0
  69. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-maven.sh +0 -0
  70. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-npm.sh +0 -0
  71. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/configure-pip.sh +0 -0
  72. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/deco-dispatch-tagging-single.sh +0 -0
  73. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/deco-dispatch-tagging.sh +0 -0
  74. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/deco-load-maven-creds.sh +0 -0
  75. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/download-artifact.sh +0 -0
  76. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/jfrog-oidc-token.py +0 -0
  77. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/jfrog-oidc-token.sh +0 -0
  78. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/maven-central-publish.sh +0 -0
  79. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/mlflow/ts_publish.ts +0 -0
  80. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/mlflow/validate_ts_release.ts +0 -0
  81. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/npm-oidc-publish.sh +0 -0
  82. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/.github/scripts/pypi-oidc-publish.sh +0 -0
  83. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/_release-scripts/CODEOWNERS +0 -0
  84. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/about.toml +0 -0
  85. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/ci/proxy/htpasswd +0 -0
  86. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/ci/proxy/squid-auth.conf +0 -0
  87. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/clippy.toml +0 -0
  88. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/deny.toml +0 -0
  89. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/PECOBLR-2091-retry-logic-design.md +0 -0
  90. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/client-refactor-design.md +0 -0
  91. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/cloudfetch-implementation-plan.md +0 -0
  92. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/cloudfetch-pipeline-redesign.md +0 -0
  93. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/complex-types-json-stringify.md +0 -0
  94. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/connection-metadata-design.md +0 -0
  95. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/fix-duplicate-link-prefetch.md +0 -0
  96. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/inline-arrow-results-design.md +0 -0
  97. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/oauth-sprint-plan.md +0 -0
  98. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/oauth-u2m-m2m-design.md +0 -0
  99. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/odbc-batch-optimization.md +0 -0
  100. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/odbc-metadata-ffi-design.md +0 -0
  101. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/prepared-statement-design.md +0 -0
  102. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/proxy-support-design.md +0 -0
  103. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/result-metadata-propagation.md +0 -0
  104. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/designs/tls-config-design.md +0 -0
  105. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/migration-plan.md +0 -0
  106. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/pr-4-plan.md +0 -0
  107. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/pr-5-plan.md +0 -0
  108. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/docs/spec-v0.md +0 -0
  109. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/include/legacy/databricks_metadata_ffi.h +0 -0
  110. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/license.tpl +0 -0
  111. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/osv-scanner.toml +0 -0
  112. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/pytest.ini +0 -0
  113. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/errors.rs +0 -0
  114. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/executed_async.rs +0 -0
  115. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/fetch.rs +0 -0
  116. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/lib.rs +0 -0
  117. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/logging.rs +0 -0
  118. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/macros.rs +0 -0
  119. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/metadata.rs +0 -0
  120. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/params.rs +0 -0
  121. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/src/result_stream.rs +0 -0
  122. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/conftest.py +0 -0
  123. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_async.py +0 -0
  124. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_auth.py +0 -0
  125. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_execute.py +0 -0
  126. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_metadata.py +0 -0
  127. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_module.py +0 -0
  128. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/pyo3/tests/test_session.py +0 -0
  129. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/config.rs +0 -0
  130. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/mod.rs +0 -0
  131. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/cache.rs +0 -0
  132. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/callback.rs +0 -0
  133. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/m2m.rs +0 -0
  134. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/mod.rs +0 -0
  135. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/oidc.rs +0 -0
  136. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/token.rs +0 -0
  137. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/token_store.rs +0 -0
  138. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/oauth/u2m.rs +0 -0
  139. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/auth/pat.rs +0 -0
  140. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/error.rs +0 -0
  141. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/metadata.rs +0 -0
  142. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/mod.rs +0 -0
  143. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/result.rs +0 -0
  144. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/session.rs +0 -0
  145. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/ffi/statement.rs +0 -0
  146. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/kernel_error.rs +0 -0
  147. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/klog.rs +0 -0
  148. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/logging.rs +0 -0
  149. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/mod.rs +0 -0
  150. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/schemas.rs +0 -0
  151. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/sql.rs +0 -0
  152. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/static_data.rs +0 -0
  153. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/metadata/type_mapping.rs +0 -0
  154. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/chunk_downloader.rs +0 -0
  155. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/mod.rs +0 -0
  156. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/cloudfetch/streaming_provider.rs +0 -0
  157. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/inline/mod.rs +0 -0
  158. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/inline/provider.rs +0 -0
  159. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/inline/streaming.rs +0 -0
  160. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/post_processor/json.rs +0 -0
  161. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/post_processor/mod.rs +0 -0
  162. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/reader/test_utils.rs +0 -0
  163. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/result/mod.rs +0 -0
  164. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/handle.rs +0 -0
  165. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/params.rs +0 -0
  166. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/params_codec.rs +0 -0
  167. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/statement/validity.rs +0 -0
  168. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/telemetry/mod.rs +0 -0
  169. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/types/cloudfetch.rs +0 -0
  170. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/types/mod.rs +0 -0
  171. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/util/mod.rs +0 -0
  172. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/src/util/runtime.rs +0 -0
  173. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/oauth_u2m_integration.rs +0 -0
  174. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_async_execute_e2e.rs +0 -0
  175. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_execute_wiremock.rs +0 -0
  176. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_session_e2e.rs +0 -0
  177. {databricks_sql_kernel-0.1.2 → databricks_sql_kernel-0.2.0}/tests/v0_session_wiremock.rs +0 -0
  178. {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)."
@@ -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.
@@ -382,7 +382,7 @@ dependencies = [
382
382
 
383
383
  [[package]]
384
384
  name = "databricks-sql-kernel"
385
- version = "0.1.2"
385
+ version = "0.2.0"
386
386
  dependencies = [
387
387
  "arrow-array",
388
388
  "arrow-buffer",
@@ -14,7 +14,7 @@
14
14
 
15
15
  [package]
16
16
  name = "databricks-sql-kernel"
17
- version = "0.1.2"
17
+ version = "0.2.0"
18
18
  edition = "2021"
19
19
  authors = ["Databricks"]
20
20
  license = "Apache-2.0"
@@ -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.*
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databricks-sql-kernel
3
- Version: 0.1.2
3
+ Version: 0.2.0
4
4
  Requires-Dist: pyarrow>=23.0.1,<24
5
5
  Summary: Python bindings for the Databricks SQL Kernel (PyO3)
6
6
  Author: Databricks
@@ -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' for matching we'll match with or without it.
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.1.2"
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.1.2"
415
+ version = "0.2.0"
416
416
  dependencies = [
417
417
  "arrow-array",
418
418
  "arrow-pyarrow",
@@ -31,7 +31,7 @@
31
31
 
32
32
  [package]
33
33
  name = "databricks-sql-kernel-pyo3"
34
- version = "0.1.2"
34
+ version = "0.2.0"
35
35
  edition = "2021"
36
36
  authors = ["Databricks"]
37
37
  license = "Apache-2.0"
@@ -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
- // Default the U2M OAuth client to the Python connector's
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: oauth.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 u2m_defaults_client_id_to_python_connector() {
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
- assert!(scopes.is_none());
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 { client_id, .. } => {
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<()> {