ワンクリックで
review-comet-pr
// Review a DataFusion Comet pull request for Spark compatibility and implementation correctness. Provides guidance to a reviewer rather than posting comments directly.
// Review a DataFusion Comet pull request for Spark compatibility and implementation correctness. Provides guidance to a reviewer rather than posting comments directly.
Triage open Comet issues marked `requires-triage` per the project bug triage guide. Applies the recommended priority and area labels, removes `requires-triage`, and files a dated summary issue listing what was done. A human reviews the summary issue and closes it when satisfied.
Use when wiring an existing DataFusion or datafusion-spark function into Comet for a Spark expression. Identifies the right wiring pattern (one-line passthrough, datafusion-spark UDF registration, or custom serde with input massaging / restrictions), applies the Scala serde, registers the UDF in jni_api when needed, and adds SQL file tests. Assumes the function already exists upstream — if not, switch to `implement-comet-expression`.
Use when implementing a new Spark expression in DataFusion Comet. Walks through cloning latest Spark master to study the canonical implementation, checking the upstream datafusion-spark crate before writing native code, building the Comet serde and Rust wire-up from the contributor guide, then running audit-comet-expression to drive a test-coverage iteration loop.
Audit an existing Comet expression for correctness and test coverage. Studies the Spark implementation across versions 3.4.3, 3.5.8, and 4.0.1, reviews the Comet and DataFusion implementations, identifies missing test coverage, and offers to implement additional tests.
| name | review-comet-pr |
| description | Review a DataFusion Comet pull request for Spark compatibility and implementation correctness. Provides guidance to a reviewer rather than posting comments directly. |
| argument-hint | <pr-number> |
Review Comet PR #$ARGUMENTS
Fetch the PR details to understand the scope:
gh pr view $ARGUMENTS --repo apache/datafusion-comet --json title,body,author,isDraft,state,files
Before forming your review:
# View existing comments on a PR
gh pr view $ARGUMENTS --repo apache/datafusion-comet --comments
Read the changed files and understand the area of the codebase being modified:
# View the diff
gh pr diff $ARGUMENTS --repo apache/datafusion-comet
For expression PRs, check how similar expressions are implemented in the codebase. Look at the serde files in spark/src/main/scala/org/apache/comet/serde/ and Rust implementations in native/spark-expr/src/.
For any PR that adds or modifies an expression, you must read the Spark source code to understand the canonical behavior. This is the authoritative reference for what Comet must match.
Clone or update the Spark repo:
# Clone if not already present (use /tmp to avoid polluting the workspace)
if [ ! -d /tmp/spark ]; then
git clone --depth 1 https://github.com/apache/spark.git /tmp/spark
fi
Find the expression implementation in Spark:
# Search for the expression class (e.g., for "Conv", "Hex", "Substring")
find /tmp/spark/sql/catalyst/src/main/scala -name "*.scala" | xargs grep -l "case class <ExpressionName>"
Read the Spark implementation carefully. Pay attention to:
eval and doGenEval/nullSafeEval methods. These define the exact behavior.inputTypes and dataType fields. These define which types Spark accepts and what it returns.nullable = true? Does nullSafeEval handle nulls implicitly?require assertions.SQLConf.get.ansiEnabled or failOnError).Read the Spark tests for the expression:
# Find test files
find /tmp/spark/sql -name "*.scala" -path "*/test/*" | xargs grep -l "<ExpressionName>"
Compare the Spark behavior against the Comet implementation in the PR. Identify:
IncompatibleSuggest additional tests for any edge cases or type combinations covered in Spark's tests that are missing from the PR's tests.
This is the most critical aspect of Comet reviews. Comet must produce identical results to Spark.
For expression PRs, verify against the Spark source you read in step 2:
Check edge cases
Verify all data types are handled
inputTypes in Spark source)Check for ANSI mode differences
IncompatibleAlways verify PRs follow the implementation guidelines.
spark/src/main/scala/org/apache/comet/serde/)exprToProtoInternalgetSupportLevel reflects true compatibility:
Compatible() - matches Spark exactlyIncompatible(Some("reason")) - differs in documented waysUnsupported(Some("reason")) - cannot be implementeddatetime.scala, strings.scala, arithmetic.scala, etc.)QueryPlanSerde.scala)Location: native/spark-expr/src/
Result types.Expression tests should use Comet SQL Tests (CometSqlFileTestSuite) where possible. This framework automatically runs each query through both Spark and Comet and compares results. No Scala code is needed. Only fall back to Comet Scala Tests in CometExpressionSuite when Comet SQL Tests cannot express the test. Examples include complex DataFrame setup, programmatic data generation, or non-expression tests.
Comet SQL Test location: spark/src/test/resources/sql-tests/expressions/<category>/
Categories include: aggregate/, array/, string/, math/, struct/, map/, datetime/, hash/, etc.
Comet SQL Test structure:
-- Create test data
statement
CREATE TABLE test_crc32(col string, a int, b float) USING parquet
statement
INSERT INTO test_crc32 VALUES ('Spark', 10, 1.5), (NULL, NULL, NULL), ('', 0, 0.0)
-- Default mode: verifies native Comet execution + result matches Spark
query
SELECT crc32(col) FROM test_crc32
-- spark_answer_only: compares results without requiring native execution
query spark_answer_only
SELECT crc32(cast(a as string)) FROM test_crc32
-- tolerance: allows numeric variance for floating-point results
query tolerance=0.0001
SELECT cos(v) FROM test_trig
-- expect_fallback: asserts fallback to Spark occurs
query expect_fallback(unsupported expression)
SELECT unsupported_func(v) FROM test_table
-- expect_error: verifies both engines throw matching exceptions
query expect_error(ARITHMETIC_OVERFLOW)
SELECT 2147483647 + 1
-- ignore: skip queries with known bugs (include GitHub issue link)
query ignore(https://github.com/apache/datafusion-comet/issues/NNNN)
SELECT known_buggy_expr(v) FROM test_table
Running Comet SQL Tests:
# All Comet SQL Tests
./mvnw test -Dsuites="org.apache.comet.CometSqlFileTestSuite" -Dtest=none
# Specific test file (substring match)
./mvnw test -Dsuites="org.apache.comet.CometSqlFileTestSuite crc32" -Dtest=none
CRITICAL: Verify all test requirements (regardless of framework):
SELECT expression(NULL))withSQLConf(SQLConf.OPTIMIZER_EXCLUDED_RULES.key ->
"org.apache.spark.sql.catalyst.optimizer.ConstantFolding") {
checkSparkAnswerAndOperator("SELECT func(literal)")
}
For PRs that add new expressions, performance is not optional. The whole point of Comet is to be faster than Spark. If a new expression is not faster, it may not be worth adding.
Check that the PR includes microbenchmark results. The PR description should contain benchmark numbers comparing Comet vs Spark for the new expression. If benchmark results are missing, flag this as a required addition.
Look for a microbenchmark implementation. Expression benchmarks live in spark/src/test/scala/org/apache/spark/sql/benchmark/. Check whether the PR adds a benchmark for the new expression.
Review the benchmark results if provided:
Review the Rust implementation for performance concerns:
If benchmark results show Comet is slower than Spark, flag this clearly. The PR should explain why the regression is acceptable or include a plan to optimize.
Always check the CI status and summarize any test failures in your review.
# View CI check status
gh pr checks $ARGUMENTS --repo apache/datafusion-comet
# View failed check details
gh pr checks $ARGUMENTS --repo apache/datafusion-comet --failed
Some user-facing docs are auto-generated from the serde. Others are hand-edited. Treat them differently.
Generated by GenerateDocs — do NOT ask the contributor to edit these by hand. CI regenerates and publishes them on every merge to main:
docs/source/user-guide/latest/compatibility/expressions/ (math.md, datetime.md, array.md, string.md, aggregate.md, struct.md, map.md, misc.md, cast.md)docs/source/user-guide/latest/configs.mdFor these, check the source instead. Does the new or modified CometExpressionSerde provide accurate getIncompatibleReasons() and getUnsupportedReasons() strings? Each returned string is rendered as a bullet on the corresponding compat page. Common gaps to flag:
Incompatible(Some("...")) in getSupportLevel but getIncompatibleReasons() is empty, so the compat page shows it as supported with no caveats.Unsupported(Some("...")) for specific data types or argument shapes but no getUnsupportedReasons() to surface the limitation to users.notes argument passed to Compatible / Incompatible / Unsupported. They do not have to match exactly, but consistency helps users.See docs/source/contributor-guide/adding_a_new_expression.md (sections "Documenting Incompatible and Unsupported Reasons") for the contract these methods follow.
Hand-edited — PR should update if relevant:
docs/source/user-guide/latest/expressions.md — the supported-expressions list. New expressions belong here.latest/compatibility/ pages such as floating-point.md, operators.md, regex.md, scans.md.iceberg.md, installation.md, tuning.md when the PR changes user-visible behavior.If the PR adds a new expression but does not update expressions.md, flag that. If it touches incompatibility behavior, flag that the serde reasons should reflect the change.
CometSqlFileTestSuite) rather than adding to Comet Scala Tests like CometExpressionSuite. Suggest migration if the PR adds Comet Scala Tests for expressions that could use Comet SQL Tests instead../mvnw install -pl common -DskipTestsgetSupportLevel: Edge cases should be marked as Incompatibledatafusion-functions (e.g. levenshtein, concat, coalesce, sha2, regexp_replace), check that the serde sets the return type explicitly via scalarFunctionExprToProtoWithReturnType rather than scalarFunctionExprToProto or the bare CometScalarFunction(name) shortcut. Without an explicit return type, the native planner consults DataFusion's UDF registry first for type resolution, and any arity or input-type difference between the Spark and DataFusion versions will fail native execution with Error from DataFusion: Function 'X' expects N arguments but received M. The Comet UDF is only swapped in after DF's signature validation passes. See the "When to set the return type explicitly" section in docs/source/contributor-guide/adding_a_new_expression.md.Present your review as guidance for the reviewer. Structure your output as:
Write reviews that sound human and conversational. Avoid:
Instead:
IMPORTANT: Never post comments or reviews on the PR directly. This skill is for providing guidance to a human reviewer. Present all findings and suggested comments to the user. The user will decide what to post.