arrowsql 0.1.0__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 (488) hide show
  1. arrowsql-0.2.0/AGENTS.md +27 -0
  2. {arrowsql-0.1.0 → arrowsql-0.2.0}/CHANGELOG.md +40 -3
  3. {arrowsql-0.1.0 → arrowsql-0.2.0}/Cargo.lock +2 -1
  4. {arrowsql-0.1.0 → arrowsql-0.2.0}/Cargo.toml +4 -1
  5. {arrowsql-0.1.0 → arrowsql-0.2.0}/PKG-INFO +1 -1
  6. arrowsql-0.2.0/build.rs +3 -0
  7. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/AGENT_MODE.md +14 -0
  8. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PACKAGING.md +5 -4
  9. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ROADMAP.md +2 -2
  10. {arrowsql-0.1.0 → arrowsql-0.2.0}/pyproject.toml +3 -2
  11. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/_rust_auth.py +23 -8
  12. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/aio.py +20 -7
  13. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/arrow_parallel.py +11 -4
  14. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/auth.py +37 -1
  15. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/bulk_parallel.py +41 -49
  16. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/connection.py +18 -13
  17. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/connection_string_parser.py +33 -5
  18. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/cursor.py +44 -7
  19. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/ddbc_bindings.pyi +13 -0
  20. arrowsql-0.2.0/python/arrowsql/exceptions.py +214 -0
  21. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/helpers.py +13 -0
  22. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/logging.py +8 -8
  23. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/parameter_helper.py +4 -12
  24. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/row.py +23 -208
  25. {arrowsql-0.1.0 → arrowsql-0.2.0}/requirements-dev.txt +1 -0
  26. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/check_upstream_baseline.py +12 -2
  27. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/run_tests.py +18 -1
  28. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/mod.rs +2 -1
  29. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/connection.rs +60 -20
  30. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/convert.rs +49 -66
  31. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/hub.rs +2 -23
  32. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/pool.rs +25 -3
  33. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/session.rs +149 -53
  34. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/sink.rs +13 -15
  35. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/arrow_encode.rs +4 -2
  36. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/mod.rs +2 -0
  37. arrowsql-0.2.0/src/bulk/parallel.rs +193 -0
  38. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/rows.rs +7 -17
  39. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/settings.rs +10 -0
  40. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/wire.rs +1 -15
  41. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/connection.rs +28 -11
  42. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/buffer.rs +39 -0
  43. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/python.rs +1 -1
  44. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/temporal.rs +27 -0
  45. arrowsql-0.2.0/src/errors.rs +316 -0
  46. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/getinfo.rs +7 -12
  47. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/lib.rs +7 -0
  48. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/logging.rs +12 -0
  49. arrowsql-0.2.0/src/numeric.rs +40 -0
  50. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/batch.rs +18 -9
  51. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/mod.rs +6 -0
  52. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/py_types.rs +54 -102
  53. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/pooling.rs +2 -2
  54. arrowsql-0.2.0/src/rowfactory.rs +368 -0
  55. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/runtime.rs +34 -12
  56. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/batch_rpc.rs +1 -8
  57. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/cancel.rs +3 -1
  58. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/cursor.rs +1 -0
  59. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/exec.rs +3 -1
  60. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/mod.rs +2 -1
  61. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/odbc.rs +24 -5
  62. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/wire.rs +17 -2
  63. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/conftest.py +8 -1
  64. arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/MAPPING.md +87 -0
  65. arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/test_bulk_timeout_udt.py +67 -0
  66. arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/test_bulk_types_and_errors.py +233 -0
  67. arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/test_session_and_rpc.py +402 -0
  68. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_connection_strings.py +3 -1
  69. arrowsql-0.2.0/tests/common_issues/test_review_python_security.py +92 -0
  70. arrowsql-0.2.0/tests/common_issues/test_review_security_parser.py +27 -0
  71. arrowsql-0.2.0/tests/common_issues/test_review_security_scripts.py +80 -0
  72. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_row_access.py +29 -0
  73. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_aio.py +10 -1
  74. arrowsql-0.2.0/tests/common_issues/test_rs_aio_review.py +287 -0
  75. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_auth_keywords.py +74 -2
  76. arrowsql-0.2.0/tests/common_issues/test_rs_bulk_parallel_native.py +191 -0
  77. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_parallel_rows.py +9 -0
  78. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_core_regressions.py +2 -2
  79. arrowsql-0.2.0/tests/common_issues/test_rs_review_rust.py +158 -0
  80. arrowsql-0.2.0/tests/mock/conftest.py +234 -0
  81. arrowsql-0.2.0/tests/mock/mockutil.py +6 -0
  82. arrowsql-0.2.0/tests/mock/test_aio_null_discovery.py +47 -0
  83. arrowsql-0.2.0/tests/mock/test_faults.py +285 -0
  84. arrowsql-0.2.0/tests/mock/test_login_tls.py +208 -0
  85. arrowsql-0.2.0/tests/mock/test_results.py +157 -0
  86. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/VENDOR.md +10 -3
  87. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/tds_client.rs +20 -0
  88. arrowsql-0.1.0/python/arrowsql/exceptions.py +0 -378
  89. arrowsql-0.1.0/src/rowfactory.rs +0 -70
  90. {arrowsql-0.1.0 → arrowsql-0.2.0}/.cargo/config.toml +0 -0
  91. {arrowsql-0.1.0 → arrowsql-0.2.0}/.gitattributes +0 -0
  92. {arrowsql-0.1.0 → arrowsql-0.2.0}/.gitignore +0 -0
  93. {arrowsql-0.1.0 → arrowsql-0.2.0}/CONTRIBUTING.md +0 -0
  94. {arrowsql-0.1.0 → arrowsql-0.2.0}/LICENSE +0 -0
  95. {arrowsql-0.1.0 → arrowsql-0.2.0}/LICENSE.upstream-mssql-python +0 -0
  96. {arrowsql-0.1.0 → arrowsql-0.2.0}/README.md +0 -0
  97. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ARCHITECTURE.md +0 -0
  98. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ARROW_ODBC_RESEARCH.md +0 -0
  99. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ARROW_PLAN.md +0 -0
  100. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ASYNC.md +0 -0
  101. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/BENCHMARK_SUMMARY.md +0 -0
  102. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/CONTRACT.md +0 -0
  103. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/EXPORT_RESEARCH.md +0 -0
  104. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/FEATURES.md +0 -0
  105. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/FREE_THREADED.md +0 -0
  106. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PERFORMANCE_RESEARCH.md +0 -0
  107. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PLATFORMS_AND_CONNECTION.md +0 -0
  108. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PYTHON_LAYER_CHANGES.md +0 -0
  109. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/TEST_SCOPE.md +0 -0
  110. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/UPSTREAM_BUGS_FOUND.md +0 -0
  111. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/UPSTREAM_ISSUES.md +0 -0
  112. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/icon.svg +0 -0
  113. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo-dark-static.svg +0 -0
  114. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo-dark.svg +0 -0
  115. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo-static.svg +0 -0
  116. {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo.svg +0 -0
  117. {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/README.md +0 -0
  118. {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/_demo.py +0 -0
  119. {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/agent_mode.py +0 -0
  120. {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/arrow_duckdb.py +0 -0
  121. {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/odbc2deltalake_sync.py +0 -0
  122. {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/write_arrow.py +0 -0
  123. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/__init__.py +0 -0
  124. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/_server_sqlstate.py +0 -0
  125. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/_utf8_strings.py +0 -0
  126. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/agent.py +0 -0
  127. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/__init__.py +0 -0
  128. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/_connection_context.py +0 -0
  129. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/_native.py +0 -0
  130. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_connection.py +0 -0
  131. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_cursor.py +0 -0
  132. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_execute.py +0 -0
  133. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_fetch.py +0 -0
  134. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/exception_translator.py +0 -0
  135. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/connection_string_builder.py +0 -0
  136. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/constants.py +0 -0
  137. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/db_connection.py +0 -0
  138. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/decimal_config.py +0 -0
  139. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/mssql_python.pyi +0 -0
  140. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/odbc_provider.py +0 -0
  141. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/perf_timer.py +0 -0
  142. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/pooling.py +0 -0
  143. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/py.typed +0 -0
  144. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/type.py +0 -0
  145. {arrowsql-0.1.0 → arrowsql-0.2.0}/python/mssql_python/__init__.py +0 -0
  146. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/bench_reproduce.sh +0 -0
  147. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/build.sh +0 -0
  148. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/ci/install-sqlserver-windows.ps1 +0 -0
  149. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/codex_review.sh +0 -0
  150. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/env.sh +0 -0
  151. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/load_taxi.py +0 -0
  152. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/overlay_upstream_binding.sh +0 -0
  153. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/release_rustflags.sh +0 -0
  154. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/setup_tls_cert.sh +0 -0
  155. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/test_overlay.sh +0 -0
  156. {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/wheel_size.sh +0 -0
  157. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/fmt.rs +0 -0
  158. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/render.rs +0 -0
  159. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/sqltype.rs +0 -0
  160. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/mod.rs +0 -0
  161. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/export.rs +0 -0
  162. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/mod.rs +0 -0
  163. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/plan.rs +0 -0
  164. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/arrow_source.rs +0 -0
  165. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/arrow_wire.rs +0 -0
  166. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/catalog.rs +0 -0
  167. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/connstr.rs +0 -0
  168. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/consts.rs +0 -0
  169. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/binary.rs +0 -0
  170. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/describe.rs +0 -0
  171. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/hidden.rs +0 -0
  172. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/mod.rs +0 -0
  173. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/numeric.rs +0 -0
  174. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/text.rs +0 -0
  175. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/diag.rs +0 -0
  176. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/null_types.rs +0 -0
  177. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/placeholders.rs +0 -0
  178. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/pyformat.rs +0 -0
  179. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/udt.rs +0 -0
  180. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/types.rs +0 -0
  181. {arrowsql-0.1.0 → arrowsql-0.2.0}/src/utf8_wrap.rs +0 -0
  182. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_ctds.txt +0 -0
  183. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_dotnet_sqlclient.txt +0 -0
  184. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_go_mssqldb.txt +0 -0
  185. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_sqlalchemy.txt +0 -0
  186. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/README.md +0 -0
  187. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_ctds_cursor_fetch.py +0 -0
  188. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_ctds_executemany.py +0 -0
  189. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_ctds_transactions.py +0 -0
  190. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_fastmssql_async_threads.py +0 -0
  191. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_fastmssql_errors_values.py +0 -0
  192. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_fastmssql_lifecycle_pool.py +0 -0
  193. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_go_mssqldb_bulkcopy.py +0 -0
  194. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_go_mssqldb_xact_guid.py +0 -0
  195. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_jdbc_bigint_guid.py +0 -0
  196. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_jdbc_temporal_params.py +0 -0
  197. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_rs_arrow_bulkcopy.py +0 -0
  198. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_rs_bulkcopy.py +0 -0
  199. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pymssql_bulkcopy_paths.py +0 -0
  200. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pymssql_qmark_substitution.py +0 -0
  201. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pymssql_types_procs.py +0 -0
  202. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pyodbc_connection.py +0 -0
  203. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pyodbc_cursor_results.py +0 -0
  204. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pyodbc_types.py +0 -0
  205. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_rust_mssql_driver_bulkcopy.py +0 -0
  206. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_rust_mssql_driver_param_echo.py +0 -0
  207. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_catalog.py +0 -0
  208. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_identity_sequence.py +0 -0
  209. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_query.py +0 -0
  210. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_types.py +0 -0
  211. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlclient_bulkcopy.py +0 -0
  212. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlclient_scalar_commands.py +0 -0
  213. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tedious_protocol.py +0 -0
  214. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tedious_statements.py +0 -0
  215. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_bulk.py +0 -0
  216. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_login_password.py +0 -0
  217. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_query_types.py +0 -0
  218. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_results_transactions.py +0 -0
  219. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/rs_dtypes.py +0 -0
  220. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_binary_guid.py +0 -0
  221. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_dead_connection.py +0 -0
  222. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_decimal_numeric.py +0 -0
  223. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_executemany.py +0 -0
  224. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_g1_pyformat_scanner.py +0 -0
  225. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_integers_bool_float.py +0 -0
  226. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_issue_581_sqlstate.py +0 -0
  227. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_large_values.py +0 -0
  228. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_messages_errors.py +0 -0
  229. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_multiple_results.py +0 -0
  230. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_nulls_typing.py +0 -0
  231. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_agent_mode.py +0 -0
  232. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_aio_pool_semantics.py +0 -0
  233. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_aio.py +0 -0
  234. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_exotic.py +0 -0
  235. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_paths.py +0 -0
  236. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_special.py +0 -0
  237. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arith_errors.py +0 -0
  238. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arrow_native.py +0 -0
  239. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arrow_stream_close.py +0 -0
  240. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arrow_type_mapping.py +0 -0
  241. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_batch_parsing.py +0 -0
  242. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bigint_overflow_agg.py +0 -0
  243. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_decimal_width.py +0 -0
  244. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_native.py +0 -0
  245. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_native_rows.py +0 -0
  246. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_parallel.py +0 -0
  247. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_rows_pipeline.py +0 -0
  248. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_serializer_chunks.py +0 -0
  249. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_cancel.py +0 -0
  250. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_char_padding.py +0 -0
  251. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_client_cpu_paths.py +0 -0
  252. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_collation_case.py +0 -0
  253. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_cte_recursion.py +0 -0
  254. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_database_context.py +0 -0
  255. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_date_strings_dateformat.py +0 -0
  256. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_datetimeoffset_deep.py +0 -0
  257. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_decimal_param_inference.py +0 -0
  258. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_decode_fastpaths.py +0 -0
  259. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_defaults_computed.py +0 -0
  260. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_description_types.py +0 -0
  261. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_duckdb_integration.py +0 -0
  262. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_error_mid_resultset.py +0 -0
  263. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_executemany_types.py +0 -0
  264. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_fetch_sizes_arraysize.py +0 -0
  265. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_float_real_edges.py +0 -0
  266. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_for_json.py +0 -0
  267. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_g3_decode_encode.py +0 -0
  268. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_hidden_columns.py +0 -0
  269. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_hierarchyid.py +0 -0
  270. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_identifiers_quoting.py +0 -0
  271. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_identity_triggers.py +0 -0
  272. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_isolation_levels.py +0 -0
  273. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_leaks_lifecycle.py +0 -0
  274. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_legacy_datetime_rounding.py +0 -0
  275. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_legacy_lob_types.py +0 -0
  276. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_locking_blocking.py +0 -0
  277. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_merge_output.py +0 -0
  278. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_message_flood.py +0 -0
  279. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_metadata_reuse.py +0 -0
  280. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_money_arithmetic.py +0 -0
  281. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_null_semantics.py +0 -0
  282. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_output_clause.py +0 -0
  283. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_pandas_polars_io.py +0 -0
  284. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_binding_fastpaths.py +0 -0
  285. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_fast_cells.py +0 -0
  286. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_type_plancache.py +0 -0
  287. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_wire_paths.py +0 -0
  288. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_pyformat_named.py +0 -0
  289. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_read_arrow_partitions.py +0 -0
  290. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_read_arrow_stream.py +0 -0
  291. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_rowversion_concurrency.py +0 -0
  292. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_savepoints_nested.py +0 -0
  293. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_session_set_options.py +0 -0
  294. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_setinputsizes.py +0 -0
  295. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_sparse_columnsets.py +0 -0
  296. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_spatial_deep.py +0 -0
  297. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_sql_variant_deep.py +0 -0
  298. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_string_truncation.py +0 -0
  299. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_temporal_tables.py +0 -0
  300. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_time7_precision.py +0 -0
  301. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_time_scales.py +0 -0
  302. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_triggers_rowcount.py +0 -0
  303. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_tvp_support.py +0 -0
  304. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_uniqueidentifier_order.py +0 -0
  305. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_utf8_collations.py +0 -0
  306. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_utf8_strings.py +0 -0
  307. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_varchar_codepages.py +0 -0
  308. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_xml_deep.py +0 -0
  309. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_scope_identity_temp.py +0 -0
  310. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_special_types.py +0 -0
  311. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_stored_procs.py +0 -0
  312. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_temporal.py +0 -0
  313. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_threading_gil.py +0 -0
  314. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_timeouts_cancel.py +0 -0
  315. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_transactions.py +0 -0
  316. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_unicode.py +0 -0
  317. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_wide_and_many.py +0 -0
  318. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/port/test_free_threaded.py +0 -0
  319. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/port/test_runtime_fork.py +0 -0
  320. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/port/test_tls.py +0 -0
  321. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/upstream_excluded.txt +0 -0
  322. {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/upstream_passing_baseline.txt +0 -0
  323. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/.env +0 -0
  324. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/Cargo.toml +0 -0
  325. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/LICENSE +0 -0
  326. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/README.md +0 -0
  327. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cli.rs +0 -0
  328. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/blocking.rs +0 -0
  329. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/bulk_copy.rs +0 -0
  330. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/bulk_copy_state.rs +0 -0
  331. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/client_context.rs +0 -0
  332. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/connect_stage.rs +0 -0
  333. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/connection_actions.rs +0 -0
  334. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/cursor_ops.rs +0 -0
  335. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/datasource_parser.rs +0 -0
  336. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/dns_cache.rs +0 -0
  337. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/execution_context.rs +0 -0
  338. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/instance_cache.rs +0 -0
  339. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/metadata_retriever.rs +0 -0
  340. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/multi_subnet_failover.rs +0 -0
  341. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/session_recovery.rs +0 -0
  342. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/any_transport.rs +0 -0
  343. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/buffers.rs +0 -0
  344. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/busy_poll.rs +0 -0
  345. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/certificate_validator.rs +0 -0
  346. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/extractable_stream.rs +0 -0
  347. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/localdb.rs +0 -0
  348. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/named_pipes.rs +0 -0
  349. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/network_transport.rs +0 -0
  350. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/parallel_connect.rs +0 -0
  351. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/ssl_handler.rs +0 -0
  352. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tds_transport.rs +0 -0
  353. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tls/native_tls_engine.rs +0 -0
  354. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tls/rustls_engine.rs +0 -0
  355. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tls.rs +0 -0
  356. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/alpn.rs +0 -0
  357. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/bindings.rs +0 -0
  358. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/cred.rs +0 -0
  359. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/engine.rs +0 -0
  360. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/errors.rs +0 -0
  361. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/handshake.rs +0 -0
  362. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/mod.rs +0 -0
  363. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/record_layer.rs +0 -0
  364. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/sspi.rs +0 -0
  365. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/stream.rs +0 -0
  366. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/validate.rs +0 -0
  367. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport.rs +0 -0
  368. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection.rs +0 -0
  369. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection_provider/tds_connection_provider.rs +0 -0
  370. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection_provider.rs +0 -0
  371. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/core.rs +0 -0
  372. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cursor/cursor_response.rs +0 -0
  373. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cursor/cursor_types.rs +0 -0
  374. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cursor/mod.rs +0 -0
  375. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/bulk_copy_metadata.rs +0 -0
  376. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/bulk_copy_metadata_tests.rs +0 -0
  377. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/column_values.rs +0 -0
  378. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/decoder.rs +0 -0
  379. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/encoder.rs +0 -0
  380. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/lcid_encoding.rs +0 -0
  381. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/row_writer.rs +0 -0
  382. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_json.rs +0 -0
  383. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_string/encoding.rs +0 -0
  384. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_string.rs +0 -0
  385. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_tvp.rs +0 -0
  386. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_udt.rs +0 -0
  387. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_vector.rs +0 -0
  388. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sqldatatypes.rs +0 -0
  389. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sqltypes.rs +0 -0
  390. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sync_decoder.rs +0 -0
  391. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/tds_value_serializer.rs +0 -0
  392. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes.rs +0 -0
  393. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/error/bulk_copy_errors.rs +0 -0
  394. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/error/mod.rs +0 -0
  395. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/fuzz_support.rs +0 -0
  396. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/handler/handler_factory.rs +0 -0
  397. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/handler/sspi_handler.rs +0 -0
  398. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/handler.rs +0 -0
  399. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/packet_reader.rs +0 -0
  400. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/packet_writer.rs +0 -0
  401. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/reader_writer.rs +0 -0
  402. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/token_stream.rs +0 -0
  403. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io.rs +0 -0
  404. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/lib.rs +0 -0
  405. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/attention.rs +0 -0
  406. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/batch.rs +0 -0
  407. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/bulk_load.rs +0 -0
  408. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/bulk_load_tests.rs +0 -0
  409. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/always_encrypted.rs +0 -0
  410. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/data_classification.rs +0 -0
  411. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/dns_caching.rs +0 -0
  412. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/enhanced_routing.rs +0 -0
  413. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/fedauth.rs +0 -0
  414. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/jsonfeature.rs +0 -0
  415. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/session_recovery.rs +0 -0
  416. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/useragent.rs +0 -0
  417. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/utf8.rs +0 -0
  418. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/vectorfeature.rs +0 -0
  419. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features.rs +0 -0
  420. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/headers.rs +0 -0
  421. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/login.rs +0 -0
  422. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/login_options.rs +0 -0
  423. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/messages.rs +0 -0
  424. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/parameters/rpc_parameters.rs +0 -0
  425. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/parameters.rs +0 -0
  426. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/prelogin.rs +0 -0
  427. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/rpc.rs +0 -0
  428. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/transaction_management.rs +0 -0
  429. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message.rs +0 -0
  430. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/query/metadata.rs +0 -0
  431. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/query/result.rs +0 -0
  432. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/query.rs +0 -0
  433. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/cell_decryptor.rs +0 -0
  434. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/apple.rs +0 -0
  435. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/cng.rs +0 -0
  436. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/der.rs +0 -0
  437. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/mod.rs +0 -0
  438. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/openssl.rs +0 -0
  439. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/unsupported.rs +0 -0
  440. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/describe_parameter_encryption.rs +0 -0
  441. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/encryption/aead_aes_256_cbc_hmac_sha256.rs +0 -0
  442. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/encryption/cell.rs +0 -0
  443. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/encryption/mod.rs +0 -0
  444. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/error.rs +0 -0
  445. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/keystore/certificate.rs +0 -0
  446. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/keystore/mod.rs +0 -0
  447. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/mock.rs +0 -0
  448. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/mod.rs +0 -0
  449. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/query_metadata_cache.rs +0 -0
  450. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/security_context.rs +0 -0
  451. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/spn.rs +0 -0
  452. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/unix/gssapi_context.rs +0 -0
  453. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/unix/gssapi_ffi.rs +0 -0
  454. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/unix/mod.rs +0 -0
  455. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/windows/mod.rs +0 -0
  456. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/windows/sspi_context.rs +0 -0
  457. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/windows/sspi_ffi.rs +0 -0
  458. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/sql_identifier.rs +0 -0
  459. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/ssrp.rs +0 -0
  460. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/test_client_support.rs +0 -0
  461. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/test_packet_support.rs +0 -0
  462. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/data_classification.rs +0 -0
  463. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/fed_auth_info.rs +0 -0
  464. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/login_ack.rs +0 -0
  465. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/col_info_parser.rs +0 -0
  466. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/colmetadata_parser.rs +0 -0
  467. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/common.rs +0 -0
  468. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/data_classification_parser.rs +0 -0
  469. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/done_parser.rs +0 -0
  470. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/envchange_parser.rs +0 -0
  471. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/error_parser.rs +0 -0
  472. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/featureext_parser.rs +0 -0
  473. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/fedauth_parser.rs +0 -0
  474. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/info_parser.rs +0 -0
  475. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/loginack_parser.rs +0 -0
  476. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/mod.rs +0 -0
  477. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/nbcrow_parser.rs +0 -0
  478. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/order_parser.rs +0 -0
  479. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/returnstatus_parser.rs +0 -0
  480. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/returnvalue_parser.rs +0 -0
  481. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/row_parser.rs +0 -0
  482. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/session_state_parser.rs +0 -0
  483. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/sspi_parser.rs +0 -0
  484. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/tab_name_parser.rs +0 -0
  485. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/tokenitems.rs +0 -0
  486. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/tokens.rs +0 -0
  487. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token.rs +0 -0
  488. {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/trace_context.rs +0 -0
@@ -0,0 +1,27 @@
1
+ # Rules for agents working in this repository
2
+
3
+ 1. **Version trio.** Three different numbers: `pyproject.toml` `version` and `Cargo.toml`
4
+ `version` are the distribution release and must be bumped together (plus a CHANGELOG
5
+ entry). `arrowsql.__version__` (`python/arrowsql/__init__.py`) deliberately reports the
6
+ upstream `mssql-python` release the Python layer is vendored from (currently 1.16.0);
7
+ do not bump it for a release of this project. `ddbc_bindings.__version__` is the Rust
8
+ binding contract version (`docs/CONTRACT.md`).
9
+ 2. **Vendor patches.** Every change to vendored Python (upstream-derived files) is marked
10
+ `RUST-PORT` in the code and listed in `docs/PYTHON_LAYER_CHANGES.md`. Every change to
11
+ `vendor/mssql-tds` gets an entry in `vendor/mssql-tds/VENDOR.md`.
12
+ 3. **Upstream baseline gate.** `tests/upstream_passing_baseline.txt` lists upstream tests
13
+ that must keep passing. Run `scripts/check_upstream_baseline.py` (or the baseline
14
+ snippet from the PR template) before pushing; 0 baseline tests may be missing and
15
+ teardown ERRORs count as failures. Never edit the baseline or `upstream_excluded.txt`
16
+ to hide a regression.
17
+ 4. **Stay in Rust.** Put new behaviour in the Rust core (`src/`) and keep the Python layer
18
+ thin. Python is for the DB-API surface, argument validation and glue.
19
+ 5. **Tests.** Each fix gets a regression test in `tests/common_issues` (or `tests/port`,
20
+ `tests/mock`). Run tests with `python scripts/run_tests.py <id> <paths>`, which uses a
21
+ private database per id. Full suites run in CI.
22
+ 6. **Secrets.** Never print, cat or commit `.env.local` or the SA password; connection
23
+ strings in logs and error messages must not contain values. Check
24
+ `git log -p origin/main..HEAD` for the password before every push.
25
+ 7. **Git.** Never push to `main`; work on a branch and open a PR. Do not restart
26
+ containers or touch other sessions' processes. Use `nice -n 19` for builds and tests
27
+ while benchmarks run.
@@ -8,12 +8,46 @@ Version numbers in this project are deliberately three different things:
8
8
 
9
9
  | what | value | meaning |
10
10
  |---|---|---|
11
- | distribution `arrowsql` | 0.1.0 | this project's release number (`pyproject.toml`) |
11
+ | distribution `arrowsql` | 0.2.0 | this project's release number (`pyproject.toml`) |
12
12
  | `arrowsql.__version__` | 1.16.0 | the upstream `mssql-python` release the Python layer is vendored from; kept so code that checks the upstream version keeps working |
13
13
  | `arrowsql.ddbc_bindings.__version__` | 1.0.0 | version of the Rust binding contract (`docs/CONTRACT.md`) |
14
14
 
15
15
  ## [Unreleased]
16
16
 
17
+ ## [0.2.0] - 2026-11-01
18
+
19
+ ### Added
20
+
21
+ - `write_arrow()` no longer needs pyarrow: any Arrow PyCapsule source (`__arrow_c_stream__` /
22
+ `__arrow_c_array__`: polars, DuckDB, nanoarrow, pyarrow) is loaded by the parallel bulk copy
23
+ in Rust (`DDBCBulkCopyArrowParallel`).
24
+ - DB-API exceptions are raised from Rust: the SQLSTATE-to-class table, the 1222 / 2628 / 8114
25
+ promotions and the `driver_error` / `ddbc_error` / `sqlstate` / `native_error` attributes are
26
+ built natively (`DDBCRaiseFor`). The native `Connection` and `getinfo` raise typed exceptions.
27
+ - `Row` is backed by a Rust core (`RowCore`): indexing, attribute access, copy and pickle run
28
+ natively.
29
+
30
+ ### Changed
31
+
32
+ - Faster LOB row fetch: large pure-ASCII values are narrowed when they are pushed, and the row
33
+ arena is sized once (fetchmany over LOB columns about 2.5x faster).
34
+
35
+ ### Fixed
36
+
37
+ - Arrow reads decoded OEM 437/850 `varchar` lossily; every fetch path now decodes it the same.
38
+ - A forked child closing an inherited connection no longer shuts down the parent's session.
39
+ - `round_to_scale` / money rounding: exponent text is rounded, ties round half away from zero on
40
+ every path, independent of the ambient decimal context.
41
+ - Row bulk copy without column mappings rejects extra source columns instead of dropping them;
42
+ ragged `executemany` rows raise a DB-API error instead of a panic.
43
+ - Closing a partly read result no longer blocks on a locked row.
44
+ - asyncio: `fetch_arrow` raises the drained error, cancellation and pool races, drain budget and
45
+ stale cursor state after errors.
46
+ - Request timeout accounting and cancel-handle publish order in the vendored `mssql-tds`.
47
+ - Security and CI hardening: release publishing only from `main`, actions pinned to SHAs.
48
+
49
+ ## [0.1.0] - 2026-11-01
50
+
17
51
  ### Added
18
52
 
19
53
  - UTF-8 transfer for Arrow reads: `read_arrow(..., utf8_strings=True)` and the new
@@ -79,5 +113,8 @@ Version numbers in this project are deliberately three different things:
79
113
  - Pool checkout does not probe an idle connection with a timeout (upstream
80
114
  GH #854), and `set_attr(SQL_ATTR_CONNECTION_TIMEOUT)` is not carried across
81
115
  pool reuse. See `tests/upstream_excluded.txt`.
82
- - Always Encrypted, `ActiveDirectoryPassword` and NTLM are not supported.
83
- - Only Linux x86_64 has been exercised against a database.
116
+ - Always Encrypted and NTLM are not supported.
117
+ - Linux x86_64 is the platform exercised daily against a database. CI also builds and runs
118
+ the DB-free tests on macOS, Windows (x64, arm64) and Linux arm64, and runs the DB suite
119
+ against SQL Server Express on `windows-latest` (the `windows-db` job; Windows is not a
120
+ required gate).
@@ -274,7 +274,7 @@ checksum = "4583a4551df46e2792f82ceeac45e850d2e2d5debba0b91f102385cda5b11f06"
274
274
 
275
275
  [[package]]
276
276
  name = "ddbc_bindings"
277
- version = "0.1.0"
277
+ version = "0.2.0"
278
278
  dependencies = [
279
279
  "arrow-array",
280
280
  "arrow-buffer",
@@ -285,6 +285,7 @@ dependencies = [
285
285
  "mssql-tds",
286
286
  "parking_lot",
287
287
  "pyo3",
288
+ "pyo3-build-config",
288
289
  "tokio",
289
290
  "uuid",
290
291
  ]
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "ddbc_bindings"
3
- version = "0.1.0"
3
+ version = "0.2.0"
4
4
  edition = "2024"
5
5
  license = "MIT"
6
6
  description = "Rust (PyO3 + mssql-tds) replacement for mssql-python's ODBC-based ddbc_bindings"
@@ -45,6 +45,9 @@ mssql-tds = { git = "https://github.com/microsoft/mssql-rs", rev = "6b6b48ecbbbd
45
45
  [target.'cfg(target_env = "musl")'.dependencies]
46
46
  mimalloc = { version = "0.1", default-features = false, features = ["local_dynamic_tls"] }
47
47
 
48
+ [build-dependencies]
49
+ pyo3-build-config = "0.29.0"
50
+
48
51
  [profile.dev]
49
52
  opt-level = 1
50
53
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: arrowsql
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Classifier: Development Status :: 3 - Alpha
5
5
  Classifier: Intended Audience :: Developers
6
6
  Classifier: Operating System :: POSIX :: Linux
@@ -0,0 +1,3 @@
1
+ fn main() {
2
+ pyo3_build_config::use_pyo3_cfgs();
3
+ }
@@ -50,3 +50,17 @@ text = query(conn_or_connection_string, "SELECT TOP 100 * FROM dbo.orders WHERE
50
50
  a partial result with a success footer. Bad arguments exit 2, Ctrl-C exits 130.
51
51
  - `query_cursor(cursor, sql)` runs on an existing cursor; `render_cursor(cursor)`
52
52
  renders one that has just executed. String connections use autocommit.
53
+
54
+ ## Credentials and least privilege
55
+
56
+ - The CLI accepts a full connection string with `--connection-string` / `--conn`.
57
+ Anything on the command line is visible to other local users (`ps`, `/proc`) and ends up
58
+ in shell history and agent transcripts, so do **not** put the password there. Pass it
59
+ through the environment instead: `MSSQL_CONNECTION_STRING` or `DB_CONNECTION_STRING`
60
+ (read when `--connection-string` is absent), set from a secret store or an untracked
61
+ `.env` file the agent never prints.
62
+ - Give the agent its own SQL login or Entra principal with the least privilege that the
63
+ task needs, ideally read-only (`db_datareader`, `VIEW DEFINITION`) on one database. The
64
+ tool runs the SQL it is given unchanged and does not make an unsafe statement safe.
65
+ - Prefer `Authentication=ActiveDirectoryServicePrincipal`-style or token credentials with
66
+ short lifetimes over long-lived `sa` passwords; never use `sa`.
@@ -9,7 +9,7 @@ brings only the compiled `ddbc_bindings` extension and the vendored
9
9
  | (none) | nothing | `connect()`, the DB-API cursor/row path, `aio`, `read_arrow` on the native Arrow stream |
10
10
  | `arrow` | `pyarrow>=14` | `cursor.arrow()`, `arrow_batch()`, `arrow_reader()` (upstream API surface) |
11
11
  | `azure` | `azure-identity` | `auth=` / `token_provider=` with azure-identity credentials |
12
- | `async-preview` | `mssql-python-rs==0.4.0` (Microsoft `mssql_py_core`, ~30 MB) | `bulkcopy()`, `bulkcopy_arrow()`, upstream `async_query` preview |
12
+ | `async-preview` | `mssql-python-rs==0.4.0` (Microsoft `mssql_py_core`, ~30 MB) | upstream `async_query` preview; fallback for `bulkcopy()` / `bulkcopy_arrow()` only on cursors without a native handle (bulk copy itself runs in the Rust core) |
13
13
 
14
14
  ## Wheels, sdist and versions
15
15
 
@@ -66,9 +66,10 @@ stack. Every optional import is lazy:
66
66
  Arrow fetch/insert methods (`TYPE_CHECKING` guard at module top).
67
67
  * `auth.py`, `db_connection.py`: `azure.identity` / `azure.core` are imported
68
68
  inside the functions that build those credentials.
69
- * `cursor.py` bulkcopy: `mssql_py_core` is imported in
70
- `_bulkcopy_import_core()`. A missing package raises an `ImportError`
71
- that names the `async-preview` extra.
69
+ * `cursor.py` bulkcopy: bulk copy runs natively (`DDBCBulkCopyRows` /
70
+ `DDBCBulkCopyArrow`); `mssql_py_core` is imported in
71
+ `_bulkcopy_import_core()` only for cursors without a native handle. A
72
+ missing package raises an `ImportError` that names the `async-preview` extra.
72
73
  * `odbc_provider.py`: the provider package (`mssql_python_odbc` / `mssql_py_core`)
73
74
  is imported only when the upstream ODBC provider is selected. The Rust
74
75
  port path (`ddbc_bindings.__rust_port__`) skips that import.
@@ -9,11 +9,11 @@ compatibility.
9
9
  | | upstream mssql-python 1.16 | this project today | target |
10
10
  |---|---:|---:|---:|
11
11
  | driver | 9.4 MB (`mssql_python`) | 4.7 MB extension + 0.6 MB Python | ~2-3 MB |
12
- | `mssql_py_core` (Rust TDS, via `mssql-python-rs`) | 30 MB | 30 MB (bulkcopy, async preview) | 0 (optional extra) |
12
+ | `mssql_py_core` (Rust TDS, via `mssql-python-rs`) | 30 MB | 0 core, 30 MB with the `async-preview` extra (async preview; bulkcopy fallback only) | 0 (optional extra) |
13
13
  | `mssql_python_odbc` (ODBC driver) | 7 MB | 0 | 0 |
14
14
  | required runtime deps | 2 | 1 | **0** |
15
15
 
16
- Plan: own bulk copy in the Rust core (drops `mssql_py_core` for bulkcopy), the
16
+ Done: bulk copy runs in the Rust core (`mssql_py_core` is no longer needed for bulkcopy). Plan: the
17
17
  upstream async preview moves behind an extra, `pyarrow` and `azure-identity`
18
18
  stay optional, one abi3 wheel per platform if the measured cost is nil,
19
19
  stripped release builds.
@@ -4,7 +4,7 @@ build-backend = "maturin"
4
4
 
5
5
  [project]
6
6
  name = "arrowsql"
7
- version = "0.1.0"
7
+ version = "0.2.0"
8
8
  description = "mssql-python with its ODBC/C++ core replaced by Rust (PyO3 + mssql-tds)"
9
9
  requires-python = ">=3.10"
10
10
  readme = "README.md"
@@ -36,7 +36,8 @@ classifiers = [
36
36
  dependencies = []
37
37
 
38
38
  [project.optional-dependencies]
39
- # Upstream async_query preview and bulkcopy() (still served by Microsoft's mssql_py_core).
39
+ # Upstream async_query preview. bulkcopy()/bulkcopy_arrow() run natively; mssql_py_core is
40
+ # only a fallback for cursors without a native handle (the upstream ODBC provider path).
40
41
  async-preview = ["mssql-python-rs==0.4.0"]
41
42
  # Arrow fetch (arrow(), arrow_batch(), read_arrow()) and Arrow bulk insert.
42
43
  arrow = ["pyarrow>=14"]
@@ -13,6 +13,7 @@ through to a SQL login with the client id or UPN. This module keeps auth.py
13
13
 
14
14
  from __future__ import annotations
15
15
 
16
+ import hashlib
16
17
  import sys
17
18
  from typing import Callable, Dict, Optional
18
19
 
@@ -81,25 +82,39 @@ def make_password_token_factory(username: str, password: str) -> Callable[[str,
81
82
  if not username or not password:
82
83
  raise ValueError("ActiveDirectoryPassword auth requires UID (user principal name) and PWD")
83
84
 
85
+ secret_hash = hashlib.sha256(password.encode("utf-8")).hexdigest()
86
+
84
87
  def _factory(spn: str, sts_url: str, _auth_method: str) -> bytes:
85
88
  # pylint: disable=import-outside-toplevel
86
89
  from azure.identity import UsernamePasswordCredential
87
90
  from azure.core.exceptions import ClientAuthenticationError
88
- from arrowsql.auth import _parse_tenant_id
91
+ from azure.core.pipeline.transport import RequestsTransport
92
+ from arrowsql import auth as _auth
89
93
 
90
94
  if not spn:
91
95
  raise RuntimeError("ActiveDirectoryPassword: empty SPN from server")
92
- tenant_id = _parse_tenant_id(sts_url)
96
+ tenant_id = _auth._parse_tenant_id(sts_url)
93
97
  if not tenant_id:
94
98
  raise RuntimeError(f"Could not extract tenant_id from STS URL: {sts_url!r}")
95
- scope = spn if spn.endswith("/.default") else spn.rstrip("/") + "/.default"
99
+ scope = _auth._scope_from_server_spn(spn)
96
100
  try:
97
- credential = UsernamePasswordCredential(
98
- client_id=_PASSWORD_CLIENT_ID,
99
- username=username,
100
- password=password,
101
- tenant_id=tenant_id,
101
+ cache_key = _auth._credential_cache_key(
102
+ _AD_PASSWORD,
103
+ {"tenant_id": tenant_id, "username": username, "secret_hash": secret_hash},
102
104
  )
105
+ with _auth._credential_cache_lock:
106
+ credential = _auth._credential_cache.get(cache_key)
107
+ if credential is None:
108
+ # The factory runs on a blocking-pool worker of the core;
109
+ # bound the Entra round-trip like the service-principal path.
110
+ credential = UsernamePasswordCredential(
111
+ client_id=_PASSWORD_CLIENT_ID,
112
+ username=username,
113
+ password=password,
114
+ tenant_id=tenant_id,
115
+ transport=RequestsTransport(connection_timeout=10, read_timeout=15),
116
+ )
117
+ _auth._credential_cache[cache_key] = credential
103
118
  token = credential.get_token(scope).token
104
119
  except ClientAuthenticationError:
105
120
  # The provider text can echo the account; keep it out of the exception chain.
@@ -122,6 +122,16 @@ class AsyncCursor:
122
122
  def connection(self) -> "AsyncConnection":
123
123
  return self._conn
124
124
 
125
+ def _retire(self) -> None:
126
+ """Forget the current result: no row, description or count survives it."""
127
+ self._batch = None
128
+ self._rows = []
129
+ self._pos = 0
130
+ self._done = True
131
+ self.description = None
132
+ self.rowcount = -1
133
+ self.messages = []
134
+
125
135
  def _install(self, result) -> None:
126
136
  shape, batch, done, rowcount, messages = result
127
137
  self._batch = batch
@@ -135,9 +145,12 @@ class AsyncCursor:
135
145
  def _check(self) -> None:
136
146
  if self._closed:
137
147
  raise _interface_error("Cursor is closed")
148
+ if self._conn._closed:
149
+ raise _interface_error("Connection is closed")
138
150
 
139
151
  async def execute(self, operation: str, *parameters: Any) -> "AsyncCursor":
140
152
  self._check()
153
+ self._retire() # a failed or cancelled execute leaves no stale rows behind
141
154
  params = _params(parameters) if parameters else None
142
155
  result = await _wait(self._c, self._c.execute(_hub(), self._id, operation, params))
143
156
  self._install(result)
@@ -145,10 +158,8 @@ class AsyncCursor:
145
158
 
146
159
  async def executemany(self, operation: str, seq_of_parameters: Sequence[Sequence[Any]]) -> None:
147
160
  self._check()
161
+ self._retire()
148
162
  rows = await _wait(self._c, self._c.executemany(_hub(), self._id, operation, seq_of_parameters))
149
- self._batch = None
150
- self._done = True
151
- self.description = None
152
163
  self.rowcount = rows
153
164
 
154
165
  async def _more(self, n: int) -> list:
@@ -172,6 +183,7 @@ class AsyncCursor:
172
183
  return out
173
184
 
174
185
  async def fetchone(self) -> Optional[Any]:
186
+ self._check()
175
187
  batch = self._batch
176
188
  if batch is not None:
177
189
  row = batch.next()
@@ -189,6 +201,7 @@ class AsyncCursor:
189
201
  return await self.fetchone()
190
202
 
191
203
  async def fetchmany(self, size: Optional[int] = None) -> list:
204
+ self._check()
192
205
  size = self.arraysize if size is None else size
193
206
  out = self._local(size)
194
207
  while len(out) < size and not self._done:
@@ -200,6 +213,7 @@ class AsyncCursor:
200
213
  return out
201
214
 
202
215
  async def fetchall(self) -> list:
216
+ self._check()
203
217
  out = self._local(2**62)
204
218
  while not self._done: # a result that fails after some rows ends with the error
205
219
  more = await self._more(2**62)
@@ -227,9 +241,7 @@ class AsyncCursor:
227
241
  self._check()
228
242
  result = await _wait(self._c, self._c.nextset(_hub(), self._id))
229
243
  if result is None:
230
- self._batch = None
231
- self._done = True
232
- self.description = None
244
+ self._retire()
233
245
  return None
234
246
  self._install(result)
235
247
  return True
@@ -237,7 +249,7 @@ class AsyncCursor:
237
249
  async def close(self) -> None:
238
250
  if not self._closed:
239
251
  self._closed = True
240
- self._batch = None
252
+ self._retire()
241
253
  self._c.close_cursor(self._id)
242
254
 
243
255
  def __del__(self):
@@ -253,6 +265,7 @@ class AsyncCursor:
253
265
  return self
254
266
 
255
267
  async def __anext__(self):
268
+ self._check()
256
269
  batch = self._batch
257
270
  if batch is not None:
258
271
  row = batch.next()
@@ -27,6 +27,7 @@ import weakref
27
27
  from typing import Any, List, Optional, Sequence, Tuple
28
28
 
29
29
  from arrowsql import ddbc_bindings
30
+ from arrowsql.logging import logger
30
31
  from arrowsql.db_connection import connect
31
32
  from arrowsql._utf8_strings import utf8_query
32
33
  from arrowsql.exceptions import raise_exception
@@ -136,7 +137,10 @@ def read_arrow_stream(
136
137
  ``>= bk`` (plus an ``IS NULL`` slice when the column is nullable), each
137
138
  bound as a typed parameter. No MIN/MAX or size probe is run, so the first
138
139
  batch comes sooner, and skew can be handled by passing quantiles. Bounds
139
- must ascend in the column's own ordering (for strings: its collation); a
140
+ must ascend in the column's own ordering (for strings: its collation). Only
141
+ Python code-point order is checked here, not the server collation: a list
142
+ that ascends in Python but not in the collation yields overlapping or empty
143
+ slices (duplicate or missing rows), so order string bounds by the collation; a
140
144
  ``str`` bound is sent as nvarchar, so a ``varchar`` column is compared
141
145
  after an implicit conversion (no index seek). ``partition_nullable`` says
142
146
  whether the column may hold NULL (default: asked from the server, one
@@ -405,13 +409,16 @@ def _probe_meta(cursor, query, column, plain=None, with_rows: bool = True) -> Tu
405
409
  cursor.execute(f"SELECT {_ROWS_SQL}, {_NULLABLE_SQL}", (match.group(1),) + describe)
406
410
  rows, nullable = cursor.fetchone()
407
411
  return (None if rows is None else int(rows)), nullable is None or bool(nullable)
408
- except Exception:
409
- pass
412
+ except Exception as exc: # pylint: disable=broad-exception-caught
413
+ logger.debug("parallel read: catalog probe failed, falling back: %s", type(exc).__name__)
410
414
  try:
411
415
  cursor.execute(f"SELECT {_NULLABLE_SQL}", describe)
412
416
  row = cursor.fetchone()
413
417
  return None, row is None or row[0] is None or bool(row[0])
414
- except Exception:
418
+ except Exception as exc: # pylint: disable=broad-exception-caught
419
+ logger.debug(
420
+ "parallel read: nullability probe failed, assuming nullable: %s", type(exc).__name__
421
+ )
415
422
  return None, True
416
423
 
417
424
 
@@ -81,6 +81,42 @@ class TokenInfo(NamedTuple):
81
81
  # audience is rejected by SQL Server at login.
82
82
  _SQL_SCOPE = "https://database.windows.net/.default"
83
83
 
84
+ # Resource hosts a SQL server may name in FEDAUTHINFO. The SPN comes from the
85
+ # (possibly untrusted) server, so a token is only requested for these audiences;
86
+ # anything else fails closed instead of minting a token for an arbitrary resource.
87
+ _ALLOWED_SQL_RESOURCE_HOSTS = frozenset(
88
+ {
89
+ "database.windows.net",
90
+ "database.chinacloudapi.cn",
91
+ "database.usgovcloudapi.net",
92
+ "database.cloudapi.de",
93
+ "database.fabric.microsoft.com",
94
+ }
95
+ )
96
+
97
+
98
+ def _scope_from_server_spn(spn: str) -> str:
99
+ """Return the ``.default`` scope for a server-supplied resource SPN.
100
+
101
+ Raises ``RuntimeError`` unless the SPN is an https URL on an allow-listed
102
+ SQL resource host. Only the host is used; any path or query is dropped.
103
+ """
104
+ # pylint: disable=import-outside-toplevel
105
+ from urllib.parse import urlparse
106
+
107
+ try:
108
+ parsed = urlparse(spn or "")
109
+ host = (parsed.hostname or "").lower()
110
+ except ValueError:
111
+ host = ""
112
+ if parsed.scheme != "https" or host not in _ALLOWED_SQL_RESOURCE_HOSTS or parsed.port not in (None, 443):
113
+ raise RuntimeError(
114
+ "Refusing to request an Entra token: the server named a resource that is not a "
115
+ "known SQL resource host"
116
+ )
117
+ return f"https://{host}/.default"
118
+
119
+
84
120
  # One-time guard so the DefaultAzureCredential multi-user pooling caveat is
85
121
  # logged at most once per process rather than on every token acquisition.
86
122
  _dac_pooling_warned = False
@@ -443,6 +479,7 @@ class ServicePrincipalAuth:
443
479
  tenant_id = _parse_tenant_id(sts_url)
444
480
  if not tenant_id:
445
481
  raise RuntimeError(f"Could not extract tenant_id from STS URL: {sts_url!r}")
482
+ scope = _scope_from_server_spn(spn)
446
483
 
447
484
  try:
448
485
  # Reuse the shared credential cache (introduced for MSI in PR #573)
@@ -508,7 +545,6 @@ class ServicePrincipalAuth:
508
545
  )
509
546
  _credential_cache[cache_key] = credential
510
547
  # mssql-tds passes the resource SPN; azure-identity wants a scope.
511
- scope = spn if spn.endswith("/.default") else spn.rstrip("/") + "/.default"
512
548
  token = credential.get_token(scope).token
513
549
  logger.info(
514
550
  "ServicePrincipal token factory: token acquired, length=%d chars",
@@ -28,10 +28,11 @@ import queue
28
28
  import threading
29
29
  import time
30
30
  import warnings
31
- from contextlib import closing
31
+ from contextlib import ExitStack, closing
32
32
  from concurrent.futures import ThreadPoolExecutor, wait
33
33
  from typing import Any, Optional
34
34
 
35
+ from arrowsql import ddbc_bindings
35
36
  from arrowsql.db_connection import connect
36
37
 
37
38
  # Cap on rows per slice. Smaller slices spread work across workers; larger
@@ -94,8 +95,9 @@ def write_arrow(
94
95
  ``rows_per_second`` and ``workers`` (connections used).
95
96
 
96
97
  Raises the first error from any worker or from reading the source. The
97
- other workers stop taking new slices. ``workers > 1`` needs pyarrow to cut
98
- the source.
98
+ other workers stop taking new slices. No Arrow library is needed: the
99
+ source is imported once through the Arrow C stream and cut into slices in
100
+ Rust (a streaming source is read on demand, not materialized).
99
101
  """
100
102
  _check_args(workers, batch_size, timeout)
101
103
  bulk_options = {
@@ -117,15 +119,8 @@ def write_arrow(
117
119
  result = _load_single(connection_str, table, source, table_lock, bulk_options, connect_kwargs)
118
120
  return _summarize([result], 1, started)
119
121
 
120
- slice_rows = _slice_rows(source, workers)
121
- results = _load_parallel(
122
- connection_str,
123
- workers,
124
- _slices(source, slice_rows),
125
- lambda cursor, first, pieces: _load_arrow_pieces(
126
- cursor, table, first, pieces, table_lock, bulk_options
127
- ),
128
- connect_kwargs,
122
+ results = _load_native_parallel(
123
+ connection_str, table, source, workers, table_lock, bulk_options, connect_kwargs
129
124
  )
130
125
  return _summarize(results, workers, started)
131
126
 
@@ -235,19 +230,46 @@ def _slice_size(count, workers):
235
230
  return max(1, min(_MAX_SLICE_ROWS, -(-count // (workers * _SLICES_PER_WORKER))))
236
231
 
237
232
 
238
- def _slice_rows(source, workers):
239
- num_rows = getattr(source, "num_rows", None)
240
- if isinstance(num_rows, int) and num_rows > 0:
241
- return _slice_size(num_rows, workers)
242
- return _MAX_SLICE_ROWS
243
-
244
-
245
233
  def _load_single(connection_str, table, source, table_lock, bulk_options, connect_kwargs):
246
234
  with connect(connection_str, autocommit=True, **connect_kwargs) as conn:
247
235
  with closing(conn.cursor()) as cursor:
248
236
  return cursor.bulkcopy_arrow(table, source, table_lock=table_lock, **bulk_options)
249
237
 
250
238
 
239
+ def _load_native_parallel(connection_str, table, source, workers, table_lock, bulk_options, connect_kwargs):
240
+ """One Rust call: N connections pull slices of ``source`` from a shared cursor."""
241
+ from arrowsql.cursor import _raise_native_bulk_error
242
+
243
+ with ExitStack() as stack:
244
+ with ThreadPoolExecutor(max_workers=workers, thread_name_prefix="mssql-bulk-connect") as pool:
245
+ futures = [
246
+ pool.submit(connect, connection_str, autocommit=True, **connect_kwargs)
247
+ for _ in range(workers)
248
+ ]
249
+ connections = []
250
+ failure = None
251
+ for future in futures:
252
+ try:
253
+ connections.append(stack.enter_context(future.result()))
254
+ except BaseException as exc:
255
+ failure = failure or exc
256
+ if failure is not None:
257
+ raise failure
258
+ cursors = [stack.enter_context(closing(conn.cursor())) for conn in connections]
259
+ handles = [cursor._native_bulk_handle("DDBCBulkCopyArrowParallel") for cursor in cursors]
260
+ if any(handle is None for handle in handles):
261
+ raise RuntimeError("write_arrow with workers > 1 needs the native (Rust) driver")
262
+ for cursor in cursors:
263
+ cursor._check_closed()
264
+ cursor._bulkcopy_connection_params()
265
+ try:
266
+ return ddbc_bindings.DDBCBulkCopyArrowParallel(
267
+ handles, table, source, table_lock=table_lock, **bulk_options
268
+ )
269
+ except RuntimeError as err:
270
+ _raise_native_bulk_error(err)
271
+
272
+
251
273
  def _load_parallel(connection_str, workers, pieces, load, connect_kwargs):
252
274
  """Feed ``pieces`` to ``workers`` connections. ``load(cursor, first, pieces)``
253
275
  runs one bulk copy over the pieces a worker pulls and returns its result."""
@@ -300,15 +322,6 @@ def _load_worker(connection_str, pending, stop, load, connect_kwargs):
300
322
  return load(cursor, first, pieces())
301
323
 
302
324
 
303
- def _load_arrow_pieces(cursor, table, first, pieces, table_lock, bulk_options):
304
- import pyarrow as pa
305
-
306
- # A RecordBatchReader is an Arrow C stream, which the native bulk
307
- # copy consumes directly; a bare generator would need mssql_py_core.
308
- reader = pa.RecordBatchReader.from_batches(first.schema, pieces)
309
- return cursor.bulkcopy_arrow(table, reader, table_lock=table_lock, **bulk_options)
310
-
311
-
312
325
  def _load_row_pieces(cursor, table, first, pieces, table_lock, bulk_options):
313
326
  rows = itertools.chain.from_iterable(pieces)
314
327
  return cursor.bulkcopy(table, rows, table_lock=table_lock, **bulk_options)
@@ -330,27 +343,6 @@ def _row_slices(rows, workers):
330
343
  yield chunk
331
344
 
332
345
 
333
- def _slices(source, slice_rows):
334
- """Yield non-empty RecordBatch slices of at most ``slice_rows`` rows."""
335
- for batch in _record_batches(source):
336
- for offset in range(0, batch.num_rows, slice_rows):
337
- yield batch.slice(offset, slice_rows)
338
-
339
-
340
- def _record_batches(source):
341
- import pyarrow as pa
342
-
343
- if isinstance(source, pa.Table):
344
- return source.to_batches()
345
- if isinstance(source, pa.RecordBatch):
346
- return [source]
347
- if isinstance(source, pa.RecordBatchReader) or hasattr(source, "__arrow_c_stream__"):
348
- return pa.RecordBatchReader.from_stream(source)
349
- if hasattr(source, "__arrow_c_array__"):
350
- return [pa.record_batch(source)]
351
- return source
352
-
353
-
354
346
  def _put(pending, item, stop):
355
347
  """Put ``item`` unless the load was stopped. Returns False if stopped."""
356
348
  while not stop.is_set():