This is an automated email from the ASF dual-hosted git repository.

lidavidm pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-adbc.git


The following commit(s) were added to refs/heads/main by this push:
     new 6d3d91caf build: package wheels for Windows/ARM (#4691)
6d3d91caf is described below

commit 6d3d91cafd0659e1594941ffafb08f1a38403fd5
Author: David Li <[email protected]>
AuthorDate: Tue Aug 25 15:37:59 2026 +0900

    build: package wheels for Windows/ARM (#4691)
    
    Closes #4684.
    
    Assisted-by: GPT-5.6 Sol <[email protected]>
---
 .github/workflows/java.yml                        |   8 +-
 .github/workflows/packaging.yml                   | 191 +++++++++++++++++++---
 LICENSE.txt                                       |   3 +-
 c/vendor/backward/backward.hpp                    |  40 ++++-
 ci/scripts/python_wheel_windows_build.bat         |  96 -----------
 ci/scripts/python_wheel_windows_build_drivers.ps1 | 127 ++++++++++++++
 ci/scripts/python_wheel_windows_build_manager.ps1 |  56 +++++++
 ci/scripts/python_wheel_windows_test.bat          |  41 -----
 ci/scripts/python_wheel_windows_test.ps1          | 102 ++++++++++++
 python/adbc_driver_flightsql/LICENSE.txt          |   5 +-
 python/adbc_driver_postgresql/LICENSE.txt         |   5 +-
 python/adbc_driver_sqlite/LICENSE.txt             |   5 +-
 12 files changed, 503 insertions(+), 176 deletions(-)

diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml
index 6b3a956da..8f418b7e0 100644
--- a/.github/workflows/java.yml
+++ b/.github/workflows/java.yml
@@ -159,10 +159,12 @@ jobs:
           ./ci/scripts/python_wheel_unix_build.sh ${{ matrix.arch }} $(pwd) 
$(pwd)/build
       - name: Build artifacts (Windows)
         if: matrix.os == 'Windows'
-        # TODO(https://github.com/apache/arrow-adbc/issues/4269): remove 
cmd.exe usage
-        shell: cmd # zizmor: ignore[misfeature]
+        shell: pwsh
         run: |
-          .\ci\scripts\python_wheel_windows_build.bat %cd% %cd%\build\${{ 
matrix.vcpkg_arch }}
+          .\ci\scripts\python_wheel_windows_build_drivers.ps1 `
+            -SourceDir $PWD.Path `
+            -BuildDir (Join-Path $PWD.Path "build/${{ matrix.vcpkg_arch }}") `
+            -Architecture "amd64"
 
       - name: Build driver manager (Windows)
         if: matrix.os == 'Windows'
diff --git a/.github/workflows/packaging.yml b/.github/workflows/packaging.yml
index 78f27d153..2d44d140b 100644
--- a/.github/workflows/packaging.yml
+++ b/.github/workflows/packaging.yml
@@ -952,16 +952,18 @@ jobs:
           path: ~/logs
 
   python-windows:
-    name: "Python ${{ matrix.python_version }} Windows"
-    runs-on: windows-latest
+    name: "Python ${{ matrix.arch }} Windows"
+    runs-on: ${{ matrix.runner }}
     needs:
       - source
     strategy:
       fail-fast: false
       matrix:
-        python_version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.14t"]
+        include:
+          - { arch: amd64, python_arch: x64, runner: windows-latest }
+          - { arch: arm64, python_arch: arm64, runner: windows-11-vs2026-arm }
     env:
-      PYTHON_VERSION: "${{ matrix.python_version }}"
+      VCPKG_DEFAULT_TRIPLET: ${{ matrix.python_arch }}-windows-static-release
       VCPKG_ROOT: "${{ github.workspace }}/vcpkg"
     steps:
       - uses: 
actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
@@ -999,6 +1001,26 @@ jobs:
           choco install --no-progress -y cmake --installargs 
'ADD_CMAKE_TO_PATH=System'
           choco install --no-progress -y visualcpp-build-tools
 
+      - name: Install MSYS2
+        if: matrix.arch == 'arm64'
+        id: msys2
+        uses: msys2/setup-msys2@66cd2cce69caa17b53920067426061ca1de3a884 # 
v2.32.0
+        with:
+          msystem: CLANGARM64
+          update: true
+          install: |
+            mingw-w64-clang-aarch64-gcc-compat
+            mingw-w64-clang-aarch64-tools
+
+      - name: Add MSYS2 toolchain to PATH
+        if: matrix.arch == 'arm64'
+        env:
+          MSYS_LOCATION: ${{ steps.msys2.outputs.msys2-location }}
+        shell: pwsh
+        run: |
+          "$env:MSYS_LOCATION\clangarm64\bin" |
+            Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
+
       - name: Install vcpkg
         shell: bash
         run: |
@@ -1009,28 +1031,117 @@ jobs:
         with:
           go-version: "${{ env.GO_VERSION }}"
           check-latest: true
-          cache: false
+          cache: false  # disable to protect against cache poisoning
           cache-dependency-path: adbc/go/adbc/go.sum
 
-      - name: Install Python ${{ matrix.python_version }}
+      - name: Install Python 3.10
+        if: matrix.arch == 'amd64'
+        id: python310
         uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # 
v7.0.0
         with:
+          architecture: ${{ matrix.python_arch }}
           check-latest: true
-          python-version: ${{ matrix.python_version }}
+          python-version: "3.10"
+          update-environment: false
 
-      - name: Build wheel
-        # TODO(https://github.com/apache/arrow-adbc/issues/4269): remove 
cmd.exe usage
-        shell: cmd # zizmor: ignore[misfeature]
-        run: |
-          pushd adbc
-          set SETUPTOOLS_SCM_PRETEND_VERSION=%VERSION%
-          .\ci\scripts\python_wheel_windows_build.bat %cd% %cd%\build
-          popd
+      - name: Install Python 3.11
+        id: python311
+        uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # 
v7.0.0
+        with:
+          architecture: ${{ matrix.python_arch }}
+          check-latest: true
+          python-version: "3.11"
+          update-environment: false
+
+      - name: Install Python 3.12
+        id: python312
+        uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # 
v7.0.0
+        with:
+          architecture: ${{ matrix.python_arch }}
+          check-latest: true
+          python-version: "3.12"
+          update-environment: false
+
+      - name: Install Python 3.13
+        id: python313
+        uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # 
v7.0.0
+        with:
+          architecture: ${{ matrix.python_arch }}
+          check-latest: true
+          python-version: "3.13"
+          update-environment: false
+
+      - name: Install Python 3.14
+        id: python314
+        uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # 
v7.0.0
+        with:
+          architecture: ${{ matrix.python_arch }}
+          check-latest: true
+          python-version: "3.14"
+          update-environment: false
+
+      - name: Install Python 3.14t
+        id: python314t
+        uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # 
v7.0.0
+        with:
+          architecture: ${{ matrix.python_arch }}
+          check-latest: true
+          python-version: "3.14t"
+          update-environment: false
+
+      - name: Build driver wheels
+        shell: pwsh
+        env:
+          PYTHON_PATH: ${{ steps.python311.outputs.python-path }}
+          SETUPTOOLS_SCM_PRETEND_VERSION: ${{ env.VERSION }}
+        run: |
+          $PythonDir = Split-Path $env:PYTHON_PATH
+          $env:PATH = "$PythonDir;$env:PATH"
+          Set-Location adbc
+          .\ci\scripts\python_wheel_windows_build_drivers.ps1 `
+            -SourceDir $PWD.Path `
+            -BuildDir (Join-Path $PWD.Path "build") `
+            -Architecture "${{ matrix.arch }}"
+          if (-not $?) { throw "Failed to build driver wheels" }
+
+      - name: Build driver manager wheels
+        shell: pwsh
+        env:
+          PYTHON_310: ${{ steps.python310.outputs.python-path }}
+          PYTHON_311: ${{ steps.python311.outputs.python-path }}
+          PYTHON_312: ${{ steps.python312.outputs.python-path }}
+          PYTHON_313: ${{ steps.python313.outputs.python-path }}
+          PYTHON_314: ${{ steps.python314.outputs.python-path }}
+          PYTHON_314T: ${{ steps.python314t.outputs.python-path }}
+          SETUPTOOLS_SCM_PRETEND_VERSION: ${{ env.VERSION }}
+        run: |
+          $OriginalPath = $env:PATH
+          $Pythons = @(
+            @{ Version = "3.10"; Path = $env:PYTHON_310 },
+            @{ Version = "3.11"; Path = $env:PYTHON_311 },
+            @{ Version = "3.12"; Path = $env:PYTHON_312 },
+            @{ Version = "3.13"; Path = $env:PYTHON_313 },
+            @{ Version = "3.14"; Path = $env:PYTHON_314 },
+            @{ Version = "3.14t"; Path = $env:PYTHON_314T }
+          )
+          Set-Location adbc
+          foreach ($Python in $Pythons) {
+            if ([string]::IsNullOrEmpty($Python.Path)) {
+              continue
+            }
+            Write-Host "::group::Building driver manager for Python 
$($Python.Version)"
+            $env:PYTHON_VERSION = $Python.Version
+            $PythonDir = Split-Path $Python.Path
+            $env:PATH = "$PythonDir;$OriginalPath"
+            .\ci\scripts\python_wheel_windows_build_manager.ps1 -SourceDir 
$PWD.Path
+            if (-not $?) { throw "Failed to build the Python 
$($Python.Version) driver manager wheel" }
+            Write-Host "::endgroup::"
+          }
 
       - name: Archive wheels
         uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a 
# v7.0.1
         with:
-          name: python${{ matrix.python_version }}-windows
+          name: python-windows-${{ matrix.arch }}
           retention-days: 7
           path: |
             adbc/python/adbc_driver_flightsql/repaired_wheels/*.whl
@@ -1040,17 +1151,45 @@ jobs:
             adbc/build/**/*.pdb
 
       - name: Test wheel
-        # TODO(https://github.com/apache/arrow-adbc/issues/4269): remove 
cmd.exe usage
-        shell: cmd # zizmor: ignore[misfeature]
+        shell: pwsh
         env:
-          PYTHON_VERSION: ${{ matrix.python_version }}
-        run: |
-          pushd adbc
-          where python.exe
-          python -m venv venv
-          CALL venv\Scripts\activate.bat
-          .\ci\scripts\python_wheel_windows_test.bat %cd%
-          popd
+          PYTHON_310: ${{ steps.python310.outputs.python-path }}
+          PYTHON_311: ${{ steps.python311.outputs.python-path }}
+          PYTHON_312: ${{ steps.python312.outputs.python-path }}
+          PYTHON_313: ${{ steps.python313.outputs.python-path }}
+          PYTHON_314: ${{ steps.python314.outputs.python-path }}
+          PYTHON_314T: ${{ steps.python314t.outputs.python-path }}
+        run: |
+          $DriverDir = Join-Path $PWD "adbc/build/bin"
+          $OriginalPath = "$DriverDir;$env:PATH"
+          $Pythons = @(
+            @{ Version = "3.10"; Path = $env:PYTHON_310 },
+            @{ Version = "3.11"; Path = $env:PYTHON_311 },
+            @{ Version = "3.12"; Path = $env:PYTHON_312 },
+            @{ Version = "3.13"; Path = $env:PYTHON_313 },
+            @{ Version = "3.14"; Path = $env:PYTHON_314 },
+            @{ Version = "3.14t"; Path = $env:PYTHON_314T }
+          )
+          Set-Location adbc
+          foreach ($Python in $Pythons) {
+            if ([string]::IsNullOrEmpty($Python.Path)) {
+              continue
+            }
+            Write-Host "::group::Testing wheels with Python $($Python.Version)"
+            $env:PYTHON_VERSION = $Python.Version
+            $PythonDir = Split-Path $Python.Path
+            $env:PATH = "$PythonDir;$OriginalPath"
+            $VenvDir = Join-Path $env:RUNNER_TEMP 
"adbc-wheel-test-$($Python.Version)"
+            python -m venv $VenvDir
+            if (-not $?) { throw "Failed to create the Python 
$($Python.Version) test environment" }
+            $env:PATH = "$(Join-Path $VenvDir 'Scripts');$env:PATH"
+            .\ci\scripts\python_wheel_windows_test.ps1 `
+              -SourceDir $PWD.Path `
+              -Architecture "${{ matrix.arch }}"
+            if (-not $?) { throw "Failed to test the Python $($Python.Version) 
wheels" }
+            Remove-Item -Recurse -Force -ErrorAction SilentlyContinue $VenvDir
+            Write-Host "::endgroup::"
+          }
 
   python-sdist:
     name: "Python sdist"
diff --git a/LICENSE.txt b/LICENSE.txt
index 6e1393ec3..836f349e2 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
 backward-cpp has the following license:
 
 Copyright 2013 Google Inc. All Rights Reserved.
diff --git a/c/vendor/backward/backward.hpp b/c/vendor/backward/backward.hpp
index a42c481c7..bab33dd57 100644
--- a/c/vendor/backward/backward.hpp
+++ b/c/vendor/backward/backward.hpp
@@ -954,7 +954,7 @@ public:
           reinterpret_cast<void *>(uctx->uc_mcontext.gregs[REG_EIP]);
       ++index;
       ctx = *reinterpret_cast<unw_context_t *>(uctx);
-#elif defined(__arm__)
+#elif defined(__arm__)     // clang libunwind/arm
       // libunwind uses its own context type for ARM unwinding.
       // Copy the registers from the signal handler's context so we can
       // unwind
@@ -985,6 +985,24 @@ public:
       }
       _stacktrace[index] = reinterpret_cast<void *>(ctx.regs[UNW_ARM_R15]);
       ++index;
+#elif defined(__aarch64__) // gcc libunwind/arm64
+      unw_getcontext(&ctx);
+      // If the IP is the same as the crash address we have a bad function
+      // dereference The caller's address is pointed to by the link pointer, so
+      // we dereference that value and set it to be the next frame's IP.
+      if (uctx->uc_mcontext.pc == reinterpret_cast<__uint64_t>(error_addr())) {
+        uctx->uc_mcontext.pc = uctx->uc_mcontext.regs[UNW_TDEP_IP];
+      }
+
+      // 29 general purpose registers
+      for (int i = UNW_AARCH64_X0; i <= UNW_AARCH64_X28; i++) {
+        ctx.uc_mcontext.regs[i] = uctx->uc_mcontext.regs[i];
+      }
+      ctx.uc_mcontext.sp = uctx->uc_mcontext.sp;
+      ctx.uc_mcontext.pc = uctx->uc_mcontext.pc;
+      ctx.uc_mcontext.fault_address = uctx->uc_mcontext.fault_address;
+      _stacktrace[index] = reinterpret_cast<void *>(ctx.uc_mcontext.pc);
+      ++index;
 #elif defined(__APPLE__) && defined(__x86_64__)
       unw_getcontext(&ctx);
       // OS X's implementation of libunwind uses its own context object
@@ -1160,10 +1178,18 @@ public:
     s.AddrStack.Mode = AddrModeFlat;
     s.AddrFrame.Mode = AddrModeFlat;
     s.AddrPC.Mode = AddrModeFlat;
-#ifdef _M_X64
+#if defined(_M_X64)
     s.AddrPC.Offset = ctx_->Rip;
     s.AddrStack.Offset = ctx_->Rsp;
     s.AddrFrame.Offset = ctx_->Rbp;
+#elif defined(_M_ARM64)
+    s.AddrPC.Offset = ctx_->Pc;
+    s.AddrStack.Offset = ctx_->Sp;
+    s.AddrFrame.Offset = ctx_->Fp;
+#elif defined(_M_ARM)
+    s.AddrPC.Offset = ctx_->Pc;
+    s.AddrStack.Offset = ctx_->Sp;
+    s.AddrFrame.Offset = ctx_->R11;
 #else
     s.AddrPC.Offset = ctx_->Eip;
     s.AddrStack.Offset = ctx_->Esp;
@@ -1171,8 +1197,12 @@ public:
 #endif
 
     if (!machine_type_) {
-#ifdef _M_X64
+#if defined(_M_X64)
       machine_type_ = IMAGE_FILE_MACHINE_AMD64;
+#elif defined(_M_ARM64)
+      machine_type_ = IMAGE_FILE_MACHINE_ARM64;
+#elif defined(_M_ARM)
+      machine_type_ = IMAGE_FILE_MACHINE_ARMNT;
 #else
       machine_type_ = IMAGE_FILE_MACHINE_I386;
 #endif
@@ -4260,6 +4290,8 @@ public:
 #elif defined(__mips__)
     error_addr = reinterpret_cast<void *>(
         reinterpret_cast<struct sigcontext *>(&uctx->uc_mcontext)->sc_pc);
+#elif defined(__APPLE__) && defined(__POWERPC__)
+    error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__srr0);
 #elif defined(__ppc__) || defined(__powerpc) || defined(__powerpc__) ||        
\
     defined(__POWERPC__)
     error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.regs->nip);
@@ -4271,6 +4303,8 @@ public:
     error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__rip);
 #elif defined(__APPLE__)
     error_addr = reinterpret_cast<void *>(uctx->uc_mcontext->__ss.__eip);
+#elif defined(__loongarch__)
+    error_addr = reinterpret_cast<void *>(uctx->uc_mcontext.__pc);
 #else
 #warning ":/ sorry, ain't know no nothing none not of your architecture!"
 #endif
diff --git a/ci/scripts/python_wheel_windows_build.bat 
b/ci/scripts/python_wheel_windows_build.bat
deleted file mode 100644
index 0a81ea792..000000000
--- a/ci/scripts/python_wheel_windows_build.bat
+++ /dev/null
@@ -1,96 +0,0 @@
-@rem Licensed to the Apache Software Foundation (ASF) under one
-@rem or more contributor license agreements.  See the NOTICE file
-@rem distributed with this work for additional information
-@rem regarding copyright ownership.  The ASF licenses this file
-@rem to you under the Apache License, Version 2.0 (the
-@rem "License"); you may not use this file except in compliance
-@rem with the License.  You may obtain a copy of the License at
-@rem
-@rem   http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing,
-@rem software distributed under the License is distributed on an
-@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@rem KIND, either express or implied.  See the License for the
-@rem specific language governing permissions and limitations
-@rem under the License.
-
-@echo on
-
-set source_dir=%1
-set build_dir=%2
-
-echo "=== (%PYTHON_VERSION%) Building ADBC libpq driver ==="
-
-set CMAKE_BUILD_TYPE=RelWithDebInfo
-set CMAKE_GENERATOR=Visual Studio 18 2026
-set CMAKE_GENERATOR_PLATFORM=x64
-set CMAKE_UNITY_BUILD=ON
-set VCPKG_FEATURE_FLAGS=-manifests
-set VCPKG_TARGET_TRIPLET=x64-windows-static
-set VCPKG_DEFAULT_HOST_TRIPLET=x64-windows-static
-
-IF NOT DEFINED VCPKG_ROOT (echo "Must set VCPKG_ROOT" && exit /B 1)
-IF NOT DEFINED ADBC_BUILD_STATIC SET ADBC_BUILD_STATIC=OFF
-
-%VCPKG_ROOT%\vcpkg install --triplet=%VCPKG_TARGET_TRIPLET% libpq 
"sqlite3[dbstat,fts3,fts4,fts5,geopoly,json1,limit,math,rtree,session,snapshot,soundex]"
-IF %errorlevel% NEQ 0 EXIT /B %errorlevel%
-
-mkdir %build_dir%
-pushd %build_dir%
-
-cmake ^
-      -G "%CMAKE_GENERATOR%" ^
-      -A "%CMAKE_GENERATOR_PLATFORM%" ^
-      -DADBC_BUILD_SHARED=ON ^
-      -DADBC_BUILD_STATIC=%ADBC_BUILD_STATIC% ^
-      -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% ^
-      -DCMAKE_INSTALL_PREFIX=%build_dir% ^
-      -DCMAKE_TOOLCHAIN_FILE=%VCPKG_ROOT%/scripts/buildsystems/vcpkg.cmake ^
-      -DCMAKE_UNITY_BUILD=%CMAKE_UNITY_BUILD% ^
-      -DVCPKG_TARGET_TRIPLET=%VCPKG_TARGET_TRIPLET% ^
-      -DADBC_DRIVER_FLIGHTSQL=ON ^
-      -DADBC_DRIVER_MANAGER=ON ^
-      -DADBC_DRIVER_POSTGRESQL=ON ^
-      -DADBC_DRIVER_SQLITE=ON ^
-      %source_dir%\c || exit /B 1
-
-cmake --build . --config %CMAKE_BUILD_TYPE% --target install --verbose -j || 
exit /B 1
-
-set ADBC_FLIGHTSQL_LIBRARY=%build_dir%\bin\adbc_driver_flightsql.dll
-set ADBC_POSTGRESQL_LIBRARY=%build_dir%\bin\adbc_driver_postgresql.dll
-set ADBC_SQLITE_LIBRARY=%build_dir%\bin\adbc_driver_sqlite.dll
-
-# Build with Cython debug info
-set ADBC_BUILD_TYPE=debug
-
-popd
-
-python -m pip install --upgrade pip delvewheel wheel || exit /B 1
-
-FOR /F %%i IN ('python -c "import sysconfig; 
print(sysconfig.get_platform())"') DO set PLAT_NAME=%%i
-
-FOR %%c IN (adbc_driver_manager adbc_driver_flightsql adbc_driver_postgresql 
adbc_driver_sqlite) DO (
-    pushd %source_dir%\python\%%c
-
-    echo "=== (%PYTHON_VERSION%) Checking %%c version ==="
-    python %%c\_version.py || exit /B 1
-
-    echo "=== (%PYTHON_VERSION%) Building %%c wheel ==="
-    python -m pip wheel --no-deps -w dist -vvv . || exit /B 1
-
-    echo "=== (%PYTHON_VERSION%) Re-tag %%c wheel ==="
-    FOR %%w IN (dist\*.whl) DO (
-        python %source_dir%\ci\scripts\python_wheel_fix_tag.py %%w || exit /B 1
-    )
-
-    echo "=== (%PYTHON_VERSION%) Repair %%c wheel ==="
-    REM Always copy the wheel once since delvewheel doesn't copy if no changes 
needed
-    mkdir repaired_wheels
-    FOR %%w IN (dist\*.whl) DO (
-        copy %%w repaired_wheels\
-        delvewheel repair -w repaired_wheels\ %%w || exit /B 1
-    )
-
-    popd
-)
diff --git a/ci/scripts/python_wheel_windows_build_drivers.ps1 
b/ci/scripts/python_wheel_windows_build_drivers.ps1
new file mode 100755
index 000000000..6f67840fc
--- /dev/null
+++ b/ci/scripts/python_wheel_windows_build_drivers.ps1
@@ -0,0 +1,127 @@
+#!/usr/bin/env pwsh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+param(
+    [Parameter(Mandatory = $true)]
+    [string]$SourceDir,
+    [Parameter(Mandatory = $true)]
+    [string]$BuildDir,
+    [Parameter(Mandatory = $true)]
+    [ValidateSet("amd64", "arm64")]
+    [string]$Architecture
+)
+
+$ErrorActionPreference = "Stop"
+
+if (-not $env:VCPKG_ROOT) {
+    throw "Must set VCPKG_ROOT"
+}
+
+if ($Architecture -eq "amd64") {
+    $CMakePlatform = "x64"
+    $PlatformTag = "win_amd64"
+    $VcpkgTriplet = "x64-windows-static-release"
+} else {
+    $CMakePlatform = "ARM64"
+    $PlatformTag = "win_arm64"
+    $VcpkgTriplet = "arm64-windows-static-release"
+}
+
+$BuildType = "RelWithDebInfo"
+$env:VCPKG_FEATURE_FLAGS = "-manifests"
+$env:VCPKG_TARGET_TRIPLET = $VcpkgTriplet
+$env:VCPKG_DEFAULT_HOST_TRIPLET = $VcpkgTriplet
+
+Write-Host "=== Building ADBC drivers for $Architecture ==="
+
+& (Join-Path $env:VCPKG_ROOT "vcpkg.exe") install `
+    "--triplet=$VcpkgTriplet" `
+    "libpq" `
+    
"sqlite3[dbstat,fts3,fts4,fts5,geopoly,json1,limit,math,rtree,session,snapshot,soundex]"
 `
+    --overlay-triplets $(Join-Path $SourceDir "ci\vcpkg\triplets")
+if (-not $?) { throw "Failed to install vcpkg dependencies" }
+
+New-Item -ItemType Directory -Force -Path $BuildDir | Out-Null
+
+cmake `
+    -S (Join-Path $SourceDir "c") `
+    -B $BuildDir `
+    -G "Visual Studio 18 2026" `
+    -A $CMakePlatform `
+    -DADBC_BUILD_SHARED=ON `
+    "-DCMAKE_BUILD_TYPE=$BuildType" `
+    "-DCMAKE_INSTALL_PREFIX=$BuildDir" `
+    "-DCMAKE_TOOLCHAIN_FILE=$(Join-Path $env:VCPKG_ROOT 
'scripts/buildsystems/vcpkg.cmake')" `
+    -DCMAKE_UNITY_BUILD=ON `
+    "-DVCPKG_OVERLAY_TRIPLETS=$(Join-Path $SourceDir 'ci\vcpkg\triplets')" `
+    "-DVCPKG_TARGET_TRIPLET=$VcpkgTriplet" `
+    -DADBC_DRIVER_FLIGHTSQL=ON `
+    -DADBC_DRIVER_MANAGER=ON `
+    -DADBC_DRIVER_POSTGRESQL=ON `
+    -DADBC_DRIVER_SQLITE=ON
+if (-not $?) { throw "Failed to configure the CMake build" }
+
+cmake --build $BuildDir --config $BuildType --target install --verbose -j
+if (-not $?) { throw "Failed to build and install the CMake project" }
+
+$env:ADBC_FLIGHTSQL_LIBRARY = Join-Path $BuildDir 
"bin/adbc_driver_flightsql.dll"
+$env:ADBC_POSTGRESQL_LIBRARY = Join-Path $BuildDir 
"bin/adbc_driver_postgresql.dll"
+$env:ADBC_SQLITE_LIBRARY = Join-Path $BuildDir "bin/adbc_driver_sqlite.dll"
+
+python -m pip install --upgrade pip delvewheel wheel
+if (-not $?) { throw "Failed to install Python build dependencies" }
+
+$env:ADBC_BUILD_TYPE = "debug"
+$Components = @(
+    "adbc_driver_flightsql",
+    "adbc_driver_postgresql",
+    "adbc_driver_sqlite"
+)
+
+foreach ($Component in $Components) {
+    $ComponentDir = Join-Path $SourceDir "python/$Component"
+    Push-Location $ComponentDir
+    try {
+        Remove-Item -Recurse -Force -ErrorAction SilentlyContinue build, dist, 
repaired_wheels
+
+        Write-Host "=== Checking $Component version ==="
+        python "$Component/_version.py"
+        if (-not $?) { throw "Failed to check the $Component version" }
+
+        Write-Host "=== Building $Component wheel ==="
+        python -m pip wheel --no-deps -w dist -vvv .
+        if (-not $?) { throw "Failed to build the $Component wheel" }
+
+        $Wheels = @(Get-ChildItem -Path "dist/*.whl")
+        foreach ($Wheel in $Wheels) {
+            python (Join-Path $SourceDir "ci/scripts/python_wheel_fix_tag.py") 
`
+                "--plat-name=$PlatformTag" $Wheel.FullName
+            if (-not $?) { throw "Failed to update the $Component wheel tag" }
+        }
+
+        New-Item -ItemType Directory -Force -Path repaired_wheels | Out-Null
+        $Wheels = @(Get-ChildItem -Path "dist/*.whl")
+        foreach ($Wheel in $Wheels) {
+            Copy-Item $Wheel.FullName repaired_wheels
+            python -m delvewheel repair -w repaired_wheels $Wheel.FullName
+            if (-not $?) { throw "Failed to repair the $Component wheel" }
+        }
+    } finally {
+        Pop-Location
+    }
+}
diff --git a/ci/scripts/python_wheel_windows_build_manager.ps1 
b/ci/scripts/python_wheel_windows_build_manager.ps1
new file mode 100755
index 000000000..a5c7559eb
--- /dev/null
+++ b/ci/scripts/python_wheel_windows_build_manager.ps1
@@ -0,0 +1,56 @@
+#!/usr/bin/env pwsh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+param(
+    [Parameter(Mandatory = $true)]
+    [string]$SourceDir
+)
+
+$ErrorActionPreference = "Stop"
+$Component = "adbc_driver_manager"
+$ComponentDir = Join-Path $SourceDir "python/$Component"
+$TemporaryWheelDir = Join-Path $ComponentDir "temp_wheels"
+
+python -m pip install --upgrade pip delvewheel wheel
+if (-not $?) { throw "Failed to install Python build dependencies" }
+
+$env:ADBC_BUILD_TYPE = "debug"
+
+Push-Location $ComponentDir
+try {
+    Remove-Item -Recurse -Force -ErrorAction SilentlyContinue build, 
$TemporaryWheelDir
+
+    Write-Host "=== Checking $Component version ==="
+    python "$Component/_version.py"
+    if (-not $?) { throw "Failed to check the $Component version" }
+
+    Write-Host "=== Building $Component wheel ==="
+    python -m pip wheel --no-deps -w $TemporaryWheelDir -vvv .
+    if (-not $?) { throw "Failed to build the $Component wheel" }
+
+    New-Item -ItemType Directory -Force -Path repaired_wheels | Out-Null
+    $Wheels = @(Get-ChildItem -Path "$TemporaryWheelDir/*.whl")
+    foreach ($Wheel in $Wheels) {
+        Copy-Item $Wheel.FullName repaired_wheels
+        python -m delvewheel repair -w repaired_wheels $Wheel.FullName
+        if (-not $?) { throw "Failed to repair the $Component wheel" }
+    }
+} finally {
+    Pop-Location
+    Remove-Item -Recurse -Force -ErrorAction SilentlyContinue 
$TemporaryWheelDir
+}
diff --git a/ci/scripts/python_wheel_windows_test.bat 
b/ci/scripts/python_wheel_windows_test.bat
deleted file mode 100644
index 78e60681f..000000000
--- a/ci/scripts/python_wheel_windows_test.bat
+++ /dev/null
@@ -1,41 +0,0 @@
-@rem Licensed to the Apache Software Foundation (ASF) under one
-@rem or more contributor license agreements.  See the NOTICE file
-@rem distributed with this work for additional information
-@rem regarding copyright ownership.  The ASF licenses this file
-@rem to you under the Apache License, Version 2.0 (the
-@rem "License"); you may not use this file except in compliance
-@rem with the License.  You may obtain a copy of the License at
-@rem
-@rem   http://www.apache.org/licenses/LICENSE-2.0
-@rem
-@rem Unless required by applicable law or agreed to in writing,
-@rem software distributed under the License is distributed on an
-@rem "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-@rem KIND, either express or implied.  See the License for the
-@rem specific language governing permissions and limitations
-@rem under the License.
-
-@echo on
-
-set source_dir=%1
-
-echo "=== (%PYTHON_VERSION%) Installing wheels ==="
-
-FOR %%c IN (adbc_driver_manager adbc_driver_flightsql adbc_driver_postgresql 
adbc_driver_sqlite) DO (
-    FOR %%w IN (%source_dir%\python\%%c\dist\*.whl) DO (
-        pip install --no-deps --force-reinstall %%w || exit /B 1
-    )
-)
-
-pip install pytest pyarrow pandas protobuf
-
-echo "=== (%PYTHON_VERSION%) Testing wheels ==="
-
-IF [%PYTHON_VERSION:~-1%]==[t] SET PYTHON_GIL=0
-
-FOR %%c IN (adbc_driver_manager adbc_driver_flightsql adbc_driver_postgresql 
adbc_driver_sqlite) DO (
-    echo "=== Testing %%c ==="
-    python -c "import %%c" || exit /B 1
-    python -c "import %%c.dbapi" || exit /B 1
-    python -m pytest -vvx --import-mode append -k "not duckdb and not sqlite 
and not polars" %source_dir%\python\%%c\tests || exit /B 1
-)
diff --git a/ci/scripts/python_wheel_windows_test.ps1 
b/ci/scripts/python_wheel_windows_test.ps1
new file mode 100755
index 000000000..2c1a525be
--- /dev/null
+++ b/ci/scripts/python_wheel_windows_test.ps1
@@ -0,0 +1,102 @@
+#!/usr/bin/env pwsh
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+param(
+    [Parameter(Mandatory = $true)]
+    [string]$SourceDir,
+    [Parameter(Mandatory = $true)]
+    [ValidateSet("amd64", "arm64")]
+    [string]$Architecture
+)
+
+$ErrorActionPreference = "Stop"
+$Components = @(
+    "adbc_driver_manager",
+    "adbc_driver_flightsql",
+    "adbc_driver_postgresql",
+    "adbc_driver_sqlite"
+)
+$PythonTag = python -c "import sysconfig; print('cp' + 
sysconfig.get_python_version().replace('.', ''))"
+if (-not $?) { throw "Failed to determine the Python tag" }
+# https://github.com/python/cpython/issues/127405: unlike Unix, Windows does 
not
+# expose free-threading through abiflags, so use Py_GIL_DISABLED instead.
+$PythonFlags = python -c "import sysconfig; print('t' if 
sysconfig.get_config_var('Py_GIL_DISABLED') else '')"
+if (-not $?) { throw "Failed to determine whether Python is free-threaded" }
+$PythonTag = $PythonTag.Trim()
+$PythonFlags = $PythonFlags.Trim()
+if ($PythonFlags.Contains("t")) {
+    $env:PYTHON_GIL = "0"
+}
+
+Write-Host "=== ($PythonTag$PythonFlags) Installing wheels ==="
+
+foreach ($Component in $Components) {
+    if ($Component -eq "adbc_driver_manager") {
+        $WheelPattern = "*-$PythonTag-$PythonTag$PythonFlags-*.whl"
+    } else {
+        $WheelPattern = "*-py3-none-*.whl"
+    }
+
+    $WheelDir = Join-Path $SourceDir "python/$Component/repaired_wheels"
+    $Wheels = @(Get-ChildItem -Path (Join-Path $WheelDir $WheelPattern))
+    if ($Wheels.Count -ne 1) {
+        throw "Expected one $Component wheel matching $WheelPattern, found 
$($Wheels.Count)"
+    }
+
+    python -m pip install --no-deps --force-reinstall $Wheels[0].FullName
+    if (-not $?) { throw "Failed to install the $Component wheel" }
+}
+
+python -m pip install pytest typing-extensions
+if (-not $?) { throw "Failed to install Python test dependencies" }
+
+foreach ($Component in $Components) {
+    python -c "import $Component; import $Component.dbapi"
+    if (-not $?) { throw "Failed to import $Component" }
+}
+
+# TODO(lidavidm): make tests consistent with Unix, also consistently mark
+# tests with what they require so we can easily filter them here
+if ($PythonFlags.Contains("t") -and $Architecture -ne "amd64") {
+    Write-Host "=== Testing free-threaded driver manager without PyArrow or 
Polars ==="
+    # We don't have pyarrow or polars, so most tests won't work
+    python -m pytest -vvx --import-mode append `
+        -k "unknown_driver or missing_platform or bad" `
+        (Join-Path $SourceDir 
"python/adbc_driver_manager/tests/test_manifest.py")
+    if (-not $?) { throw "Failed to test the free-threaded driver manager" }
+} elseif ($Architecture -eq "amd64") {
+    python -m pip install pyarrow pandas protobuf
+    if (-not $?) { throw "Failed to install amd64 Python test dependencies" }
+
+    foreach ($Component in $Components) {
+        Write-Host "=== Testing $Component ==="
+        python -m pytest -vvx --import-mode append `
+            -k "not duckdb and not sqlite and not polars" `
+            (Join-Path $SourceDir "python/$Component/tests")
+        if (-not $?) { throw "Failed to test $Component" }
+    }
+} else {
+    python -m pip install polars
+    if (-not $?) { throw "Failed to install Polars" }
+
+    Write-Host "=== Testing driver manager with Polars and without PyArrow ==="
+    $env:ADBC_NO_SKIP_TESTS = "1"
+    python -m pytest -vvx --import-mode append `
+        (Join-Path $SourceDir 
"python/adbc_driver_manager/tests/test_dbapi_polars_nopyarrow.py")
+    if (-not $?) { throw "Failed to test the driver manager with Polars" }
+}
diff --git a/python/adbc_driver_flightsql/LICENSE.txt 
b/python/adbc_driver_flightsql/LICENSE.txt
index 61aa66933..234146c77 100644
--- a/python/adbc_driver_flightsql/LICENSE.txt
+++ b/python/adbc_driver_flightsql/LICENSE.txt
@@ -271,7 +271,7 @@ All rights reserved.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/fmt contain code from {fmt}.
+The files under c/vendor/fmt contain code from {fmt}, version 12.2.0.
 {fmt} is under the MIT license:
 
 Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
 backward-cpp has the following license:
 
 Copyright 2013 Google Inc. All Rights Reserved.
diff --git a/python/adbc_driver_postgresql/LICENSE.txt 
b/python/adbc_driver_postgresql/LICENSE.txt
index 2880ddafe..674e4fa1f 100644
--- a/python/adbc_driver_postgresql/LICENSE.txt
+++ b/python/adbc_driver_postgresql/LICENSE.txt
@@ -271,7 +271,7 @@ All rights reserved.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/fmt contain code from {fmt}.
+The files under c/vendor/fmt contain code from {fmt}, version 12.2.0.
 {fmt} is under the MIT license:
 
 Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
 backward-cpp has the following license:
 
 Copyright 2013 Google Inc. All Rights Reserved.
diff --git a/python/adbc_driver_sqlite/LICENSE.txt 
b/python/adbc_driver_sqlite/LICENSE.txt
index 8ba94fd8d..5fd5ba981 100644
--- a/python/adbc_driver_sqlite/LICENSE.txt
+++ b/python/adbc_driver_sqlite/LICENSE.txt
@@ -271,7 +271,7 @@ All rights reserved.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/fmt contain code from {fmt}.
+The files under c/vendor/fmt contain code from {fmt}, version 12.2.0.
 {fmt} is under the MIT license:
 
 Copyright (c) 2012 - present, Victor Zverovich and {fmt} contributors
@@ -297,7 +297,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 
SOFTWARE.
 
 
--------------------------------------------------------------------------------
 
-The files under c/vendor/backward contain code from backward-cpp.
+The files under c/vendor/backward contain code from backward-cpp, commit
+0bfd0a07a61551413ccd2ab9a9099af3bad40681.
 backward-cpp has the following license:
 
 Copyright 2013 Google Inc. All Rights Reserved.

Reply via email to