dongjoon-hyun commented on code in PR #59965:
URL: https://github.com/apache/spark/pull/59965#discussion_r4452124779
##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/TableOutputResolver.scala:
##########
@@ -878,7 +885,8 @@ object TableOutputResolver extends SQLConfHelper with
Logging {
private def canCauseCastOverflow(cast: Cast): Boolean = {
containsIntegralOrDecimalType(cast.dataType) &&
- !Cast.canUpCast(cast.child.dataType, cast.dataType)
+ // The check of a generated column casts an expression before it is
resolved.
+ (!cast.child.resolved || !Cast.canUpCast(cast.child.dataType,
cast.dataType))
Review Comment:
Thank you. I reproduced both: a provided value failed with
`CAST_OVERFLOW_IN_TABLE_INSERT` for `a * 2` and for `a div 0`. In 7192b681ca7 I
took your second option and went back to the plain ANSI cast, and
`canCauseCastOverflow` and `TableOutputResolver.cast` are as on master again.
Your example now gives `ARITHMETIC_OVERFLOW` and `DIVIDE_BY_ZERO`, as on the
base. The test `SPARK-60757: the check of a provided value reports the error of
the expression` replaces the overflow test.
As you note, the only difference left is for a catalog-defined column whose
expression type doesn't up-cast to the column type: a provided value fails with
`CAST_OVERFLOW`, and an auto-filled one with `CAST_OVERFLOW_IN_TABLE_INSERT`.
##########
docs/sql-migration-guide.md:
##########
@@ -71,6 +71,8 @@ license: |
- Since Spark 4.4, the Spark Thrift Server logs a warning at startup when
`hive.server2.enable.doAs` is `true` and `hive.server2.authentication` verifies
user identities (any recognized type other than `NONE`/`NOSASL`), because
executor-side data access still runs as the server's own service identity
rather than the connecting user (SPARK-5159). Set
`spark.sql.hive.thriftServer.allowIneffectiveDoAs` to `true` to acknowledge the
limitation and silence the warning. Spark 5.0 is expected to refuse to start on
this configuration unless that option is set.
- Since Spark 4.4, `UPDATE` and `MERGE` on a Data Source V2 table fail with
`DATATYPE_MISMATCH.INVALID_ROW_LEVEL_OPERATION_ASSIGNMENTS` when they assign to
a metadata column of the table. This includes `UPDATE SET *` and `INSERT *` in
`MERGE WITH SCHEMA EVOLUTION` when the source has a column with the name of a
metadata column of the target table. Previously, these assignments passed
analysis and were usually ignored. To restore the previous behavior, set
`spark.sql.legacy.ignoreMetadataColumnAssignments` to `true`.
- Since Spark 4.4, `CREATE TABLE`, `REPLACE TABLE`, and `ALTER TABLE ... ADD
CONSTRAINT` on a Data Source V2 table fail with
`USER_DEFINED_FUNCTION_IN_CHECK_CONSTRAINT` when the condition of a CHECK
constraint calls a user-defined scalar function, including a Data Source V2
function. `ALTER TABLE ... ADD CONSTRAINT` keeps failing with
`UNSUPPORTED_SQL_UDF_USAGE` on a SQL function. Previously, a write could
resolve the function name in its own session, so that it enforced another rule
or failed (SPARK-60777). To run these statements, change the condition to call
only built-in functions. Existing constraints that call a user-defined function
are not rejected.
+- Since Spark 4.4, a write to a Data Source V2 table parses and analyzes the
stored text of a generation expression with ANSI mode on and the default values
of the SQL configs that change how a text reads, such as
`spark.sql.parser.escapedStringLiterals`, regardless of the session of the
write. Only the following still follow that session: the session time zone,
case sensitivity, `spark.sql.timestampType`,
`spark.sql.decimalOperations.allowPrecisionLoss`, the configs that a view also
takes from the session that reads it, the functions found through `SET PATH`,
and the configs that an expression reads during evaluation, such as
`spark.sql.legacy.timeParserPolicy`. Any other config that the parsing or the
analysis reads takes its default value, also one that a function reads while it
is built, such as `spark.sql.legacy.negativeIndexInArrayInsert`. A text that
does not resolve under these settings, such as `flag = 1` on a `BOOLEAN`
column, is parsed with the ANSI mode of that session a
nd analyzed under that session, and a text that does not parse under them is
parsed under that session. Previously, the session of the write decided how the
text read, so a write could silently store a wrong value (SPARK-60757). As a
result, with `spark.sql.ansi.enabled=false`, also for a table created with that
setting, a write can fail with an error such as `CAST_INVALID_INPUT` where
Spark 4.3 stored `NULL`, and an implicit cast can change the stored value. The
validation of a provided value compares it with the value that the write would
store, so a value that only casts to it now fails with
`CHECK_CONSTRAINT_VIOLATION`, also with ANSI mode on. For example, for `b
STRING GENERATED ALWAYS AS (coalesce(s, 1))` with `s = '007'`, which stores
`7`, a provided `07` fails. A table created with a non-default value of a
config such as `spark.sql.parser.escapedStringLiterals` also gets the default
reading of its text on every write, without an error. A table CHECK constraint
is still read
under the session that writes, so a constraint that repeats the text of a
generation expression can fail a write whose session sets such a config. A row
that Spark 4.3 stored differently can fail with such an error or with
`CHECK_CONSTRAINT_VIOLATION` when a later write provides it again, such as an
`INSERT ... SELECT` from the same table. A `DELETE` does not check the
generated columns of the rows that it carries. To fix such a table, create a
new table with a text that reads as intended under these settings, and copy the
other columns into it with `INSERT ... SELECT`. To restore the previous
behavior, set `spark.sql.legacy.useCurrentConfigsForGeneratedColumn` to `true`.
Review Comment:
Right, I confirmed that `07` still fails under an ANSI writer with the flag
on, where the base accepts it. In 7192b681ca7 the entry now says "To read the
text under the session of the write, as Spark 4.3 does, set ...". The PR
description lists the changes that stay with the flag on. The flag's test now
also inserts a provided value, which the check reads under the session too.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]