Skip to content

Commit 7078ef7

Browse files
authored
Merge branch 'main' into dev/chao/codex/skip-intermediate-replay-headroom
2 parents ede48fc + 714956b commit 7078ef7

125 files changed

Lines changed: 6970 additions & 2033 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.

.github/workflows/large_files.yml

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,6 @@ jobs:
3636
with:
3737
fetch-depth: 0
3838
- name: Check size of new Git objects
39-
env:
40-
# 1.5 MB ought to be enough for anybody.
41-
# TODO in case we may want to consciously commit a bigger file to the repo without using Git LFS we may disable the check e.g. with a label
42-
MAX_FILE_SIZE_BYTES: 1572864
4339
shell: bash
4440
run: |
4541
if [ "${{ github.event_name }}" = "merge_group" ]; then
@@ -51,18 +47,4 @@ jobs:
5147
base_sha="${{ github.event.pull_request.base.sha }}"
5248
head_sha="${{ github.event.pull_request.head.sha }}"
5349
fi
54-
git rev-list --objects ${base_sha}..${head_sha} \
55-
> pull-request-objects.txt
56-
exit_code=0
57-
while read -r id path; do
58-
# Skip objects which are not files (commits, trees)
59-
if [ ! -z "${path}" ]; then
60-
size="$(git cat-file -s "${id}")"
61-
if [ "${size}" -gt "${MAX_FILE_SIZE_BYTES}" ]; then
62-
exit_code=1
63-
echo "Object ${id} [${path}] has size ${size}, exceeding ${MAX_FILE_SIZE_BYTES} limit." >&2
64-
echo "::error file=${path}::File ${path} has size ${size}, exceeding ${MAX_FILE_SIZE_BYTES} limit."
65-
fi
66-
fi
67-
done < pull-request-objects.txt
68-
exit "${exit_code}"
50+
./ci/scripts/check_large_files.sh --base "${base_sha}" --head "${head_sha}"

.github/workflows/rust.yml

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -855,15 +855,9 @@ jobs:
855855
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
856856
with:
857857
node-version: "20"
858-
- name: Check if configs.md has been modified
858+
- name: Check generated config and function docs
859859
run: |
860-
# If you encounter an error, run './dev/update_config_docs.sh' and commit
861-
./dev/update_config_docs.sh
862-
git diff --exit-code
863-
- name: Check if any of the ***_functions.md has been modified
864-
run: |
865-
# If you encounter an error, run './dev/update_function_docs.sh' and commit
866-
./dev/update_function_docs.sh
860+
./ci/scripts/check_generated_docs.sh
867861
git diff --exit-code
868862
869863
# This job ensures `datafusion-examples/README.md` stays in sync with the source code:

Cargo.lock

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

benchmarks/sql_benchmarks/null_aware_join/benchmarks/q05.benchmark

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ group null_aware_join
33

44
load sql_benchmarks/null_aware_join/init/load.sql
55

6+
# Correctness canary: the NOT IN result must match a reference count
7+
# that does not use NOT IN. It holds for every NAJ_ROWS / NAJ_LARGE_ROWS.
8+
# As Q04, with NULL outer keys excluded unless the subquery is empty.
9+
assert I
10+
SELECT count(*) = (
11+
SELECT count(*) FROM small_outer o
12+
WHERE o.z <= (SELECT min(z) FROM small_inner)
13+
OR (o.id_n1 IS NOT NULL AND NOT (o.id % 2 = 0 AND (o.id / 2) % 1000 < o.z))
14+
)
15+
FROM small_outer o
16+
WHERE o.id_n1 NOT IN (SELECT i.id_n0 FROM small_inner i WHERE i.z < o.z);
17+
----
18+
# Pinned to today's behaviour, which is incorrect. See
19+
# https://github.com/apache/datafusion/issues/25336 -- the fix flips this.
20+
false
21+
622
expect_plan HashJoinExec
723
expect_plan null_aware
824

benchmarks/sql_benchmarks/null_aware_join/benchmarks/q06.benchmark

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,22 @@ group null_aware_join
33

44
load sql_benchmarks/null_aware_join/init/load.sql
55

6+
# Correctness canary: the NOT IN result must match a reference count
7+
# that does not use NOT IN. It holds for every NAJ_ROWS / NAJ_LARGE_ROWS.
8+
# As Q04, with NULL outer keys excluded unless the subquery is empty.
9+
assert I
10+
SELECT count(*) = (
11+
SELECT count(*) FROM small_outer o
12+
WHERE o.z <= (SELECT min(z) FROM small_inner)
13+
OR (o.id_n50 IS NOT NULL AND NOT (o.id % 2 = 0 AND (o.id / 2) % 1000 < o.z))
14+
)
15+
FROM small_outer o
16+
WHERE o.id_n50 NOT IN (SELECT i.id_n0 FROM small_inner i WHERE i.z < o.z);
17+
----
18+
# Pinned to today's behaviour, which is incorrect. See
19+
# https://github.com/apache/datafusion/issues/25336 -- the fix flips this.
20+
false
21+
622
expect_plan HashJoinExec
723
expect_plan null_aware
824

benchmarks/sql_benchmarks/null_aware_join/benchmarks/q07.benchmark

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,24 @@ group null_aware_join
33

44
load sql_benchmarks/null_aware_join/init/load.sql
55

6+
# Correctness canary: the NOT IN result must match a reference count
7+
# that does not use NOT IN. It holds for every NAJ_ROWS / NAJ_LARGE_ROWS.
8+
# A row is TRUE when the subquery is empty, or when the subquery holds no NULL
9+
# and the key is not in it. A NULL is in scope when its z is below o.z.
10+
assert I
11+
SELECT count(*) = (
12+
SELECT count(*) FROM small_outer o
13+
WHERE o.z <= (SELECT min(z) FROM small_inner)
14+
OR (o.z <= (SELECT min(z) FROM small_inner WHERE id_n50 IS NULL)
15+
AND NOT (o.id % 2 = 0 AND (o.id / 2) % 1000 < o.z))
16+
)
17+
FROM small_outer o
18+
WHERE o.id_n0 NOT IN (SELECT i.id_n50 FROM small_inner i WHERE i.z < o.z);
19+
----
20+
# Pinned to today's behaviour, which is incorrect. See
21+
# https://github.com/apache/datafusion/issues/25336 -- the fix flips this.
22+
false
23+
624
expect_plan HashJoinExec
725
expect_plan null_aware
826

benchmarks/sql_benchmarks/null_aware_join/benchmarks/q08.benchmark

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,30 @@ group null_aware_join
33

44
load sql_benchmarks/null_aware_join/init/load.sql
55

6+
# Correctness canary: the NOT IN result must match a reference count
7+
# that does not use NOT IN. It holds for every NAJ_ROWS / NAJ_LARGE_ROWS.
8+
# A row is TRUE when o.z > 900, when the subquery for its k is empty, or when
9+
# its key is not NULL and not in that subquery.
10+
assert I
11+
SELECT count(*) = (
12+
SELECT count(*)
13+
FROM small_outer o
14+
JOIN (SELECT k, min(z) AS min_z FROM small_inner GROUP BY k) m ON m.k = o.k
15+
WHERE o.z > 900
16+
OR o.z <= m.min_z
17+
OR (o.id_n50 IS NOT NULL
18+
AND NOT (o.id % 2 = 0 AND (o.id / 2) % 16 = o.k AND (o.id / 2) % 1000 < o.z))
19+
)
20+
FROM small_outer o
21+
WHERE o.z > 900
22+
OR o.id_n50 NOT IN (
23+
SELECT i.id_n0 FROM small_inner i WHERE i.k = o.k AND i.z < o.z
24+
);
25+
----
26+
# Pinned to today's behaviour, which is incorrect. See
27+
# https://github.com/apache/datafusion/issues/25336 -- the fix flips this.
28+
false
29+
630
expect_plan HashJoinExec
731

832
run
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
name Q09
2+
group null_aware_join
3+
4+
load sql_benchmarks/null_aware_join/init/load.sql
5+
6+
# Correctness canary: the positive IN result must match a reference count that
7+
# does not use IN. It holds for every NAJ_ROWS. A row is TRUE when o.z > 900 or
8+
# when some in-scope subquery row equals its key; a NULL mark and a FALSE mark
9+
# keep the same rows here, which is what makes the plain mark join correct.
10+
assert I
11+
SELECT count(*) = (
12+
SELECT count(*)
13+
FROM small_outer o
14+
WHERE o.z > 900
15+
OR EXISTS (
16+
SELECT 1 FROM small_inner i
17+
WHERE i.k = o.k AND i.z < o.z AND i.id_n0 = o.id_n50
18+
)
19+
)
20+
FROM small_outer o
21+
WHERE o.z > 900
22+
OR o.id_n50 IN (
23+
SELECT i.id_n0 FROM small_inner i WHERE i.k = o.k AND i.z < o.z
24+
);
25+
----
26+
true
27+
28+
expect_plan HashJoinExec
29+
30+
run
31+
-- Q9: the same correlated shape as Q08, but a NON-negated IN. A Filter keeps a
32+
-- row only when the predicate is TRUE, and AND/OR make TRUE only out of TRUE,
33+
-- so a NULL mark behaves exactly like a FALSE mark and the mark join must NOT
34+
-- be null-aware. Every other query in this suite covers the direction where
35+
-- null-aware handling is required; this one covers the direction where taking
36+
-- it anyway is pure cost. Widening the "needs null-aware" test until this shape
37+
-- is included does not change any result, so only this timing shows it.
38+
SELECT count(*)
39+
FROM small_outer o
40+
WHERE o.z > 900
41+
OR o.id_n50 IN (
42+
SELECT i.id_n0 FROM small_inner i WHERE i.k = o.k AND i.z < o.z
43+
);
44+
45+
cleanup sql_benchmarks/null_aware_join/init/cleanup.sql

benchmarks/sql_benchmarks/null_aware_join/null_aware_join.suite

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
description = "Null-aware (NOT IN) hash join benchmarks: uncorrelated, non-equality-correlated, and equality-correlated NOT IN across NULL fractions"
1+
description = "Null-aware (NOT IN) hash join benchmarks: uncorrelated, non-equality-correlated, and equality-correlated NOT IN across NULL fractions, plus the positive IN shape that must not be null-aware"
22

33
query_pattern = "q{QUERY_ID_PADDED}.benchmark"
44

@@ -8,7 +8,7 @@ short = "r"
88
env = "NAJ_ROWS"
99
default = "10000"
1010
values = ["10000", "..."]
11-
help = "Rows per table for the correlated NOT IN queries (Q04-Q08). These evaluate the join filter over candidate build x probe pairs, so their cost grows with the square of this value."
11+
help = "Rows per table for the correlated queries (Q04-Q09). These evaluate the join filter over candidate build x probe pairs, so their cost grows with the square of this value."
1212

1313
[[options]]
1414
name = "large-rows"

ci/scripts/check_generated_docs.sh

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Licensed to the Apache Software Foundation (ASF) under one
4+
# or more contributor license agreements. See the NOTICE file
5+
# distributed with this work for additional information
6+
# regarding copyright ownership. The ASF licenses this file
7+
# to you under the Apache License, Version 2.0 (the
8+
# "License"); you may not use this file except in compliance
9+
# with the License. You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing,
14+
# software distributed under the License is distributed on an
15+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16+
# KIND, either express or implied. See the License for the
17+
# specific language governing permissions and limitations
18+
# under the License.
19+
20+
# Regenerates the configuration and function documentation pages and checks
21+
# that the committed pages match, the same way the "check configs.md and
22+
# ***_functions.md is up-to-date" job does. With `--write`, replaces the pages
23+
# with the generated ones.
24+
25+
set -euo pipefail
26+
27+
SCRIPT_NAME="$(basename "${BASH_SOURCE[0]}")"
28+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
29+
ROOT_DIR="$(cd "${SCRIPT_DIR}/../.." && pwd)"
30+
31+
source "${SCRIPT_DIR}/utils/git.sh"
32+
33+
CONFIG_DOCS_DIR="docs/source/user-guide"
34+
FUNCTION_DOCS_DIR="docs/source/user-guide/sql"
35+
36+
MODE="check"
37+
ALLOW_DIRTY=0
38+
39+
usage() {
40+
cat >&2 <<USAGE
41+
Usage: $0 [--write] [--allow-dirty]
42+
43+
Checks that docs/source/user-guide/configs.md and the aggregate, scalar, and window
44+
function pages under docs/source/user-guide/sql/ match the output of
45+
dev/update_config_docs.sh and dev/update_function_docs.sh.
46+
--write Replace the pages with the generated ones (requires a clean git worktree, no uncommitted changes).
47+
--allow-dirty Allow \`--write\` to run even when the git worktree has uncommitted changes.
48+
USAGE
49+
exit 1
50+
}
51+
52+
while [[ $# -gt 0 ]]; do
53+
case "$1" in
54+
--write)
55+
MODE="write"
56+
;;
57+
--allow-dirty)
58+
ALLOW_DIRTY=1
59+
;;
60+
-h|--help)
61+
usage
62+
;;
63+
*)
64+
usage
65+
;;
66+
esac
67+
shift
68+
done
69+
70+
cd "${ROOT_DIR}"
71+
72+
if [[ "$MODE" == "write" && $ALLOW_DIRTY -eq 0 ]]; then
73+
require_clean_work_tree "$SCRIPT_NAME" || exit 1
74+
fi
75+
76+
if ! command -v npx >/dev/null 2>&1; then
77+
echo "[${SCRIPT_NAME}] npx is required to run the prettier check. Install Node.js (e.g., brew install node) and re-run." >&2
78+
exit 1
79+
fi
80+
81+
# One scratch directory beneath each documentation directory, so Prettier finds
82+
# the same configuration as for the committed pages.
83+
SCRATCH_DIRS=()
84+
cleanup() {
85+
rm -rf ${SCRATCH_DIRS[@]+"${SCRATCH_DIRS[@]}"}
86+
}
87+
trap cleanup EXIT
88+
trap 'exit 130' INT
89+
trap 'exit 143' TERM
90+
CONFIG_SCRATCH="$(mktemp -d "${ROOT_DIR}/${CONFIG_DOCS_DIR}/.config-docs-check.XXXXXX")"
91+
SCRATCH_DIRS+=("${CONFIG_SCRATCH}")
92+
FUNCTION_SCRATCH="$(mktemp -d "${ROOT_DIR}/${FUNCTION_DOCS_DIR}/.function-docs-check.XXXXXX")"
93+
SCRATCH_DIRS+=("${FUNCTION_SCRATCH}")
94+
95+
./dev/update_config_docs.sh --output-dir "${CONFIG_SCRATCH}"
96+
./dev/update_function_docs.sh --output-dir "${FUNCTION_SCRATCH}"
97+
98+
GENERATED=(
99+
"${CONFIG_SCRATCH}/configs.md"
100+
"${FUNCTION_SCRATCH}/aggregate_functions.md"
101+
"${FUNCTION_SCRATCH}/scalar_functions.md"
102+
"${FUNCTION_SCRATCH}/window_functions.md"
103+
)
104+
COMMITTED=(
105+
"${CONFIG_DOCS_DIR}/configs.md"
106+
"${FUNCTION_DOCS_DIR}/aggregate_functions.md"
107+
"${FUNCTION_DOCS_DIR}/scalar_functions.md"
108+
"${FUNCTION_DOCS_DIR}/window_functions.md"
109+
)
110+
111+
if [[ "$MODE" == "write" ]]; then
112+
for i in "${!COMMITTED[@]}"; do
113+
cp "${GENERATED[$i]}" "${COMMITTED[$i]}" || {
114+
echo "[${SCRIPT_NAME}] failed to copy the generated page to ${COMMITTED[$i]}" >&2
115+
exit 1
116+
}
117+
echo "${COMMITTED[$i]} updated."
118+
done
119+
exit 0
120+
fi
121+
122+
stale_count=0
123+
for i in "${!COMMITTED[@]}"; do
124+
diff_status=0
125+
diff -u -L "${COMMITTED[$i]} (committed)" -L "${COMMITTED[$i]} (generated)" \
126+
"${COMMITTED[$i]}" "${GENERATED[$i]}" > "${GENERATED[$i]}.diff" || diff_status=$?
127+
case "${diff_status}" in
128+
0)
129+
echo "${COMMITTED[$i]} is up-to-date."
130+
;;
131+
1)
132+
stale_count=$((stale_count + 1))
133+
echo ""
134+
echo "${COMMITTED[$i]} is out of date."
135+
echo "------------------------------------------------------------"
136+
cat "${GENERATED[$i]}.diff"
137+
echo "------------------------------------------------------------"
138+
;;
139+
*)
140+
echo "❌ diff exited with status ${diff_status} while comparing ${COMMITTED[$i]}; no comparison result." >&2
141+
exit "${diff_status}"
142+
;;
143+
esac
144+
done
145+
146+
if [[ ${stale_count} -gt 0 ]]; then
147+
echo ""
148+
echo "${stale_count} generated page(s) out of date. To update them, run:"
149+
echo ""
150+
echo " ./ci/scripts/check_generated_docs.sh --write"
151+
exit 1
152+
fi

0 commit comments

Comments
 (0)