Skip to content
Closed
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
27 changes: 24 additions & 3 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,21 @@ jobs:
echo "::error::integration tests failed on Java $VERSION"
failed="$failed $VERSION"
fi

# The optional Arrow module uses Arrow Java's C Data JNI on the same staged
# release pair. All A1/A2 registration and A5 insert tests must run on rc.3;
# no local-engine or skipEngineVersionCheck override is allowed in PR CI.
if mvn $MAVEN_ARGS -pl chdb-arrow -am test \
-Djvm="$HOME_DIR/bin/java" \
-Dchdb.arrow.it=true \
-Dchdb.library.path="$LIBS" \
-DargLine=--add-opens=java.base/java.nio=ALL-UNNAMED \
-DfailIfNoTests=true; then
echo "Arrow Java $VERSION passed (see report for the separate core conversion regression)"
else
echo "::error::Arrow integration tests failed on Java $VERSION"
failed="$failed $VERSION-arrow"
fi
echo "::endgroup::"
done

Expand Down Expand Up @@ -282,7 +297,7 @@ jobs:
if: always()
uses: actions/upload-artifact@v4
with:
name: debug-symbols-${{ matrix.platform }}-java${{ matrix.java }}
name: debug-symbols-${{ matrix.platform }}
path: target/debug-symbols/
if-no-files-found: ignore
retention-days: 14
Expand All @@ -291,9 +306,14 @@ jobs:
if: failure()
uses: actions/upload-artifact@v4
with:
name: test-reports-${{ matrix.platform }}-java${{ matrix.java }}
name: test-reports-${{ matrix.platform }}
path: |
chdb-jdbc/target/surefire-reports/
chdb-arrow/target/surefire-reports/
chdb-arrow/target/hs_err_pid*.log
chdb-arrow/target/replay_pid*.log
chdb-arrow/*.dump
chdb-arrow/*.dumpstream
chdb-integration-tests/target/failsafe-reports/
chdb-integration-tests/target/hs_err_pid*.log
chdb-integration-tests/target/replay_pid*.log
Expand Down Expand Up @@ -354,6 +374,7 @@ jobs:
*) ARCH=x86_64 ;;
esac
LIBS="$PWD/chdb-native-${{ matrix.platform }}/target/native/META-INF/chdb/native/linux/$ARCH"
ENGINE_VERSION=$(sed -n 's/^engine.version=//p' scripts/engine.properties | head -1)

# The workspace and the local Maven repository are mounted at the paths they already
# have, so the classpath file needs no rewriting.
Expand All @@ -370,7 +391,7 @@ jobs:
ldd '"$LIBS"'/libchdb_java_jni.so

echo
java -Xmx512m -Dchdb.library.path='"$LIBS"' -Dchdb.it.engine.version=26.11.0-rc.2 -cp "'"$PWD"'/chdb-jdbc/target/classes:'"$PWD"'/chdb-integration-tests/target/test-classes:'"$(cat target/it-cp.txt)"'" org.junit.platform.console.ConsoleLauncher execute --select-package=org.chdb.it --include-classname=".*IT" --details=summary --disable-banner --fail-if-no-tests
java -Xmx512m -Dchdb.library.path='"$LIBS"' -Dchdb.it.engine.version='"$ENGINE_VERSION"' -cp "'"$PWD"'/chdb-jdbc/target/classes:'"$PWD"'/chdb-integration-tests/target/test-classes:'"$(cat target/it-cp.txt)"'" org.junit.platform.console.ConsoleLauncher execute --select-package=org.chdb.it --include-classname=".*IT" --details=summary --disable-banner --fail-if-no-tests
'

- name: A query over the memory limit returns an exception, not an OOM kill
Expand Down
14 changes: 9 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ streaming, forward-only result sets over ClickHouse SQL.

> **Status: release candidate.** The current Maven release candidate is `v1.0.0-rc.2`, built with
> chDB Core `26.11.0-rc.2`. RC artifacts are available from the public chDB Maven repository; the
> public API is not frozen. See
> public API is not frozen. This development branch targets core `26.11.0-rc.3` and adds an
> optional `chdb-arrow` module; those Java artifacts have not been published. See
> [What works today](#what-works-today).

```java
Expand All @@ -23,8 +24,9 @@ try (Connection connection = DriverManager.getConnection("jdbc:chdb::memory:");

## Support matrix

Every one of the four platforms builds, passes the full test suite on Java 11, 17, 21 and 25,
and is loaded from a real packaged JAR, in CI:
The existing JDBC binding has built and passed its full suite on these four platforms and
Java 11, 17, 21 and 25 in CI. The new Arrow module is added to the PR matrix for rc.3,
but is not yet a published-platform claim:

| | Linux glibc | macOS |
|---|---|---|
Expand All @@ -40,7 +42,8 @@ and is loaded from a real packaged JAR, in CI:
engine does. Each package records the figure it was built against in its
`manifest.properties`, and CI runs the whole test suite on AlmaLinux 8 to demonstrate the
floor rather than infer it from symbol versions.
- **Engine:** chDB Core **26.11.0-rc.2**, pinned. The C ABI is version-locked, so the driver
- **Engine in this source branch:** chDB Core **26.11.0-rc.3**, pinned. Published Java
`1.0.0-rc.2` still uses core `26.11.0-rc.2`. The C ABI is version-locked, so the driver
refuses to run against a different engine build rather than risking a struct-layout mismatch.
That release is a chdb-core *pre-release*, pinned to validate the ClickHouse 26.11 baseline;
a binding on an engine RC is itself an RC and is not the V1 GA
Expand Down Expand Up @@ -114,7 +117,8 @@ all-platforms package, on purpose: it would be the sum of those four.
SemVer, on the binding alone: `1.0.0` is the first release and a major bump means a breaking
change to the Java API. The engine version is not part of it — it is in each package's
`manifest.properties`, pinned in [`scripts/engine.properties`](scripts/engine.properties) and
named in the release notes (`26.11.0-rc.2` today), and the driver refuses to load any other build.
named in the release notes (`26.11.0-rc.2` for the published Java RC, `26.11.0-rc.3`
in this development branch), and the driver refuses to load any other build.

The first test version is the RC `1.0.0-rc.1`; later candidates increment the final number, and
the first stable Maven release is `1.0.0`. RCs use the permanent `com.clickhouse.chdb` groupId,
Expand Down
57 changes: 57 additions & 0 deletions chdb-arrow/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# chDB Arrow (in development)

This optional artifact currently contains experimental A1 batch/A2 reader registration,
A3 materialized output, A4 incremental output, and A5 synchronous insert. It is not an implementation of the complete
A1–A6 native Arrow contract.
It does not use Arrow IPC, and it does not promise zero copies inside ClickHouse.

`ArrowSession.openInMemory()` opens a dedicated JDBC-managed connection to the process-wide
in-memory database; `open(jdbcUrl)` also supports the JDBC driver's path rules.
`queryArrowMaterialized(sql, allocator)` executes the complete query before it
returns an Apache Arrow Java `ArrowReader`. The caller closes the reader and then its
allocator. The session does not share another JDBC connection. `registerOwnedReader(reader, allocator)`
transfers reader ownership and returns a closable scope with `fromSql()`. Use that SQL
fragment only on the owning session, for one scan. Keep the allocator alive until the scope
is closed. A close requested while a materialized query runs waits for it to complete,
then unregisters before releasing the C stream. `queryArrow(sql, allocator)` returns an
`ArrowQuery` reader that pulls one core batch at a time. Close it after partial consumption,
or call `cancel()` to stop future fetches; cancellation waits for a fetch already in progress.
Only one incremental query may be active on a session.
`insertBatch(table, root, allocator)` and `insertOwnedReader(table, reader, allocator)`
use core's synchronous C Stream insert. Only simple ASCII table names and distinctly named
source columns are accepted; this excludes core's unnamed-column positional fallback.
There is no transaction guarantee and a failed insert can leave partial writes.
`ArrowOptions.DEFAULT` rejects unsupported output types, materializes LowCardinality and
exports String as UTF-8. Both query forms accept an explicit `ArrowOptions` for binary
String output, dictionary LowCardinality and lossy unsupported-type output. DateTime
defaults to Arrow unsigned 32-bit seconds without timezone; use DateTime64 in SQL for
timestamp semantics.
`registerBatch(root, allocator)` adapts one current `VectorSchemaRoot` batch; the caller
retains ownership of the root and must not mutate or close it before unregistering.

The test `ArrowSessionTest` is opt-in (`-Dchdb.arrow.it=true`) and requires a matching
engine and JNI shim in the directory given by `-Dchdb.library.path`. The previously
published Java `1.0.0-rc.2` platform JAR has JNI ABI 2 and cannot run this work-in-progress
ABI 3 module. Arrow Java 19.0.0 on classpath also requires
`--add-opens=java.base/java.nio=ALL-UNNAMED` on supported JDKs.

The current source pins chDB core `26.11.0-rc.3`. For a macOS arm64 release-asset
smoke test, compile the Java side (`mvn -pl chdb-jdbc -am compile`), then run
`scripts/build-native.sh macos-aarch64`. That script downloads the exact rc.3 asset,
verifies its SHA-256 and stages the engine plus JNI shim in
`chdb-native-macos-aarch64/target/native/`. Run the opt-in test with the staged pair:

```sh
mvn -pl chdb-arrow -am test -Dchdb.arrow.it=true \
-Dchdb.library.path="$PWD/chdb-native-macos-aarch64/target/native/META-INF/chdb/native/macos/aarch64" \
-DargLine=--add-opens=java.base/java.nio=ALL-UNNAMED
```

The earlier core `26.11.0-rc.2` omitted a `get_schema` release during registration:
a value-correct Java scan left 148 bytes in the Arrow allocator. The rc.3 release
includes that fix, so **A1/A2/A5 tests are not skipped** on this baseline. One
separate regression for an unparseable String inserted into Int64 remains disabled
pending core investigation; it must not be reported as passing. CI exercises the
same suite on all four native platforms and Java 11/17/21/25 without a version
override. No production deployment should use a local `--local-engine` package or
`chdb.skipEngineVersionCheck`.
88 changes: 88 additions & 0 deletions chdb-arrow/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.clickhouse.chdb</groupId>
<artifactId>chdb-java-parent</artifactId>
<version>1.0.0-rc.3-SNAPSHOT</version>
</parent>
<artifactId>chdb-arrow</artifactId>
<name>chDB Arrow</name>
<description>Optional Apache Arrow Java integration for chDB.</description>
<dependencies>
<dependency>
<groupId>com.clickhouse.chdb</groupId>
<artifactId>chdb-jdbc</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-c-data</artifactId>
<version>${arrow.java.version}</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-vector</artifactId>
<version>${arrow.java.version}</version>
</dependency>
<dependency>
<groupId>org.apache.arrow</groupId>
<artifactId>arrow-memory-netty</artifactId>
<version>${arrow.java.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Automatic-Module-Name>org.chdb.arrow</Automatic-Module-Name>
<Implementation-Version>${project.version}</Implementation-Version>
<chDB-Engine-Version>${chdb.engine.version}</chDB-Engine-Version>
<chDB-JNI-ABI-Version>${chdb.jni.abi.version}</chDB-JNI-ABI-Version>
<Arrow-Java-Version>${arrow.java.version}</Arrow-Java-Version>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<executions>
<execution><id>attach-sources</id><goals><goal>jar-no-fork</goal></goals></execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<executions>
<execution><id>attach-javadocs</id><goals><goal>jar</goal></goals></execution>
</executions>
<configuration>
<doclint>all,-accessibility</doclint>
<quiet>true</quiet>
<notimestamp>true</notimestamp>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
27 changes: 27 additions & 0 deletions chdb-arrow/src/main/java/org/chdb/arrow/ArrowOptions.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package org.chdb.arrow;

/**
* Explicit core Arrow output type choices. Defaults reject unsupported types, materialize
* LowCardinality, and expose String as UTF-8. Alternative mappings can lose type fidelity;
* callers opt into them rather than silently changing JDBC or Arrow defaults.
*/
public final class ArrowOptions {
public static final ArrowOptions DEFAULT = new ArrowOptions(false, false, true);

private final boolean unsupportedAsBinary;
private final boolean lowCardinalityAsDictionary;
private final boolean stringAsString;

public ArrowOptions(boolean unsupportedAsBinary, boolean lowCardinalityAsDictionary,
boolean stringAsString) {
this.unsupportedAsBinary = unsupportedAsBinary;
this.lowCardinalityAsDictionary = lowCardinalityAsDictionary;
this.stringAsString = stringAsString;
}

int nativeFlags() {
return (unsupportedAsBinary ? 1 : 0)
| (lowCardinalityAsDictionary ? 2 : 0)
| (stringAsString ? 4 : 0);
}
}
Loading
Loading