LuciferYang commented on code in PR #59545:
URL: https://github.com/apache/spark/pull/59545#discussion_r4346095747


##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/constraints.scala:
##########
@@ -120,16 +122,32 @@ case class CheckConstraint(
     condition: String,
     override val userProvidedName: String = null,
     override val tableName: String = null,
-    override val userProvidedCharacteristic: ConstraintCharacteristic = 
ConstraintCharacteristic.empty)
+    override val userProvidedCharacteristic: ConstraintCharacteristic = 
ConstraintCharacteristic.empty,
+    analyzedChild: Option[Expression] = None)
   extends UnaryExpression
   with TableConstraint
-  with ImplicitCastInputTypes {
+  with ImplicitCastInputTypes
+  with AnalysisAwareExpression[CheckConstraint] {
 // scalastyle:on line.size.limit
 
+  final override val nodePatterns: Seq[TreePattern] = 
Seq(ANALYSIS_AWARE_EXPRESSION)
+
   override def inputTypes: Seq[AbstractDataType] = Seq(BooleanType)
 
+  override def stringArgs: Iterator[Any] =
+    Iterator(child, condition, userProvidedName, tableName, 
userProvidedCharacteristic)
+
+  override def markAsAnalyzed(): CheckConstraint = copy(analyzedChild = 
Some(child))
+
+  // ALTER TABLE builds the constraint from the optimized plan, where the 
current time, date,
+  // catalog, user and the like are replaced by their values at the time of 
the ALTER TABLE. A
+  // condition that reads one is stored without a predicate, so that writes 
check `predicateSql`.

Review Comment:
   Agreed. The user-facing section now says that such a constraint is re-parsed 
with each writer's session settings, as CREATE TABLE constraints without a 
predicate already are, and SPARK-60453 covers storing the confs. I confirmed 
the `doubleQuotedIdentifiers` case: a writer with the default settings fails 
with CAST_INVALID_INPUT.
   



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/constraints.scala:
##########
@@ -120,16 +122,32 @@ case class CheckConstraint(
     condition: String,
     override val userProvidedName: String = null,
     override val tableName: String = null,
-    override val userProvidedCharacteristic: ConstraintCharacteristic = 
ConstraintCharacteristic.empty)
+    override val userProvidedCharacteristic: ConstraintCharacteristic = 
ConstraintCharacteristic.empty,
+    analyzedChild: Option[Expression] = None)
   extends UnaryExpression
   with TableConstraint
-  with ImplicitCastInputTypes {
+  with ImplicitCastInputTypes
+  with AnalysisAwareExpression[CheckConstraint] {
 // scalastyle:on line.size.limit
 
+  final override val nodePatterns: Seq[TreePattern] = 
Seq(ANALYSIS_AWARE_EXPRESSION)
+
   override def inputTypes: Seq[AbstractDataType] = Seq(BooleanType)
 
+  override def stringArgs: Iterator[Any] =
+    Iterator(child, condition, userProvidedName, tableName, 
userProvidedCharacteristic)
+
+  override def markAsAnalyzed(): CheckConstraint = copy(analyzedChild = 
Some(child))

Review Comment:
   Confirmed: with the flag, `current_timestamp()` is stored frozen. The 
description mentions it, and SPARK-60456 tracks narrowing that branch to the 
OPTIONS values.
   



##########
sql/core/src/test/scala/org/apache/spark/sql/execution/command/v2/CheckConstraintSuite.scala:
##########
@@ -170,6 +170,60 @@ class CheckConstraintSuite extends QueryTest with 
CommandSuiteBase with DDLComma
     }
   }
 
+  test("SPARK-60032: Check constraint added by ALTER TABLE reading the current 
time") {
+    // The check compares with the time of the write, not the time of the 
ALTER TABLE.

Review Comment:
   Confirmed: on a copy-on-write table with rows 1 and 2 and `CHECK (db = 
current_database())` added in `ns`, `DELETE FROM t WHERE id > 1` run in `ns2` 
fails on the copied row 1, while with the predicate frozen as before this PR it 
succeeds. UPDATE behaves the same. The user-facing section mentions it, and 
SPARK-60453 covers whether such a constraint should be VALID and whether copied 
rows need checking.
   



-- 
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]

Reply via email to