Skip to content

fix: keep set operations after subquery operands at the outer query #1169

fix: keep set operations after subquery operands at the outer query

fix: keep set operations after subquery operands at the outer query #1169

Workflow file for this run

name: Verify
on:
pull_request:
workflow_dispatch:
permissions:
contents: read
concurrency:
group: verify-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
changes:
name: Classify verification scope
runs-on: ubuntu-24.04
outputs:
checks: ${{ steps.scope.outputs.checks }}
duckdb: ${{ steps.scope.outputs.duckdb }}
postgres: ${{ steps.scope.outputs.postgres }}
performance: ${{ steps.scope.outputs.performance }}
format_performance: ${{ steps.scope.outputs.format_performance }}
rules_performance: ${{ steps.scope.outputs.rules_performance }}
wheels: ${{ steps.scope.outputs.wheels }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Select relevant suites
id: scope
env:
EVENT_NAME: ${{ github.event_name }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
run: |
write_scope() {
{
echo "duckdb=$1"
echo "postgres=$2"
echo "performance=$3"
echo "format_performance=$4"
echo "rules_performance=$5"
echo "checks=$6"
echo "wheels=$7"
} >> "${GITHUB_OUTPUT}"
}
if [[ "${EVENT_NAME}" != "pull_request" ]]; then
write_scope true true true true true true true
exit 0
fi
duckdb=false
postgres=false
performance=false
format_performance=false
rules_performance=false
wheels=false
broad=false
changed=false
# A change that only touches the website, root-level Markdown, the README demo GIFs or the
# skill pages generated from the website docs skips the Python checks and test suites.
# The website builds in its own workflow.
docs_only=true
while IFS= read -r -d '' path; do
changed=true
case "${path}" in
website/*|.github/workflows/website.yml|.github/demos/*) ;;
src/sqlbuild/.agents/skills/sqlbuild/references/docs/*.md) ;;
*/*) docs_only=false ;;
*.md) ;;
*) docs_only=false ;;
esac
case "${path}" in
crates/*|Cargo.toml|Cargo.lock|pyproject.toml|.github/workflows/verify.yml)
wheels=true
;;
esac
case "${path}" in
crates/*|Cargo.toml|Cargo.lock|pyproject.toml|uv.lock)
broad=true
performance=true
format_performance=true
rules_performance=true
;;
src/sqlbuild/compiler/*|src/sqlbuild/adapter/type_system/*)
broad=true
performance=true
rules_performance=true
;;
src/sqlbuild/cli/commands/_helpers/compile/*|src/sqlbuild/executor/testing/*|scripts/cold_compile_performance/*|scripts/compile_performance_ratio/*|scripts/compare_compile_performance.py|tests/e2e/src/sqlbuild/cli/commands/main/compile/*)
broad=true
performance=true
;;
src/sqlbuild/cli/commands/_helpers/lineage/*|src/sqlbuild/cli/commands/_helpers/plan/*|src/sqlbuild/cli/commands/_helpers/scope/*|src/sqlbuild/cli/commands/_helpers/build_planning/*|src/sqlbuild/cli/commands/main/inspection/*|src/sqlbuild/cli/commands/main/project/*|src/sqlbuild/cli/output/*|src/sqlbuild/executor/build/*|src/sqlbuild/executor/run/*|src/sqlbuild/presentation/*)
# Inspection, plan, and build guards run inside the fresh-process compile jobs.
broad=true
performance=true
;;
src/sqlbuild/rule_engine/*|src/sqlbuild/lint/*|scripts/rules_benchmark/*|scripts/benchmark_rules_ci.py|tests/performance/*)
broad=true
performance=true
format_performance=true
rules_performance=true
;;
tests/e2e/src/sqlbuild/cli/commands/main/format/*)
duckdb=true
format_performance=true
;;
tests/e2e/src/sqlbuild/cli/commands/main/postgres/*|tests/integration/src/sqlbuild/adapters/postgres/*|tests/integration/src/sqlbuild/runtime/execution_history/*)
postgres=true
;;
tests/e2e/*)
duckdb=true
;;
tests/unit/*|tests/integration/*)
;;
.github/workflows/verify.yml|Makefile)
performance=true
format_performance=true
rules_performance=true
;;
.github/*|docs/*|website/*|*.md|.gitignore|LICENSE)
;;
*)
broad=true
;;
esac
# Three dots: compare with the merge base, so changes that landed on main after the branch
# started are not counted as this pull request's changes.
done < <(git diff --name-only -z "${BASE_SHA}...${HEAD_SHA}")
if [[ "${changed}" != "true" ]]; then
write_scope true true true true true true true
exit 0
fi
checks=true
if [[ "${docs_only}" == "true" ]]; then
checks=false
fi
if [[ "${broad}" == "true" ]]; then
duckdb=true
postgres=true
format_performance=true
fi
write_scope \
"${duckdb}" \
"${postgres}" \
"${performance}" \
"${format_performance}" \
"${rules_performance}" \
"${checks}" \
"${wheels}"
lockfile:
name: Lockfile consistency
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Verify lockfile
run: uv lock --check --python 3.12
checks:
name: Static checks and unit + integration tests
needs: [changes, lockfile]
if: needs.changes.outputs.checks == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 30
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Run static checks
run: make check-ci
- name: Run native checks
run: make rust-check
- name: Run unit and integration tests
run: make test
e2e_shards:
name: DuckDB E2E (${{ matrix.name }})
needs: [changes, lockfile]
if: needs.changes.outputs.duckdb == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- name: build core
target: test-e2e-duckdb-build-core
- name: build incremental
target: test-e2e-duckdb-build-incremental
- name: CLI data
target: test-e2e-duckdb-cli-data
- name: CLI commands
target: test-e2e-duckdb-cli
- name: CLI inspection
target: test-e2e-duckdb-inspection
- name: integrations
target: test-e2e-duckdb-integrations
env:
PYTEST_XDIST_AUTO_NUM_WORKERS: "4"
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Report runner CPU topology
run: |
echo "nproc=$(nproc)"
echo "online_processors=$(getconf _NPROCESSORS_ONLN)"
lscpu
uv run python - <<'PY'
import os
print(f"os.cpu_count={os.cpu_count()}")
print(f"sched_getaffinity={sorted(os.sched_getaffinity(0))}")
print(
"PYTEST_XDIST_AUTO_NUM_WORKERS="
f"{os.environ.get('PYTEST_XDIST_AUTO_NUM_WORKERS', '<unset>')}"
)
PY
- name: Run DuckDB E2E shard
run: make ${{ matrix.target }}
format_performance:
name: Formatter performance guards
needs: [changes, lockfile]
if: needs.changes.outputs.format_performance == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 10
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras --python 3.12
- name: Run formatter performance guards
run: >-
uv run pytest
tests/e2e/src/sqlbuild/cli/commands/main/format/test_format_performance.py
-n auto --dist loadfile -m performance
performance:
name: Performance guards
needs: [changes, lockfile]
# Temporarily disabled while the Blacksmith runner allowance is unavailable.
# These budgets are calibrated for the 8-vCPU Blacksmith runner.
if: false
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Run performance guards
run: make test-e2e-performance
cold_compile_performance:
name: Fresh-process compile (${{ matrix.models }} models)
needs: [changes, lockfile]
if: needs.changes.outputs.performance == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
models: [3000, 5000, 10000]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Run fresh-process compile guard under 4 GiB
env:
BENCHMARK_MODELS: ${{ matrix.models }}
MEMORY_LIMIT_BYTES: "4294967296"
run: |
sudo systemd-run \
--unit="sqlbuild-cold-${BENCHMARK_MODELS}-${GITHUB_RUN_ID}" \
--uid="$(id -u)" \
--gid="$(id -g)" \
--same-dir \
--setenv="HOME=${HOME}" \
--setenv="PATH=${PATH}" \
--setenv="SQLBUILD_REQUIRE_MEMORY_LIMIT_BYTES=${MEMORY_LIMIT_BYTES}" \
--property="MemoryMax=${MEMORY_LIMIT_BYTES}" \
--property="MemorySwapMax=0" \
--wait \
--collect \
--pipe \
make test-e2e-cold-compile-performance \
SQLBUILD_BENCHMARK_MODELS="${BENCHMARK_MODELS}"
dense_compile_performance:
name: Dense all-rules compile (${{ matrix.models }} models)
needs: [changes, lockfile]
if: needs.changes.outputs.performance == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
models: [1000, 3000, 5000, 10000]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Run dense all-rules guard under 4 GiB
env:
BENCHMARK_MODELS: ${{ matrix.models }}
MEMORY_LIMIT_BYTES: "4294967296"
run: |
sudo systemd-run \
--unit="sqlbuild-dense-${BENCHMARK_MODELS}-${GITHUB_RUN_ID}" \
--uid="$(id -u)" \
--gid="$(id -g)" \
--same-dir \
--setenv="HOME=${HOME}" \
--setenv="PATH=${PATH}" \
--setenv="SQLBUILD_REQUIRE_MEMORY_LIMIT_BYTES=${MEMORY_LIMIT_BYTES}" \
--property="MemoryMax=${MEMORY_LIMIT_BYTES}" \
--property="MemorySwapMax=0" \
--wait \
--collect \
--pipe \
make test-e2e-dense-compile-performance \
SQLBUILD_BENCHMARK_MODELS="${BENCHMARK_MODELS}"
- name: Run diagnostic-heavy compile guards
if: matrix.models == 1000
run: make test-e2e-diagnostic-compile-performance
compile_performance_ratio:
name: Same-runner compile ratio (${{ matrix.kind }} 3000 models)
needs: [changes, lockfile]
if: needs.changes.outputs.performance == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
include:
- kind: dense
max_ratio: "1.10"
- kind: fresh
max_ratio: "1.10"
steps:
- uses: actions/checkout@v4
- name: Check out the comparison base
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.sha || 'main' }}
path: base
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
base/uv.lock
base/Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install head dependencies
run: uv sync --locked --all-groups --all-extras
- name: Install base dependencies
working-directory: base
run: uv sync --locked --all-extras
- name: Compare base and head cold compiles
env:
KIND: ${{ matrix.kind }}
MAX_RATIO: ${{ matrix.max_ratio }}
run: |
uv run python -m scripts.compare_compile_performance \
--kind "${KIND}" \
--max-ratio "${MAX_RATIO}" \
--models 3000 \
--base-python base/.venv/bin/python \
--head-python .venv/bin/python
cache_compile_performance:
name: Fresh-process compile cache (${{ matrix.models }} models)
needs: [changes, lockfile]
if: needs.changes.outputs.performance == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 15
strategy:
fail-fast: false
matrix:
models: [3000, 5000, 10000]
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Run fresh-process compile cache guard under 4 GiB
env:
BENCHMARK_MODELS: ${{ matrix.models }}
MEMORY_LIMIT_BYTES: "4294967296"
run: |
sudo systemd-run \
--unit="sqlbuild-cache-${BENCHMARK_MODELS}-${GITHUB_RUN_ID}" \
--uid="$(id -u)" \
--gid="$(id -g)" \
--same-dir \
--setenv="HOME=${HOME}" \
--setenv="PATH=${PATH}" \
--setenv="SQLBUILD_REQUIRE_MEMORY_LIMIT_BYTES=${MEMORY_LIMIT_BYTES}" \
--property="MemoryMax=${MEMORY_LIMIT_BYTES}" \
--property="MemorySwapMax=0" \
--wait \
--collect \
--pipe \
make test-e2e-cache-compile-performance \
SQLBUILD_BENCHMARK_MODELS="${BENCHMARK_MODELS}"
- name: Run varied 1k warm-cache guard under 4 GiB
if: matrix.models == 3000
env:
MEMORY_LIMIT_BYTES: "4294967296"
run: |
sudo systemd-run \
--unit="sqlbuild-varied-cache-${GITHUB_RUN_ID}" \
--uid="$(id -u)" \
--gid="$(id -g)" \
--same-dir \
--setenv="HOME=${HOME}" \
--setenv="PATH=${PATH}" \
--setenv="SQLBUILD_REQUIRE_MEMORY_LIMIT_BYTES=${MEMORY_LIMIT_BYTES}" \
--property="MemoryMax=${MEMORY_LIMIT_BYTES}" \
--property="MemorySwapMax=0" \
--wait \
--collect \
--pipe \
make test-e2e-varied-cache-performance
rules_performance:
name: Rules performance guards
needs: [changes, lockfile]
# Temporarily disabled while the Blacksmith runner allowance is unavailable.
# These budgets are calibrated for the 8-vCPU Blacksmith runner.
if: false
runs-on: ubuntu-24.04
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Run required Rules performance profile
timeout-minutes: 10
run: >-
uv run python -m scripts.benchmark_rules_ci
--output "${RUNNER_TEMP}/rules-performance-ci.json"
--summary-output "${RUNNER_TEMP}/rules-performance-ci.md"
--max-seconds 420
- name: Publish benchmark summary
if: always()
run: |
if [[ -f "${RUNNER_TEMP}/rules-performance-ci.md" ]]; then
cat "${RUNNER_TEMP}/rules-performance-ci.md" >> "${GITHUB_STEP_SUMMARY}"
fi
- name: Upload benchmark evidence
if: always()
uses: actions/upload-artifact@v4
with:
name: rules-performance-${{ github.run_id }}-${{ github.run_attempt }}
path: |
${{ runner.temp }}/rules-performance-ci.json
${{ runner.temp }}/rules-performance-ci.md
if-no-files-found: error
retention-days: 90
postgres:
name: PostgreSQL integration and E2E tests
needs: [changes, lockfile]
if: needs.changes.outputs.postgres == 'true'
runs-on: ubuntu-24.04
timeout-minutes: 45
steps:
- uses: actions/checkout@v4
- uses: astral-sh/setup-uv@v5
with:
version: "0.12.3"
enable-cache: true
cache-dependency-glob: |
uv.lock
Cargo.lock
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- name: Install Python
run: uv python install 3.12
- name: Install dependencies
run: uv sync --locked --all-groups --all-extras
- name: Verify Docker
run: docker info
- name: Run PostgreSQL tests
env:
PYTHONUNBUFFERED: "1"
TESTCONTAINERS_RYUK_DISABLED: "true"
run: >-
uv run pytest tests
-m "real_warehouse and postgres"
-vv --color=yes -n auto --dist loadfile
wheels:
# Keep the platform matrix and maturin settings in sync with publish.yml.
name: Build wheel (${{ matrix.platform.name }})
needs: [changes]
if: needs.changes.outputs.wheels == 'true'
runs-on: ${{ matrix.platform.runner }}
timeout-minutes: 45
strategy:
fail-fast: false
matrix:
platform:
- name: linux-x86_64
runner: ubuntu-24.04
target: x86_64
- name: linux-aarch64
runner: ubuntu-24.04-arm
target: aarch64
- name: macos-x86_64
runner: macos-15-intel
target: x86_64
- name: macos-arm64
runner: macos-15
target: aarch64
- name: windows-x86_64
runner: windows-2025
target: x86_64
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.12"
- uses: dtolnay/rust-toolchain@master
with:
toolchain: stable
- uses: PyO3/maturin-action@v1
with:
command: build
args: --release --out dist --features extension-module
target: ${{ matrix.platform.target }}
manylinux: auto
- name: Smoke import the native extension from the built wheel
shell: bash
run: |
python -m venv "${RUNNER_TEMP}/wheel-smoke"
if [[ -x "${RUNNER_TEMP}/wheel-smoke/Scripts/python.exe" ]]; then
smoke_python="${RUNNER_TEMP}/wheel-smoke/Scripts/python.exe"
else
smoke_python="${RUNNER_TEMP}/wheel-smoke/bin/python"
fi
"${smoke_python}" -m pip install --no-deps dist/*.whl
cd "${RUNNER_TEMP}"
"${smoke_python}" -c "import sqlbuild._native"
verify:
name: Verify
if: always()
needs:
[
changes,
lockfile,
checks,
e2e_shards,
format_performance,
performance,
cold_compile_performance,
dense_compile_performance,
compile_performance_ratio,
cache_compile_performance,
rules_performance,
postgres,
wheels,
]
runs-on: ubuntu-24.04
steps:
- name: Confirm all required verification jobs passed
env:
CHANGES_RESULT: ${{ needs.changes.result }}
CHECKS_SELECTED: ${{ needs.changes.outputs.checks }}
LOCKFILE_RESULT: ${{ needs.lockfile.result }}
CHECKS_RESULT: ${{ needs.checks.result }}
E2E_SHARDS_RESULT: ${{ needs.e2e_shards.result }}
FORMAT_PERFORMANCE_RESULT: ${{ needs.format_performance.result }}
PERFORMANCE_RESULT: ${{ needs.performance.result }}
COLD_COMPILE_PERFORMANCE_RESULT: ${{ needs.cold_compile_performance.result }}
DENSE_COMPILE_PERFORMANCE_RESULT: ${{ needs.dense_compile_performance.result }}
COMPILE_PERFORMANCE_RATIO_RESULT: ${{ needs.compile_performance_ratio.result }}
CACHE_COMPILE_PERFORMANCE_RESULT: ${{ needs.cache_compile_performance.result }}
RULES_PERFORMANCE_RESULT: ${{ needs.rules_performance.result }}
POSTGRES_RESULT: ${{ needs.postgres.result }}
WHEELS_RESULT: ${{ needs.wheels.result }}
run: |
if [[ "${CHANGES_RESULT}" != "success" || "${LOCKFILE_RESULT}" != "success" ]]; then
echo "Required classification or lockfile checks did not pass" >&2
exit 1
fi
if [[ "${CHECKS_RESULT}" != "success" ]] && \
! [[ "${CHECKS_SELECTED}" == "false" && "${CHECKS_RESULT}" == "skipped" ]]; then
echo "Required static checks did not pass: ${CHECKS_RESULT}" >&2
exit 1
fi
for result in \
"${E2E_SHARDS_RESULT}" \
"${FORMAT_PERFORMANCE_RESULT}" \
"${PERFORMANCE_RESULT}" \
"${COLD_COMPILE_PERFORMANCE_RESULT}" \
"${DENSE_COMPILE_PERFORMANCE_RESULT}" \
"${COMPILE_PERFORMANCE_RATIO_RESULT}" \
"${CACHE_COMPILE_PERFORMANCE_RESULT}" \
"${RULES_PERFORMANCE_RESULT}" \
"${POSTGRES_RESULT}" \
"${WHEELS_RESULT}"; do
if [[ "${result}" != "success" && "${result}" != "skipped" ]]; then
echo "A selected verification suite did not pass: ${result}" >&2
exit 1
fi
done
echo "All path-relevant verification jobs passed"