Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/bindings.nodejs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ jobs:
shell: bash
env:
NAPI_TARGET: ${{ matrix.target }}
MACOSX_DEPLOYMENT_TARGET: 10.12
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
pnpm napi build --platform --target=$NAPI_TARGET --js generated.js
Expand Down
63 changes: 55 additions & 8 deletions .github/workflows/bindings.python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
run: ruff format --check .

build:
name: build-${{ matrix.os }}-${{ matrix.arch }}
name: build-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.wheel }}
needs: check
runs-on: ${{ matrix.runner }}
strategy:
Expand All @@ -51,10 +51,22 @@ jobs:
arch: x86_64
target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
wheel: py39-abi
- os: linux
arch: x86_64
target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
wheel: cp38
- os: linux
arch: aarch64
target: aarch64-unknown-linux-gnu
runner: ubuntu-latest
wheel: py39-abi
- os: linux
arch: aarch64
target: aarch64-unknown-linux-gnu
runner: ubuntu-latest
wheel: cp38
# FIXME: Windows build is broken
# - os: windows
# arch: x86_64
Expand All @@ -64,21 +76,39 @@ jobs:
arch: x86_64
target: x86_64-apple-darwin
runner: macos-latest
wheel: py39-abi
- os: macos
arch: x86_64
target: x86_64-apple-darwin
runner: macos-latest
wheel: cp38
- os: macos
arch: aarch64
target: aarch64-apple-darwin
runner: macos-latest
wheel: py39-abi
- os: macos
arch: aarch64
target: aarch64-apple-darwin
runner: macos-latest
wheel: cp38
steps:
- uses: actions/checkout@v4
- name: Get opts
id: opts
shell: bash
run: |
if [[ "${{ github.event_name }}" == "pull_request" ]]; then
echo "BUILD_ARGS=--strip --out dist" >> $GITHUB_OUTPUT
base_args="--strip --out dist"
else
base_args="--release --strip --out dist"
fi
if [[ "${{ matrix.wheel }}" == "py39-abi" ]]; then
wheel_args="--features py39-abi"
else
echo "BUILD_ARGS=--release --strip --out dist" >> $GITHUB_OUTPUT
wheel_args="--no-default-features --features cp38 --interpreter python3.8"
fi
echo "BUILD_ARGS=${base_args} ${wheel_args}" >> $GITHUB_OUTPUT
if [[ "${{ matrix.target }}" == "aarch64-unknown-linux-gnu" ]]; then
echo "MANYLINUX=2_28" >> $GITHUB_OUTPUT
else
Expand All @@ -89,6 +119,11 @@ jobs:
with:
cache-key: bindings-python-${{ matrix.os }}-${{ matrix.arch }}
target: ${{ matrix.target }}
- name: Setup Python 3.8 (cp38 wheels)
if: matrix.wheel == 'cp38' && matrix.os != 'linux'
uses: actions/setup-python@v5
with:
python-version: "3.8"
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
Expand All @@ -100,16 +135,17 @@ jobs:
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: bindings-python-${{ matrix.os }}-${{ matrix.arch }}
name: bindings-python-${{ matrix.os }}-${{ matrix.arch }}-${{ matrix.wheel }}
path: bindings/python/dist/*.whl

integration:
name: integration-${{ matrix.pyver }}
name: integration-${{ matrix.pyver }}-${{matrix.body}}
needs: build
runs-on: ubuntu-latest
strategy:
matrix:
pyver: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
body: ["arrow", "json"]
steps:
- uses: actions/checkout@v4
- name: Setup Python
Expand All @@ -122,22 +158,33 @@ jobs:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: bindings-python-linux-x86_64
pattern: bindings-python-linux-x86_64-*
path: bindings/python/artifacts
merge-multiple: true
- name: Install dependencies
working-directory: bindings/python
run: |
pip install behave
pip install artifacts/*.whl
if [[ "${{ matrix.pyver }}" == "3.8" ]]; then
pip install artifacts/*cp38*.whl
else
pip install artifacts/*abi3*.whl
fi
- name: Test AsyncIO
working-directory: bindings/python
run: behave tests/asyncio
env:
BODY_FORMAT: ${{ matrix.body }}
- name: Test Blocking
working-directory: bindings/python
run: behave tests/blocking
env:
BODY_FORMAT: ${{ matrix.body }}
- name: Test Cursor
working-directory: bindings/python
run: behave tests/cursor
env:
BODY_FORMAT: ${{ matrix.body }}

compat:
name: Compat Test
Expand All @@ -154,7 +201,7 @@ jobs:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: bindings-python-linux-x86_64
name: bindings-python-linux-x86_64-py39-abi
path: bindings/python/dist
- name: Run Nox
run: nox -f tests/nox/noxfile.py
Expand Down
29 changes: 24 additions & 5 deletions .github/workflows/cron.integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,27 +46,41 @@ jobs:
run: make -C tests test-bendsql DATABEND_QUERY_VERSION=${{ needs.version.outputs.version }}

build-python:
name: build-python
name: build-python-${{ matrix.wheel }}
runs-on: ubuntu-latest
strategy:
matrix:
wheel: [py39-abi, cp38]
steps:
- uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: ./.github/actions/setup
with:
cache-key: bindings-python-linux-x64
target: x86_64-unknown-linux-gnu
- name: Get opts
id: opts
shell: bash
run: |
base_args="--release --strip --out dist"
if [[ "${{ matrix.wheel }}" == "py39-abi" ]]; then
wheel_args="--features py39-abi"
else
wheel_args="--no-default-features --features cp38 --interpreter python3.8"
fi
echo "BUILD_ARGS=${base_args} ${wheel_args}" >> $GITHUB_OUTPUT
- name: Build wheels
uses: PyO3/maturin-action@v1
with:
working-directory: bindings/python
target: x86_64-unknown-linux-gnu
manylinux: auto
sccache: "true"
args: --release --strip --out dist
args: ${{ steps.opts.outputs.BUILD_ARGS }}
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: bindings-python
name: bindings-python-${{ matrix.wheel }}
path: bindings/python/dist/*.whl

build-nodejs:
Expand Down Expand Up @@ -120,13 +134,18 @@ jobs:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: bindings-python
pattern: bindings-python-*
path: bindings/python/artifacts
merge-multiple: true
- name: Install dependencies
working-directory: bindings/python
run: |
pip install behave
pip install artifacts/*.whl
if [[ "${{ matrix.pyver }}" == "3.8" ]]; then
pip install artifacts/*cp38*.whl
else
pip install artifacts/*abi3*.whl
fi
- name: Test AsyncIO
working-directory: bindings/python
run: behave tests/asyncio
Expand Down
2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,13 @@ databend-driver-macros = { path = "macros", version = "0.30.3" }
jsonb = { version = "0.5.3" }
tokio-stream = "0.1"
chrono = { version = "0.4.40", default-features = false, features = ["clock"] }
chrono-tz = { version = "0.10.4" }
arrow = { version = "55.0" }
arrow-array = { version = "55.0" }
arrow-buffer = { version = "55.0" }
arrow-schema = { version = "55.0" }
arrow-flight = { version = "55.0", features = ["flight-sql-experimental"] }
arrow-ipc = { version = "55.0", features = ["lz4", "zstd"]}
tonic = { version = "0.12", default-features = false, features = [
"transport",
"codegen",
Expand Down
1 change: 1 addition & 0 deletions bindings/nodejs/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ doc = false

[dependencies]
chrono = { workspace = true }
chrono-tz = { workspace = true }
databend-driver = { workspace = true, features = ["rustls", "flight-sql"] }
env_logger = "0.11.8"
tokio-stream = { workspace = true }
Expand Down
9 changes: 5 additions & 4 deletions bindings/nodejs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
#[macro_use]
extern crate napi_derive;

use chrono::{NaiveDate, NaiveDateTime, NaiveTime};
use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime};
use chrono_tz::Tz;
use databend_driver::LoadMethod;
use napi::{bindgen_prelude::*, Env};
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -314,10 +315,10 @@ impl ToNapiValue for Value<'_> {
databend_driver::Value::Number(n) => {
NumberValue::to_napi_value(env, NumberValue(n.clone()))
}
databend_driver::Value::Timestamp(_) => {
databend_driver::Value::Timestamp(_, _tz) => {
let inner = val.inner.clone();
let v = NaiveDateTime::try_from(inner).map_err(format_napi_error)?;
NaiveDateTime::to_napi_value(env, v)
let v = DateTime::<Tz>::try_from(inner).map_err(format_napi_error)?;
DateTime::to_napi_value(env, v)
}
databend_driver::Value::Date(_) => {
let inner = val.inner.clone();
Expand Down
8 changes: 7 additions & 1 deletion bindings/python/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ doc = false

[dependencies]
chrono = { workspace = true }
chrono-tz = { workspace = true }
databend-client = { workspace = true }
databend-driver = { workspace = true, features = ["rustls", "flight-sql"] }
databend-driver-core = { workspace = true }
Expand All @@ -23,6 +24,11 @@ ctor = "0.2"
env_logger = "0.11.8"
http = "1.0"
once_cell = "1.21"
pyo3 = { version = "0.24.2", features = ["abi3-py37", "chrono"] }
pyo3 = { version = "0.24.2", features = ["extension-module", "chrono", "chrono-tz"] }
pyo3-async-runtimes = { version = "0.24", features = ["tokio-runtime"] }
tokio = "1.44"

[features]
default = ["py39-abi"]
py39-abi = ["pyo3/abi3-py39"]
cp38 = []
22 changes: 18 additions & 4 deletions bindings/python/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@

use std::sync::Arc;

use chrono::{Duration, NaiveDate, NaiveDateTime};
#[cfg(feature = "cp38")]
use chrono::offset::Offset;
#[cfg(feature = "cp38")]
use chrono::FixedOffset;
use chrono::{DateTime, Duration, NaiveDate};
use chrono_tz::Tz;
use once_cell::sync::Lazy;
use pyo3::exceptions::{PyAttributeError, PyException, PyStopAsyncIteration, PyStopIteration};
use pyo3::sync::GILOnceCell;
Expand Down Expand Up @@ -73,11 +78,20 @@ impl<'py> IntoPyObject<'py> for Value {
let v = NumberValue(n);
v.into_bound_py_any(py)?
}
databend_driver::Value::Timestamp(_) => {
let t = NaiveDateTime::try_from(self.0).map_err(|e| {
databend_driver::Value::Timestamp(_, _) => {
let t = DateTime::<Tz>::try_from(self.0).map_err(|e| {
PyException::new_err(format!("failed to convert timestamp: {e}"))
})?;
t.into_bound_py_any(py)?
#[cfg(feature = "cp38")]
{
// chrono_tz -> PyDateTime isn't implemented for Python < 3.9 (no zoneinfo).
let t: DateTime<FixedOffset> = t.with_timezone(&t.offset().fix());
t.into_bound_py_any(py)?
}
#[cfg(not(feature = "cp38"))]
{
t.into_bound_py_any(py)?
}
}
databend_driver::Value::Date(_) => {
let d = NaiveDate::try_from(self.0)
Expand Down
Loading
Loading