Skip to content
Merged
Show file tree
Hide file tree
Changes from 38 commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
60462fd
V2 Refactoring (fixes #111)
kratz00 Oct 29, 2026
41d32c2
Differentiate CallMessageBuilder
kratz00 Oct 30, 2026
2f1c66f
Fixed clang-tidy findings
kratz00 Oct 30, 2026
d01348a
Renamed method 'create_call_message_builder'
kratz00 Oct 30, 2026
21c2991
Improved documentation builders and stream id relationship
kratz00 Oct 30, 2026
ff1d6d9
Sonar fixes.
kratz00 Oct 30, 2026
dbaab10
Increased test coverage
kratz00 Oct 30, 2026
5166eb4
Simplified error handling
kratz00 Oct 30, 2026
943d509
#111: Simplify v2 message view APIs
tkilias Oct 31, 2026
bd6ff17
#111: Split reset from send budget
tkilias Oct 31, 2026
477df79
#111: Expose builder messages directly
tkilias Oct 31, 2026
2abe251
#111: Retain control capabilities and payloads
tkilias Oct 31, 2026
7506096
#111: Document host Bazel cache fallback
tkilias Oct 31, 2026
65eb55b
#111: Increase development VM resources
tkilias Oct 31, 2026
78f3f5e
#111: Encapsulate control message
tkilias Oct 31, 2026
dd5b37e
#111: Split message content types
tkilias Oct 31, 2026
3b722e9
#111: Retain call payloads
tkilias Oct 31, 2026
80a3156
#111: Ignore v2 Bazel caches
tkilias Oct 31, 2026
2fc1f2f
#111: Encapsulate schema and record batch state
tkilias Oct 31, 2026
ac1108c
#111: Make data views abstract
tkilias Oct 31, 2026
13c2709
#111: Encapsulate remaining message structs
tkilias Oct 31, 2026
2dfdd5f
#111: Fix Mull installation in Lima template
tkilias Oct 31, 2026
55617c6
#111: Resolve open PR review comments
tkilias Nov 1, 2026
7f75e9b
#111: Add parallel v2 sanitizer test sessions
tkilias Nov 1, 2026
7f44518
#111: Add parallel v2 quality check sessions
tkilias Nov 1, 2026
e631798
#111: Fix v2 CI tool setup
tkilias Nov 1, 2026
bbb8bcd
#111: Fix remaining v2 CI checks
tkilias Nov 1, 2026
6620a13
#111: Split v1 and v2 Bazel workflows
tkilias Nov 1, 2026
d1420ab
#111: Fix remaining PR checks
tkilias Nov 2, 2026
bc210f5
#111: Fix Sonar escape sequence findings
tkilias Nov 2, 2026
5471239
Updated docs + diagrams and added stream id getters to the msg views
kratz00 Nov 2, 2026
0a484e7
Made stream_id() optional, like the other api calls
kratz00 Nov 2, 2026
e40cb07
clang format fixes
kratz00 Nov 2, 2026
5c34b7f
Added missing includes
kratz00 Nov 2, 2026
a0fa74f
Updated send() calls - only move if the send() was accepted
kratz00 Nov 2, 2026
17762c3
Fixed Sonar findings
kratz00 Nov 2, 2026
d6895c9
Made stream_id 'required'
kratz00 Nov 3, 2026
6ef2c47
Fixed exception usage
kratz00 Nov 3, 2026
e2b07aa
Rollback stream_id stays a scalar
kratz00 Nov 4, 2026
40f6855
Added tests (decodedFrame = nullptr)
kratz00 Nov 4, 2026
1c3f856
Merge remote-tracking branch 'origin/main' into feature/refactoring_c…
kratz00 Nov 4, 2026
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
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: Check Bazel Tests
name: Check Bazel Tests v1

on:
push:
Expand All @@ -18,71 +18,6 @@ env:
ZMQ_LIBRARY_PREFIX: /usr/lib/x86_64-linux-gnu
ZMQ_INCLUDE_PREFIX: /usr/include
jobs:
v2:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang curl lcov
- uses: bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86 # 0.19.0
with:
bazelisk-cache: true
- name: Build
run: bazel build --verbose_failures //...
working-directory: ./udf-runner-cpp/v2
- name: Install clang-tidy
run: |
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -- 22
sudo apt-get install -y clang-tidy-22
- name: Run clang-tidy
run: bazel build --verbose_failures --config clang-tidy //...
working-directory: ./udf-runner-cpp/v2
- name: Install clang-format
run: |
sudo apt-get install -y clang-format-22
sudo ln -sf /usr/bin/clang-format-22 /usr/local/bin/clang-format
- name: Run clang-format
run: bazel build --verbose_failures --config clang-format //...
working-directory: ./udf-runner-cpp/v2
- name: Run v2 fuzz regression tests
run: |
bazel test --verbose_failures --test_output=errors --config asan-libfuzzer \
//:frame_fuzz_test \
//:call_metadata_fuzz_test \
//:connection_information_fuzz_test \
//:export_specification_fuzz_test \
//:import_specification_fuzz_test \
//:queue_fuzz_test
working-directory: ./udf-runner-cpp/v2
- name: Run tests
run: >-
bazel test --verbose_failures --test_output=errors
--build_tag_filters=-fuzz-test
--test_tag_filters=-fuzz-test
//...
working-directory: ./udf-runner-cpp/v2
- name: Run coverage tests
run: >-
bazel test --verbose_failures --collect_code_coverage
--combined_report=lcov
--coverage_report_generator=@bazel_sonarqube//:sonarqube_coverage_generator
--build_tag_filters=-fuzz-test
--test_tag_filters=-fuzz-test,-no-coverage
//...
working-directory: ./udf-runner-cpp/v2
- name: SonarCloud Scan
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1
with:
projectBaseDir: ./udf-runner-cpp/v2
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

build:
runs-on: ubuntu-24.04
steps:
Expand Down Expand Up @@ -162,3 +97,5 @@ jobs:
with:
name: "${{ matrix.name }}"
path: /home/runner/.cache/bazel/_bazel_runner/*/execroot/_main/bazel-out/k8-dbg/testlogs/**/test.log


176 changes: 176 additions & 0 deletions .github/workflows/check_bazel_tests_v2.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
name: Check Bazel Tests v2

on:
push:
branches:
- main
pull_request:

permissions:
contents: read

env:
USE_BAZEL_VERSION: 8.8.2
jobs:
v2:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang curl lcov
- uses: bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86 # 0.19.0
with:
bazelisk-cache: true
- name: Build
run: bazel build --verbose_failures //...
working-directory: ./udf-runner-cpp/v2
- name: Run v2 fuzz regression tests
run: |
bazel test --verbose_failures --test_output=errors --config asan-libfuzzer \
//:frame_fuzz_test \
//:call_metadata_fuzz_test \
//:connection_information_fuzz_test \
//:export_specification_fuzz_test \
//:import_specification_fuzz_test \
//:queue_fuzz_test
working-directory: ./udf-runner-cpp/v2
- name: Run tests
run: >-
bazel test --verbose_failures --test_output=errors
--build_tag_filters=-fuzz-test
--test_tag_filters=-fuzz-test
//...
working-directory: ./udf-runner-cpp/v2

v2_clang_tidy:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang curl
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -- 22
sudo apt-get install -y clang-tidy-22
- name: Install Poetry dependencies
run: |
pipx install poetry
poetry install --no-interaction --no-ansi --only main
- uses: bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86 # 0.19.0
with:
bazelisk-cache: true
- name: Run clang-tidy
run: poetry run nox -s v2-clang-tidy

v2_clang_format:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang curl
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -- 22
sudo apt-get install -y clang-format-22
sudo ln -sf /usr/bin/clang-format-22 /usr/local/bin/clang-format
- name: Install Poetry dependencies
run: |
pipx install poetry
poetry install --no-interaction --no-ansi --only main
- uses: bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86 # 0.19.0
with:
bazelisk-cache: true
- name: Run clang-format
run: poetry run nox -s v2-clang-format

v2_coverage:
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang curl lcov
- name: Install Poetry dependencies
run: |
pipx install poetry
poetry install --no-interaction --no-ansi --only main
- uses: bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86 # 0.19.0
with:
bazelisk-cache: true
- name: Run coverage
run: poetry run nox -s v2-coverage
- name: Upload Sonar coverage report
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: v2-sonar-coverage
path: udf-runner-cpp/v2/bazel-out/_coverage/_coverage_report.dat
if-no-files-found: error

v2_sonar:
needs: v2_coverage
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
fetch-depth: 0
persist-credentials: false
- name: Download Sonar coverage report
uses: actions/download-artifact@95815c38cf2ff2164869cbab79da8d1f422bc89e # v4.2.1
with:
name: v2-sonar-coverage
path: udf-runner-cpp/v2/bazel-out/_coverage
- name: SonarCloud Scan
uses: SonarSource/sonarqube-scan-action@22918119ff8e1ca75a623e15c8296b6ea4fbe28f # v8.2.1
with:
projectBaseDir: ./udf-runner-cpp/v2
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}

v2_sanitizers:
strategy:
fail-fast: false
matrix:
include:
- name: asan
session: v2-tests-asan
- name: ubsan
session: v2-tests-ubsan
- name: valgrind
session: v2-tests-valgrind
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential clang curl valgrind
sudo bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)" -- 22
sudo apt-get install -y clang-22 libclang-rt-22-dev
sudo ln -sf /usr/bin/clang-22 /usr/local/bin/clang
sudo ln -sf /usr/bin/clang++-22 /usr/local/bin/clang++
- name: Install Poetry dependencies
run: |
pipx install poetry
poetry install --no-interaction --no-ansi --only main
- uses: bazel-contrib/setup-bazel@c5acdfb288317d0b5c0bbd7a396a3dc868bb0f86 # 0.19.0
with:
bazelisk-cache: true
- name: Run ${{ matrix.name }} tests
run: poetry run nox --sessions=${{ matrix.session }}


3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ dist
*.swp
MODULE.bazel.lock
bazel-*
/udf-runner-cpp/v2/.bazel-output-root/
/udf-runner-cpp/v2/.bazel-repository-cache/
/udf-runner-cpp/v2/.bazelisk/
/udf-runner-cpp/v2/coverage-html/
.serena
# CLion IDE
Expand Down
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,14 @@ unreleased changelog, so update it before the PR is merged.

## Tool availability and Lima

- When Bazel is available on the host but its default cache is not writable,
keep its caches in the workspace instead of using the VM:

```bash
bazel --output_user_root="$PWD/.bazel-output-root" \
--repository_cache="$PWD/.bazel-repository-cache" <command>
```

- When a required development tool is unavailable on the host, use the
repository's `udf-runner-cpp-dev` Lima VM instead of installing a host-wide
package.
Expand Down
7 changes: 7 additions & 0 deletions doc/changes/unreleased.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,17 @@ n/a

## Refactorings

* #111: Simplified v2 message-view presence APIs, split flow-control reset from send budget, removed builder encoding views, and retained control capabilities and call/control payloads in builder messages
* #44: Extracted WaitableQueue eventfd notifications into a reusable component

## Internal

* #111: Added parallel v2 regular-test Nox and CI runs for ASan, UBSan, and Valgrind
* #111: Added independent Nox and CI jobs for v2 clang-tidy, clang-format, coverage, and Sonar analysis
* #111: Split v1 and v2 Bazel checks into dedicated CI workflows
* #111: Fixed v1 CI to select Bazel 8.8.2 and resolved new Sonar ownership and escape-sequence findings
* #111: Fixed Lima Mull provisioning by installing the pinned LLVM 22 package
directly from its verified release artifact
* #70: Removed the standalone JSON schema validation script and its dedicated CI workflow
* #60: Added Mull mutation testing workflow and report-viewing documentation
for v2; targets without generated mutants now produce warnings instead of
Expand Down
6 changes: 3 additions & 3 deletions doc/design/v2/protocol/design_draft.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ The new UDF protocol should satisfy the following requirements.
- Support metadata exchange for protocol, script, call, and callback interactions.
- Support DB callback operations such as connection lookup, script lookup, and query execution.
- Support multiple logical streams per physical connection, with total ordering within a stream and partial ordering across streams.
- Support flow-controlled table transfer with explicit request semantics such as `Next(...)`.
- Support flow-controlled table transfer with explicit send budgets and reset requests.

### Performance Requirements

Expand Down Expand Up @@ -145,7 +145,7 @@ Exasol should introduce a new UDF protocol with the following high-level propert
- `DB` acts as the client and `UDFRunner` acts as the server.
- The protocol supports `Run`, `Function`, and `Script` call types.
- The protocol supports multiple logical streams with partial ordering across streams and total ordering within each stream.
- Table transfer is explicitly flow controlled, with `Next(...)`-style requests authorizing batch transfer.
- Table transfer is explicitly flow controlled, with send budgets authorizing batch transfer.
- The protocol supports callback interactions from `UDFRunner` to `DB`, including connection lookup, script lookup, and query execution.
- The protocol includes `ServerCapabilities`, framing, stream identifiers, and keepalive behavior.

Expand Down Expand Up @@ -199,7 +199,7 @@ The current technical direction from the repo material is:
- a connection-scoped `stream_id` model where `0` is the per-connection control stream, odd/even ownership is assigned to the generic Client and Server roles, and IDs are not reused per connection
- composite `StreamMessage` fields so related control data, such as a close and `Error`, can share one frame
- unilateral `CloseCall` and two-way `CloseConnection` termination, with `Error` indicating abnormal closure
- explicit control messages for metadata, start/call behavior, `Next`, data, callbacks, and heartbeat
- explicit control messages for metadata, start/call behavior, send budgets, reset, data, callbacks, and heartbeat
- table transfer based on Arrow-compatible batch metadata plus inline buffers on all bindings; Unix FD handoff is optional

Detailed technical design is still required for optional Unix FD handoff and final message-format decisions.
Expand Down
8 changes: 4 additions & 4 deletions doc/design/v2/protocol/high_level/calls.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ are ignored. Calls that have no result payload may still close normally.
- uses `call_metadata` and `column_metadata`, sent before any call, between calls, or with the opening message
- may carry the first input batch together with the opening message
- may stay active while nested calls such as `get_script` or `get_connection` execute
- group and row correlation belong in the data, not in `Next(...)`
- group and row correlation belong in the data, not in `Reset(...)`

See [Group and Row Correlation](correlation.md).

Expand Down Expand Up @@ -121,16 +121,16 @@ call orchestration and do not alter the generic Client/Server stream rules in th

1. run socket handling and user-code execution as independently wakeable activities
2. wait for either DB socket activity or user-code activity; do not block solely on socket receive
3. queue record batches produced by user code until the first-batch rule or a usable `Next(...)` byte budget permits emission
4. use `Next(...)` byte budgets to bound data in flight; do not impose a message-count limit
3. queue record batches produced by user code until the first-batch rule or a usable send budget permits emission
4. use send budgets to bound data in flight; do not impose a message-count limit
5. send regular `KeepAlive` messages so `DB` can continue housekeeping

### `DB`

1. prioritize nested-call responses before data-stream work
2. receive and process record batches from `UDFRunner` as a distinct data-stream event; the first batch may accompany
call-opening/control traffic
3. queue DB-produced input batches until the first-batch rule or a usable `Next(...)` byte budget permits emission
3. queue DB-produced input batches until the first-batch rule or a usable send budget permits emission
4. if nothing is ready to send, block waiting for new incoming messages
5. monitor peer liveness and terminate unhealthy sessions when needed
6. optionally open `cleanup` between calls and wait for its `CloseCall` before starting the next call
Expand Down
2 changes: 1 addition & 1 deletion doc/design/v2/protocol/high_level/endpoint_scheduling.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ stateDiagram-v2
UdfInitializing --> UdfActive: Capabilities
UdfActive --> UdfWaitingForActivity: Wait for DB or user code
UdfWaitingForActivity --> UdfOutputReady: User-code output ready
UdfOutputReady --> UdfSendingData: First batch or Next credit
UdfOutputReady --> UdfSendingData: First batch or send budget
UdfSendingData --> UdfActive: Transfer done
UdfWaitingForActivity --> UdfActive: Socket or non-output user-code event
}
Expand Down
4 changes: 2 additions & 2 deletions doc/design/v2/protocol/high_level/run_sequence.mmd
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ sequenceDiagram
Note over DB,UDFRunner: Run call opened by DB with flow-controlled bidirectional data exchange

DB->>UDFRunner: CallOpen(Run) + Payloads(call_metadata) + DataSchema(group ID, row ID) + first input RecordBatch
UDFRunner-->>DB: Next(byte_budget, reset=false, row_id=n)
UDFRunner-->>DB: next_send_budget_in_bytes
DB-->>UDFRunner: RecordBatch(group ID, row ID, input rows starting at n, is_end_of_group=true)
UDFRunner-->>DB: DataSchema(group ID, row ID) + first output RecordBatch
DB->>UDFRunner: Next(byte_budget, reset=false, row_id=m)
DB->>UDFRunner: next_send_budget_in_bytes
UDFRunner-->>DB: RecordBatch(group ID, row ID, output rows starting at m, is_end_of_group=true)
DB->>UDFRunner: CallClose(Run)
Loading
Loading