gengliangwang commented on code in PR #50761: URL: https://github.com/apache/spark/pull/50761#discussion_r2070941624
########## sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/constraints.scala: ########## @@ -259,3 +263,94 @@ case class ForeignKeyConstraint( copy(userProvidedCharacteristic = c) } } + +/** + * An expression that validates a specific invariant on a column, before writing into table. + * + * @param child The fully resolved expression to be evaluated to check the constraint. + * @param columnExtractors Extractors for each referenced column. Used to generate readable errors. + * @param constraintName The name of the constraint. + * @param predicateSql The SQL representation of the constraint. + */ +case class CheckInvariant( + child: Expression, + columnExtractors: Seq[(String, Expression)], + constraintName: String, + predicateSql: String) + extends Expression with NonSQLExpression { + + override def children: Seq[Expression] = child +: columnExtractors.map(_._2) + override def dataType: DataType = NullType + override def foldable: Boolean = false + override def nullable: Boolean = true + + override def eval(input: InternalRow): Any = { + val result = child.eval(input) + if (result == false) { + val values = columnExtractors.map { + case (column, extractor) => column -> extractor.eval(input) + }.toMap + throw QueryExecutionErrors.checkViolation(constraintName, predicateSql, values) + } + null + } + + /** + * Generate the code to extract values for the columns referenced in a violated CHECK constraint. + * We build parallel lists of full column names and their extracted values in the row which + * violates the constraint, to be passed to the [[InvariantViolationException]] constructor + * in [[generateExpressionValidationCode()]]. + * + * Note that this code is a bit expensive, so it shouldn't be run until we already + * know the constraint has been violated. + */ + private def generateColumnValuesCode( Review Comment: Yes, check ConstraintExpressionSuite -- 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: reviews-unsubscr...@spark.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For additional commands, e-mail: reviews-h...@spark.apache.org