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.
- arrowsql-0.2.0/AGENTS.md +27 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/CHANGELOG.md +40 -3
- {arrowsql-0.1.0 → arrowsql-0.2.0}/Cargo.lock +2 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/Cargo.toml +4 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/PKG-INFO +1 -1
- arrowsql-0.2.0/build.rs +3 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/AGENT_MODE.md +14 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PACKAGING.md +5 -4
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ROADMAP.md +2 -2
- {arrowsql-0.1.0 → arrowsql-0.2.0}/pyproject.toml +3 -2
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/_rust_auth.py +23 -8
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/aio.py +20 -7
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/arrow_parallel.py +11 -4
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/auth.py +37 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/bulk_parallel.py +41 -49
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/connection.py +18 -13
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/connection_string_parser.py +33 -5
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/cursor.py +44 -7
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/ddbc_bindings.pyi +13 -0
- arrowsql-0.2.0/python/arrowsql/exceptions.py +214 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/helpers.py +13 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/logging.py +8 -8
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/parameter_helper.py +4 -12
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/row.py +23 -208
- {arrowsql-0.1.0 → arrowsql-0.2.0}/requirements-dev.txt +1 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/check_upstream_baseline.py +12 -2
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/run_tests.py +18 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/mod.rs +2 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/connection.rs +60 -20
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/convert.rs +49 -66
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/hub.rs +2 -23
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/pool.rs +25 -3
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/session.rs +149 -53
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/sink.rs +13 -15
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/arrow_encode.rs +4 -2
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/mod.rs +2 -0
- arrowsql-0.2.0/src/bulk/parallel.rs +193 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/rows.rs +7 -17
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/settings.rs +10 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/wire.rs +1 -15
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/connection.rs +28 -11
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/buffer.rs +39 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/python.rs +1 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/temporal.rs +27 -0
- arrowsql-0.2.0/src/errors.rs +316 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/getinfo.rs +7 -12
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/lib.rs +7 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/logging.rs +12 -0
- arrowsql-0.2.0/src/numeric.rs +40 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/batch.rs +18 -9
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/mod.rs +6 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/py_types.rs +54 -102
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/pooling.rs +2 -2
- arrowsql-0.2.0/src/rowfactory.rs +368 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/runtime.rs +34 -12
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/batch_rpc.rs +1 -8
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/cancel.rs +3 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/cursor.rs +1 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/exec.rs +3 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/mod.rs +2 -1
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/odbc.rs +24 -5
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/statement/wire.rs +17 -2
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/conftest.py +8 -1
- arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/MAPPING.md +87 -0
- arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/test_bulk_timeout_udt.py +67 -0
- arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/test_bulk_types_and_errors.py +233 -0
- arrowsql-0.2.0/tests/common_issues/ported_mssql_rs/test_session_and_rpc.py +402 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_connection_strings.py +3 -1
- arrowsql-0.2.0/tests/common_issues/test_review_python_security.py +92 -0
- arrowsql-0.2.0/tests/common_issues/test_review_security_parser.py +27 -0
- arrowsql-0.2.0/tests/common_issues/test_review_security_scripts.py +80 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_row_access.py +29 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_aio.py +10 -1
- arrowsql-0.2.0/tests/common_issues/test_rs_aio_review.py +287 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_auth_keywords.py +74 -2
- arrowsql-0.2.0/tests/common_issues/test_rs_bulk_parallel_native.py +191 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_parallel_rows.py +9 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_core_regressions.py +2 -2
- arrowsql-0.2.0/tests/common_issues/test_rs_review_rust.py +158 -0
- arrowsql-0.2.0/tests/mock/conftest.py +234 -0
- arrowsql-0.2.0/tests/mock/mockutil.py +6 -0
- arrowsql-0.2.0/tests/mock/test_aio_null_discovery.py +47 -0
- arrowsql-0.2.0/tests/mock/test_faults.py +285 -0
- arrowsql-0.2.0/tests/mock/test_login_tls.py +208 -0
- arrowsql-0.2.0/tests/mock/test_results.py +157 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/VENDOR.md +10 -3
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/tds_client.rs +20 -0
- arrowsql-0.1.0/python/arrowsql/exceptions.py +0 -378
- arrowsql-0.1.0/src/rowfactory.rs +0 -70
- {arrowsql-0.1.0 → arrowsql-0.2.0}/.cargo/config.toml +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/.gitattributes +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/.gitignore +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/CONTRIBUTING.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/LICENSE +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/LICENSE.upstream-mssql-python +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/README.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ARCHITECTURE.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ARROW_ODBC_RESEARCH.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ARROW_PLAN.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/ASYNC.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/BENCHMARK_SUMMARY.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/CONTRACT.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/EXPORT_RESEARCH.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/FEATURES.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/FREE_THREADED.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PERFORMANCE_RESEARCH.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PLATFORMS_AND_CONNECTION.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/PYTHON_LAYER_CHANGES.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/TEST_SCOPE.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/UPSTREAM_BUGS_FOUND.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/UPSTREAM_ISSUES.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/icon.svg +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo-dark-static.svg +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo-dark.svg +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo-static.svg +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/docs/assets/logo.svg +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/README.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/_demo.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/agent_mode.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/arrow_duckdb.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/odbc2deltalake_sync.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/examples/write_arrow.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/__init__.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/_server_sqlstate.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/_utf8_strings.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/agent.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/__init__.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/_connection_context.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/_native.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_connection.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_cursor.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_execute.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/async_fetch.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/async_query/exception_translator.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/connection_string_builder.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/constants.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/db_connection.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/decimal_config.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/mssql_python.pyi +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/odbc_provider.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/perf_timer.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/pooling.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/py.typed +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/arrowsql/type.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/python/mssql_python/__init__.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/bench_reproduce.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/build.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/ci/install-sqlserver-windows.ps1 +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/codex_review.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/env.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/load_taxi.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/overlay_upstream_binding.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/release_rustflags.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/setup_tls_cert.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/test_overlay.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/scripts/wheel_size.sh +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/fmt.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/render.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/agent/sqltype.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/aio/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/export.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/arrow/plan.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/arrow_source.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/bulk/arrow_wire.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/catalog.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/connstr.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/consts.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/binary.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/describe.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/hidden.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/numeric.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/decode/text.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/diag.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/null_types.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/placeholders.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/pyformat.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/params/udt.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/types.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/src/utf8_wrap.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_ctds.txt +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_dotnet_sqlclient.txt +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_go_mssqldb.txt +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/LICENSE_sqlalchemy.txt +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/README.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_ctds_cursor_fetch.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_ctds_executemany.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_ctds_transactions.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_fastmssql_async_threads.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_fastmssql_errors_values.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_fastmssql_lifecycle_pool.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_go_mssqldb_bulkcopy.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_go_mssqldb_xact_guid.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_jdbc_bigint_guid.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_jdbc_temporal_params.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_rs_arrow_bulkcopy.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_mssql_rs_bulkcopy.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pymssql_bulkcopy_paths.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pymssql_qmark_substitution.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pymssql_types_procs.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pyodbc_connection.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pyodbc_cursor_results.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_pyodbc_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_rust_mssql_driver_bulkcopy.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_rust_mssql_driver_param_echo.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_catalog.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_identity_sequence.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_query.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlalchemy_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlclient_bulkcopy.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_sqlclient_scalar_commands.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tedious_protocol.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tedious_statements.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_bulk.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_login_password.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_query_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/ported/test_port_tiberius_results_transactions.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/rs_dtypes.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_binary_guid.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_dead_connection.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_decimal_numeric.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_executemany.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_g1_pyformat_scanner.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_integers_bool_float.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_issue_581_sqlstate.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_large_values.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_messages_errors.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_multiple_results.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_nulls_typing.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_agent_mode.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_aio_pool_semantics.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_aio.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_exotic.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_paths.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_all_data_types_special.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arith_errors.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arrow_native.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arrow_stream_close.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_arrow_type_mapping.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_batch_parsing.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bigint_overflow_agg.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_decimal_width.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_native.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_native_rows.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_parallel.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_rows_pipeline.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_bulk_serializer_chunks.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_cancel.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_char_padding.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_client_cpu_paths.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_collation_case.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_cte_recursion.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_database_context.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_date_strings_dateformat.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_datetimeoffset_deep.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_decimal_param_inference.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_decode_fastpaths.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_defaults_computed.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_description_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_duckdb_integration.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_error_mid_resultset.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_executemany_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_fetch_sizes_arraysize.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_float_real_edges.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_for_json.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_g3_decode_encode.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_hidden_columns.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_hierarchyid.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_identifiers_quoting.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_identity_triggers.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_isolation_levels.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_leaks_lifecycle.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_legacy_datetime_rounding.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_legacy_lob_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_locking_blocking.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_merge_output.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_message_flood.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_metadata_reuse.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_money_arithmetic.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_null_semantics.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_output_clause.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_pandas_polars_io.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_binding_fastpaths.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_fast_cells.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_type_plancache.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_param_wire_paths.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_pyformat_named.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_read_arrow_partitions.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_read_arrow_stream.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_rowversion_concurrency.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_savepoints_nested.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_session_set_options.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_setinputsizes.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_sparse_columnsets.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_spatial_deep.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_sql_variant_deep.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_string_truncation.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_temporal_tables.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_time7_precision.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_time_scales.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_triggers_rowcount.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_tvp_support.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_uniqueidentifier_order.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_utf8_collations.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_utf8_strings.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_varchar_codepages.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_rs_xml_deep.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_scope_identity_temp.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_special_types.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_stored_procs.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_temporal.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_threading_gil.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_timeouts_cancel.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_transactions.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_unicode.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/common_issues/test_wide_and_many.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/port/test_free_threaded.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/port/test_runtime_fork.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/port/test_tls.py +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/upstream_excluded.txt +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/tests/upstream_passing_baseline.txt +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/.env +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/Cargo.toml +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/LICENSE +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/README.md +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cli.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/blocking.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/bulk_copy.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/bulk_copy_state.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/client_context.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/connect_stage.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/connection_actions.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/cursor_ops.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/datasource_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/dns_cache.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/execution_context.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/instance_cache.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/metadata_retriever.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/multi_subnet_failover.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/session_recovery.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/any_transport.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/buffers.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/busy_poll.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/certificate_validator.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/extractable_stream.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/localdb.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/named_pipes.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/network_transport.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/parallel_connect.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/ssl_handler.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tds_transport.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tls/native_tls_engine.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tls/rustls_engine.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/tls.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/alpn.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/bindings.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/cred.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/engine.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/errors.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/handshake.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/record_layer.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/sspi.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/stream.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport/win_tls/validate.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection/transport.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection_provider/tds_connection_provider.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/connection_provider.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/core.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cursor/cursor_response.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cursor/cursor_types.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/cursor/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/bulk_copy_metadata.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/bulk_copy_metadata_tests.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/column_values.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/decoder.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/encoder.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/lcid_encoding.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/row_writer.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_json.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_string/encoding.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_string.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_tvp.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_udt.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sql_vector.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sqldatatypes.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sqltypes.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/sync_decoder.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes/tds_value_serializer.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/datatypes.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/error/bulk_copy_errors.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/error/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/fuzz_support.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/handler/handler_factory.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/handler/sspi_handler.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/handler.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/packet_reader.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/packet_writer.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/reader_writer.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io/token_stream.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/io.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/lib.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/attention.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/batch.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/bulk_load.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/bulk_load_tests.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/always_encrypted.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/data_classification.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/dns_caching.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/enhanced_routing.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/fedauth.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/jsonfeature.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/session_recovery.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/useragent.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/utf8.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features/vectorfeature.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/features.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/headers.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/login.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/login_options.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/messages.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/parameters/rpc_parameters.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/parameters.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/prelogin.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/rpc.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message/transaction_management.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/message.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/query/metadata.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/query/result.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/query.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/cell_decryptor.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/apple.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/cng.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/der.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/openssl.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/crypto/unsupported.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/describe_parameter_encryption.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/encryption/aead_aes_256_cbc_hmac_sha256.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/encryption/cell.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/encryption/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/error.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/keystore/certificate.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/keystore/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/mock.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/query_metadata_cache.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/security_context.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/spn.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/unix/gssapi_context.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/unix/gssapi_ffi.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/unix/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/windows/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/windows/sspi_context.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/security/windows/sspi_ffi.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/sql_identifier.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/ssrp.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/test_client_support.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/test_packet_support.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/data_classification.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/fed_auth_info.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/login_ack.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/col_info_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/colmetadata_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/common.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/data_classification_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/done_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/envchange_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/error_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/featureext_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/fedauth_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/info_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/loginack_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/mod.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/nbcrow_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/order_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/returnstatus_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/returnvalue_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/row_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/session_state_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/sspi_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/parsers/tab_name_parser.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/tokenitems.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token/tokens.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/token.rs +0 -0
- {arrowsql-0.1.0 → arrowsql-0.2.0}/vendor/mssql-tds/src/trace_context.rs +0 -0
arrowsql-0.2.0/AGENTS.md
ADDED
|
@@ -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.
|
|
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
|
|
83
|
-
-
|
|
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.
|
|
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.
|
|
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
|
|
arrowsql-0.2.0/build.rs
ADDED
|
@@ -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()
|
|
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: `
|
|
70
|
-
`
|
|
71
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
|
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
|
|
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 =
|
|
99
|
+
scope = _auth._scope_from_server_spn(spn)
|
|
96
100
|
try:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
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.
|
|
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.
|
|
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)
|
|
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
|
-
|
|
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.
|
|
98
|
-
the
|
|
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
|
-
|
|
121
|
-
|
|
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():
|