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


##########
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`.
   def toV2Constraint: Constraint = {
-    val predicate = new V2ExpressionBuilder(child, 
true).buildPredicate().orNull
+    val predicate = if (analyzedChild.exists(readsCurrentContext)) {
+      null
+    } else {
+      new V2ExpressionBuilder(child, true).buildPredicate().orNull

Review Comment:
   Agreed, filed as SPARK-60451 together with the CREATE and REPLACE TABLE case 
at L146, and referenced from the description. I checked the DEFAULT case as 
well: CAST_INVALID_INPUT under ANSI, and with ANSI off `INSERT INTO t(id) 
VALUES (1)` writes NULL.
   



##########
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`.
   def toV2Constraint: Constraint = {
-    val predicate = new V2ExpressionBuilder(child, 
true).buildPredicate().orNull
+    val predicate = if (analyzedChild.exists(readsCurrentContext)) {
+      null

Review Comment:
   Added your sentence to the Javadoc of `predicate()` in e2322baf889.
   



##########
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/constraints.scala:
##########
@@ -142,6 +160,17 @@ case class CheckConstraint(
       .build()
   }
 
+  /**
+   * Whether the rules that compute the current time, date, catalog and the 
like change part of `e`,
+   * applied to `e` as the optimizer has it, with its `RuntimeReplaceable`s 
replaced.
+   */
+  private def readsCurrentContext(e: Expression): Boolean = {
+    val replaced = ReplaceExpressions.replace(e)
+    replaced.containsPattern(CURRENT_LIKE) ||

Review Comment:
   Added "Check constraint added by ALTER TABLE reading the current database" 
in e2322baf889: it adds `db = current_database()` in `ns`, asserts that 
`predicate()` is null, then in `ns2` accepts 'ns2' and rejects 'ns'. It fails 
when the CURRENT_LIKE term is removed.
   



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