Skip to content

Commit 084d34d

Browse files
Pandas886cursoragentsundy-li
authored
feat(query): paimon catalog support read and distributed write (#20132)
* feat(meta): add Paimon catalog metadata Co-authored-by: Cursor <cursoragent@cursor.com> * feat(query): parse Paimon catalogs Co-authored-by: Cursor <cursoragent@cursor.com> * feat(storage): implement read-only Paimon storage Add the Paimon storage crate with catalog and table scans, split serialization, predicate pushdown, Arrow sources, and integration tests. Co-authored-by: Cursor <cursoragent@cursor.com> * feat(query): register Paimon catalog and engine Integrate CatalogCreator, the storage factory, query context, and system.tables display. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(storage): finalize the Paimon core read plan Fix timestamp and predicate pushdown, reuse the catalog in sources, add pipeline and stateful tests, and reject CREATE TABLE for read-only catalogs. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): move read tests to service integration tests - Load each table only once per source and preserve LIMIT and residual filters. - Move pipeline and read tests to the databend-query service integration suite. - Add split round-trip serialization and credential redaction tests. - Use a local filesystem fixture for stateful tests. - Give each thread its own TestFixture, remove the paimon_it_lock deadlock, and execute DDL through execute_command. - Verify 8 service, 3 partition, and 2 security tests with UNIT_TEST=TRUE; formatting and clippy are clean. * fix(paimon): repair the local filesystem fixture The fixture had never completed successfully: - Configure PaimonSparkSessionExtensions as required by paimon-spark. - Provide only non-partition columns for the append_t static partition insert. - Define the pk_t primary key with the primary-key table property because Spark cannot parse inline PRIMARY KEY syntax. * test(paimon): make the stateful read test pass The suite had not been exercised successfully before this fix: - Make every shell script executable. - Redirect fixture output so Spark logs do not pollute stdout. - Use fully qualified paimon_fs.regression names because USE CATALOG does not persist across bendsql sessions. - Regenerate the 01_read result to match actual output. The official databend-test runner now verifies 01_0000_append_pk, including append scans, primary-key deduplication, projection/filter/limit pushdown, and read-only DDL rejection. The 00_catalog case still depends on a SHOW DATABASES bug, while 02_cluster requires a multi-node cluster. * fix(paimon): fix catalog SHOW DATABASES e2e test * style(paimon): format the catalog adapter * test(paimon): cover catalog SHOW TABLES * test(paimon): add stateful SHOW TABLES coverage * feat(storage): parse Paimon system tables * feat(storage): read basic Paimon system tables * feat(storage): read Paimon file metadata system tables * feat(storage): decode Paimon stats and keys as typed JSON * fix(storage): scan all partition files through the catalog * feat(storage): read Paimon size and index system tables * fix(storage): remove location conversion clippy warning * test(paimon): validate every system table column count * fix(storage): enable SQL reads from Paimon system tables Rebuild PaimonSystemTable from the system table name in get_table_by_info, lazily load the catalog and table from the TableInfo descriptor, and project blocks in the source according to the plan to fix ORDER BY column mismatches. * test(paimon): cover SQL reads from 11 system tables * style(paimon): format physical_files_size * test(paimon): fix multi-node cluster scan e2e test * feat(paimon): add fixed-bucket write routing Co-authored-by: Cursor <cursoragent@cursor.com> * feat(paimon): transmit commit messages across nodes Co-authored-by: Cursor <cursoragent@cursor.com> * feat(paimon): implement parallel writers and centralized commit Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): skip centralized commit after failures Co-authored-by: Cursor <cursoragent@cursor.com> * feat(paimon): integrate table writes and snapshot commits Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): improve unsupported write configuration errors Co-authored-by: Cursor <cursoragent@cursor.com> * feat(paimon): redistribute writes by partition and bucket Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): preserve Merge Exchange for centralized commit Co-authored-by: Cursor <cursoragent@cursor.com> * test(paimon): cover the preserved SELECT Merge path Co-authored-by: Cursor <cursoragent@cursor.com> * test(paimon): cover local filesystem writes Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): use a portable warehouse path Co-authored-by: Cursor <cursoragent@cursor.com> * test(paimon): cover parallel cluster writes Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): finalize distributed write validation Co-authored-by: Cursor <cursoragent@cursor.com> * fix(paimon): correct distributed write routing and validation * fix(paimon): address meta version, REST, and branch review issues - Add v180 to META_CHANGE_LOG and cover CatalogMeta compatibility. - Open tables through CatalogFactory to preserve rest_env. - Resolve system tables against branch metadata paths. * fix(paimon): strip quotes from dotted CONNECTION keys Quoted identifiers such as "s3.region" retained their quotes in option keys, preventing S3 FileIO from reading the region. Match Iceberg by stripping quotes while building catalogs and tables, and add an offline regression test. * ci: add Paimon MinIO integration validation * fix: correct the Paimon S3 warehouse path * fix: correct local Paimon MinIO validation * fix(query): resolve Paimon CI failures * fix(ci): isolate Paimon test dependencies * fix(ci): stabilize Paimon cluster tests * fix(query): harden Paimon system tables --------- Co-authored-by: Cursor <cursoragent@cursor.com> Co-authored-by: sundyli <543950155@qq.com>
1 parent cd4d095 commit 084d34d

107 files changed

Lines changed: 10662 additions & 64 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: "Test sqllogic Paimon"
2+
description: "Running Paimon sqllogic tests against MinIO"
3+
runs:
4+
using: "composite"
5+
steps:
6+
- uses: ./.github/actions/setup_test
7+
with:
8+
artifacts: sqllogictests,meta,query
9+
10+
- name: Setup uv
11+
uses: astral-sh/setup-uv@v7
12+
13+
- name: Prepare Paimon on MinIO
14+
shell: bash
15+
env:
16+
AWS_ACCESS_KEY_ID: admin
17+
AWS_SECRET_ACCESS_KEY: password
18+
AWS_EC2_METADATA_DISABLED: true
19+
PAIMON_WAREHOUSE: s3://paimon/warehouse
20+
PAIMON_S3_ENDPOINT: http://127.0.0.1:9002
21+
PAIMON_S3_ACCESS_KEY: admin
22+
PAIMON_S3_SECRET_KEY: password
23+
run: |
24+
docker compose -f tests/sqllogictests/scripts/docker-compose-paimon.yml up -d
25+
for i in $(seq 1 30); do
26+
curl -sf http://127.0.0.1:9002/minio/health/live && break
27+
echo "Waiting for MinIO... ($i)"
28+
sleep 2
29+
done
30+
curl -sf http://127.0.0.1:9002/minio/health/live
31+
aws --endpoint-url http://127.0.0.1:9002 s3 mb s3://paimon
32+
uv run --script tests/sqllogictests/scripts/prepare_paimon_fs_data.py
33+
# paimon-rust 0.2.0 checks directory paths as exact S3 keys.
34+
for path in regression.db regression.db/{write_append,write_append_part,write_pk,write_pk_part}; do
35+
aws --endpoint-url http://127.0.0.1:9002 s3api put-object \
36+
--bucket paimon --key "warehouse/${path}"
37+
done
38+
39+
- name: Run Paimon sqllogic tests
40+
shell: bash
41+
env:
42+
TEST_HANDLERS: http
43+
run: bash ./scripts/ci/ci-run-sqllogic-tests-without-sandbox.sh paimon
44+
45+
- name: Stop MinIO
46+
if: always()
47+
shell: bash
48+
run: docker compose -f tests/sqllogictests/scripts/docker-compose-paimon.yml down -v
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: "Test Stateful Paimon Cluster Linux"
2+
description: "Running Paimon stateful tests in cluster mode"
3+
runs:
4+
using: "composite"
5+
steps:
6+
- uses: ./.github/actions/setup_test
7+
8+
- uses: actions/setup-java@v5
9+
with:
10+
distribution: "temurin"
11+
java-version: "17"
12+
13+
- uses: astral-sh/setup-uv@v7
14+
15+
- name: Test setup
16+
shell: bash
17+
run: bash ./scripts/setup/dev_setup.sh -yd
18+
19+
- name: Run Paimon Stateful Tests with Cluster mode
20+
shell: bash
21+
run: bash ./scripts/ci/ci-run-stateful-paimon-tests-cluster.sh
22+
23+
- name: Upload failure
24+
if: failure()
25+
uses: ./.github/actions/artifact_failure
26+
with:
27+
name: test-stateful-paimon-cluster-linux

.github/workflows/reuse.linux.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,23 @@ jobs:
349349
- uses: ./.github/actions/test_stateless_cluster_linux
350350
timeout-minutes: 25
351351

352+
test_stateful_paimon_cluster:
353+
needs: [build, check]
354+
runs-on:
355+
- self-hosted
356+
- "${{ inputs.runner_arch }}"
357+
- Linux
358+
- 4c
359+
- "${{ inputs.runner_provider }}"
360+
steps:
361+
- uses: actions/checkout@v6
362+
- uses: ./.github/actions/setup_license
363+
with:
364+
runner_provider: ${{ inputs.runner_provider }}
365+
type: ${{ inputs.license_type }}
366+
- uses: ./.github/actions/test_stateful_paimon_cluster_linux
367+
timeout-minutes: 25
368+
352369
test_stateful_standalone:
353370
needs: [build, check]
354371
runs-on:

.github/workflows/reuse.sqllogic.yml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,27 @@ jobs:
244244
with:
245245
name: test-sqllogic-standalone-iceberg-tpch
246246

247+
standalone_paimon:
248+
runs-on:
249+
- self-hosted
250+
- ${{ inputs.runner_arch }}
251+
- Linux
252+
- 4c
253+
- "${{ inputs.runner_provider }}"
254+
steps:
255+
- uses: actions/checkout@v6
256+
- uses: actions/setup-java@v5
257+
with:
258+
distribution: "temurin"
259+
java-version: "17"
260+
- uses: ./.github/actions/test_sqllogic_paimon
261+
timeout-minutes: 15
262+
- name: Upload failure
263+
if: failure()
264+
uses: ./.github/actions/artifact_failure
265+
with:
266+
name: test-sqllogic-standalone-paimon
267+
247268
cluster:
248269
runs-on:
249270
- self-hosted

0 commit comments

Comments
 (0)