[SPARK-57999][SQL][PYTHON][DOCS] Document accepted input and return types for built-in functions#57079
[SPARK-57999][SQL][PYTHON][DOCS] Document accepted input and return types for built-in functions#57079HyukjinKwon wants to merge 9 commits into
Conversation
263bea6 to
f2d7147
Compare
f2d7147 to
5afa847
Compare
5afa847 to
f30972a
Compare
f30972a to
627edde
Compare
627edde to
8386b7d
Compare
8386b7d to
81e920b
Compare
…ypes for built-in functions ### What changes were proposed in this pull request? Documents, for every built-in function argument, which input types it accepts, and for the DataFrame APIs, what type the function returns, across the three public surfaces: SQL `@ExpressionDescription` arguments blocks, Scala `functions.scala` Scaladoc, and PySpark docstrings. Each argument names its canonical/expected type (e.g. "An expression that evaluates to an integer." for SQL, "A column that evaluates to an integer." for the DataFrame APIs), return types are documented on the DataFrame surfaces (e.g. "Returns a column that evaluates to a double." / "Returns a column of the same type as the input."), and constant-only arguments are marked "Must be a constant.". Documentation only; no functional or API change. ### Why are the changes needed? The SQL reference and the Scala/PySpark `functions` APIs previously had no per-argument type information for most built-in functions and no documented return type on the DataFrame APIs. ### Does this PR introduce any user-facing change? Yes, documentation only. The built-in function reference and the Scala/PySpark `functions` docstrings now state the accepted input type of each argument and the return type of each DataFrame function. ### How was this patch tested? The documented types were derived from and cross-checked against the analyzer's measured accept/reject behavior for every function and argument position (see the PR description for the generation-and-verification process). Existing documentation and expression tests (`ExpressionInfoSuite`, docs build) pass.
81e920b to
5c37b55
Compare
…run-ons - approx_top_k/approx_top_k_accumulate: expr is gated by isDataTypeSupported (atomic allowlist), not any type - decode: bin/charset are binary/string, not any type - comparison ops (=, <=>, <, <=, >, >=), equal_null, nullif, nullifzero, max_by/min_by ord: gated by checkForOrderingExpr -> "any orderable type" - functions.scala: add missing period before appended "Returns a column..." sentence in 33 @return blocks (run-on Scaladoc) Co-authored-by: Isaac
…cala The earlier sweep matched "Returns a column" on a single line, missing 16 blocks where the appended sentence wraps as "...`sinh` Returns a" / "column..." across two lines. Add the missing period before "Returns" in sinh, tanh, add_months, date_format, the date-part extractors (year/quarter/month/ dayofweek/dayofmonth/dayofyear and siblings), last_day, and 3 more. Co-authored-by: Isaac
…wording - to_timestamp @return: the 17th run-on block missed by the prior sweep (prose line ended without a period, fusing with the next "Returns a column..." line). Add the terminal period. - any_value: "The expression to return some value of for a group of rows." read broken ("of for"); match the first/last peers: "...some value of." Co-authored-by: Isaac
…x review findings Consistency: many functions.scala functions documented @param but had no @return (or only one overload did), while the PR documents return types elsewhere. Add "Returns a column..." @return to every function/overload that was missing one (355 functions), leaving functions where a value return type is not meaningful (sort builders asc/desc, column constructors col/column, partition transforms bucket/days/months/years, UDF/dispatch udf/udaf/callUDF/ reflect, generators posexplode) without one. Return types derived from the ExpressionsSchemaSuite golden file (sql-expression-schema.md) and Catalyst dataType; polymorphic functions (max/min/first/last/coalesce/greatest/...) use "of the same type as the input" rather than the misleading example type. Review findings (pullrequestreview-4667871389): - to_time/try_to_time @return said "string" but return TimeType — corrected on both Scala @return and PySpark Returns docstrings. - bit_or: replaced content-free "The expr1 argument." arg docs with wording matching the BitwiseAnd/BitwiseXor peers ("The first/second operand ..."). Co-authored-by: Isaac
…rate
Audited every accepted-input and return type phrase across the three doc
surfaces (functions.scala Scaladoc, builtin.py docstrings, SQL
ExpressionDescription blocks) against each expression's inputTypes / dataType.
- Fold TIMESTAMP_NTZ into "timestamp" in all type phrases (e.g. "string, date,
timestamp, or timestamp_ntz" -> "string, date, or timestamp"), keeping the
distinction only in function names / SQL literals / code, not user-facing
type descriptions.
- Numeric umbrella: where numeric subtypes cast in, say "a numeric" (or "a
numeric or interval") rather than enumerating double/decimal/long — e.g.
divide operands, ceil/floor, and the statistical aggregates (corr, covar_*,
stddev_*, var_*, skewness, kurtosis, regr_*) which accept any numeric via
implicit cast to double. Kept genuinely-narrow sets ("an integral" for
kll_sketch_agg_bigint, "an integral, decimal, or interval" for div).
- Fix incorrect accepted types: to_char/to_varchar accept numeric, date,
timestamp, time, or binary (date was missing); divide dividend is
"numeric or interval", divisor "numeric"; array element-args
(array_contains/append/prepend/position/remove/insert) take the array's
element type, not an integer; element_at index is an integer for an array
or the key type for a map; nullifzero takes a numeric.
- Fix incorrect return types: unix_nanos returns a decimal (DECIMAL(21,0)),
not a long; hll_union_agg usage said "estimated number of unique values"
but returns the merged sketch's binary representation.
- element_at/try_element_at/explode/explode_outer @return now document the
map case (value type / key and value columns), not only the array case.
Verified against the ExpressionsSchemaSuite golden file and Catalyst source
via an audit pass with adversarial verification; no run-on/orphan @return
regressions.
Co-authored-by: Isaac
|
I think it's quite good now. I am triggering the last multi-agent orchastrated review |
|
cc @cloud-fan too |
|
Could you check the linter failures? |
|
If you don't mind, shall we split this into more smaller reviewable PRs? For example, at least two; one for SQL, one for Python, @HyukjinKwon ? Although we live in agentic era, the PR should be human-reviewable as much as possible. |
…udit A multi-agent verification pass over every multi-argument function's type phrases (all three surfaces, checked against Catalyst inputTypes/dataType) surfaced these: - array_insert: the `pos` arg (1-based integer index) was mislabeled "the same type as the array elements" on the PySpark surface — only `value` is the element type. `pos` is coerced to IntegerType. (review finding) - max_by/min_by (3-arg, with `k`): route through MaxMinByK whose dataType is ArrayType(valueType), so @return is "an array", not "the same type as the input". - listagg/string_agg: ListAgg.dataType = child.dataType (string or binary), so the return is polymorphic — "of the same type as the input", not "a string". - overlay: Overlay.dataType = input.dataType (string or binary) — polymorphic. - shiftleft/shiftright/shiftrightunsigned: dataType = left.dataType (integer or long) — "of the same type as the input", not "an integer". - try_divide: Divide.dataType mirrors the input (double or decimal) — matches the try_add/try_subtract/try_multiply peers' "of the same type as the input". - reduce: `merge`/`finish` are lambda args; removed the stray column type-phrase lines so they match `aggregate` and the other higher-order functions (whose lambda params carry no "A column ..." type line on the PySpark surface). Co-authored-by: Isaac
|
Yeah will do |
- Wrap 20 Scaladoc @return/@param lines that exceeded 100 characters after the type sentences were appended (the scalastyle failures dongjoon-hyun flagged), preserving the standard 3-space payload indentation. - schema_of_json(json, options): @return wrongly said "evaluates to an integer"; SchemaOfJson returns a string (DDL schema). Corrected to "a string". Co-authored-by: Isaac
|
Superseded by smaller, per-surface PRs for reviewability (per @dongjoon-hyun's suggestion). SPARK-57999 is now an umbrella, with one sub-task and PR per documentation surface:
Each carries the exact reviewed content from this PR for its surface (scalastyle line-length fixes and the |
|
Thank you for the decision, @HyukjinKwon ! |
…unctions in the SQL function reference ### What changes were proposed in this pull request? This documents, for every built-in function argument, which input types it accepts, in the SQL `@ExpressionDescription` `arguments` blocks (rendered on the SQL functions reference page), using a numeric umbrella (`a numeric` / `a numeric or interval`) where numeric subtypes cast in, and `timestamp` for TIMESTAMP_NTZ in type phrases. Subtask of SPARK-57999, split out from apache#57079 for reviewability. This PR covers only the SQL surface. ### Why are the changes needed? The SQL function reference previously had no per-argument type information for most built-in functions. This fills that gap. ### Does this PR introduce _any_ user-facing change? Yes, documentation only. No behavioral or API change. ### How was this patch tested? Existing `ExpressionInfoSuite` and the SPARK-32870 argument-block-format tests pass. Types were derived from and verified against the analyzer's accept/reject behavior and each expression's `inputTypes` / `checkInputDataTypes`. Co-authored-by: Isaac
…the Scala functions API ### What changes were proposed in this pull request? This documents, for every built-in function in the Scala `functions` API (`functions.scala`), the accepted input type of each argument (`@param`) and the return type of each DataFrame function (`@return`), using the numeric umbrella where numeric subtypes cast in and `timestamp` for TIMESTAMP_NTZ in type phrases. Subtask of SPARK-57999, split out from apache#57079 for reviewability. This PR covers only the Scala `functions.scala` surface. ### Why are the changes needed? The Scala `functions` Scaladoc previously had no per-argument type information and no documented return type for most functions. This fills that gap. ### Does this PR introduce _any_ user-facing change? Yes, documentation only. No behavioral or API change. ### How was this patch tested? Scala style/format (scalastyle + scalafmt) and the docs build pass. Types were derived from and verified against the analyzer's behavior and each expression's `inputTypes` / `dataType`. Co-authored-by: Isaac
…in the PySpark functions API ### What changes were proposed in this pull request? This documents, for every built-in function in the PySpark `functions` API (`builtin.py`), the accepted input type of each argument (`Parameters`) and the return type of each function (`Returns`), using the numeric umbrella where numeric subtypes cast in and `timestamp` for TIMESTAMP_NTZ in type phrases. Subtask of SPARK-57999, split out from apache#57079 for reviewability. This PR covers only the PySpark `builtin.py` surface. ### Why are the changes needed? The PySpark `functions` docstrings previously had no per-argument type information for most functions. This fills that gap. ### Does this PR introduce _any_ user-facing change? Yes, documentation only. No behavioral or API change. ### How was this patch tested? Python lint (flake8 + black) and the docstring doctests pass. Types were derived from and verified against the analyzer's behavior and each expression's `inputTypes` / `dataType`. Co-authored-by: Isaac
What changes were proposed in this pull request?
This PR documents, for every built-in function argument, which input types it accepts, and for
the DataFrame APIs, what type the function returns — across the three public documentation
surfaces:
@ExpressionDescriptionargumentsblocks (the SQL functions reference page),functions.scalaScaladoc (@param/@return),builtin.pydocstrings (Parameters/Returns).Each argument names its accepted type, e.g. SQL
An expression that evaluates to an integer./DataFrame
A column that evaluates to an integer.. The wording adapts to the argument kind:a numeric,a string or binary,a numeric, interval, date, timestamp, or time.Must be a constant.(e.g.ceil/floor'sscale).A lambda function..Return types are documented on the DataFrame surfaces as, e.g.,
Returns a column that evaluates to a double.,Returns a column of the same type as the input.(e.g.abs,coalesce,greatest),or
Returns a column of the element type of the input array, or the value type of the input map.for collection accessors (e.g.
element_at,explode).Conventions used for the documented types:
aggregates
corr/covar_*/stddev_*/var_*/regr_*, ordivide), the argument is documentedas
a numeric(ora numeric or interval) rather than enumeratingdouble/decimal/long,matching how mainstream SQL references document argument types. Genuinely narrow sets are kept
(e.g.
an integral,an integral, decimal, or intervalfordiv).timestampin type phrases (the distinction is kept infunction names and examples, not in user-facing type descriptions).
This PR contains only documentation text. It has no functional or API change.
Why are the changes needed?
Users of the SQL reference, the Scala
functionsAPI, and the PySparkfunctionsAPI previouslyhad no per-argument type information for most built-in functions, and no documented return type on
the DataFrame APIs. This PR fills that gap consistently across all three surfaces.
How was this patch generated and verified?
The documented types were derived from the analyzer's actual behavior, then adjusted to the
conventions above and cross-checked against each expression's
inputTypes/checkInputDataTypes/
dataTypeand theExpressionsSchemaSuiteoutput schema:accepted (natively or via cast), rejected, or constant-only, and measured each function's output
type (including functions whose return type follows their input or an input's element/value type).
TIMESTAMP_NTZ conventions.
got wrong — e.g.
to_char/to_varcharacceptnumeric, date, timestamp, time, or binary;dividedividend isnumeric or intervaland divisornumeric; array element-args(
array_contains/append/prepend/position/remove/insert) take the array's element type;element_at/explodedocument the map case;unix_nanosreturns adecimal.ExpressionInfoSuite, the SPARK-32870 argument-format tests, the docs build, Scala style/format(scalastyle + scalafmt), and Python lint (flake8 + black) all pass.
Does this PR introduce any user-facing change?
Yes — documentation only. The SQL built-in function reference, Scala
functionsScaladoc, andPySpark
functionsdocstrings now state each argument's accepted input type and each DataFramefunction's return type. There is no behavioral or API change.
How was this patch tested?
Existing documentation and expression tests (
ExpressionInfoSuite, docs build) pass. Thedocumentation text was cross-checked against the analyzer's measured accept/reject behavior and
Catalyst source for every function and argument position, as described above.