@@ -261,8 +261,17 @@ case class And(left: Expression, right: Expression) extends BinaryOperator
261261 // Recursively call semanticEquals on subexpressions to check the equivalency of two seqs.
262262 var elements1 = splitConjunctivePredicates(this )
263263 val elements2 = splitConjunctivePredicates(other)
264- for (e <- elements2) elements1 = removeFirstSemanticEquivalent(elements1, e)
265- elements1.isEmpty
264+ // We can recursively call semanticEquals to check the equivalency for subexpressions, but
265+ // there is no simple solution to compare the equivalency of sequence of expressions.
266+ // Expression class doesn't have order, so we couldn't sort them. We can neither use
267+ // set comparison as Set doesn't support custom compare function, which is semanticEquals.
268+ // To check the equivalency of elements1 and elements2, we first compare their size. Then
269+ // for each element in elements2, we remove its first semantically equivalent expression from
270+ // elements1. If they are semantically equivalent, elements1 should be empty at the end.
271+ elements1.size == elements2.size && {
272+ for (e <- elements2) elements1 = removeFirstSemanticEquivalent(elements1, e)
273+ elements1.isEmpty
274+ }
266275 }
267276
268277 override def genCode (ctx : CodeGenContext , ev : GeneratedExpressionCode ): String = {
@@ -319,12 +328,20 @@ case class Or(left: Expression, right: Expression) extends BinaryOperator
319328 // Non-deterministic expressions cannot be semantic equal
320329 if (! deterministic || ! other.deterministic) return false
321330
322- // we know both expressions are Or, so we can tolerate ordering different
323- // Recursively call semanticEquals on subexpressions to check the equivalency of two seqs.
331+ // We know both expressions are Or, so we can tolerate ordering different
324332 var elements1 = splitDisjunctivePredicates(this )
325333 val elements2 = splitDisjunctivePredicates(other)
326- for (e <- elements2) elements1 = removeFirstSemanticEquivalent(elements1, e)
327- elements1.isEmpty
334+ // We can recursively call semanticEquals to check the equivalency for subexpressions, but
335+ // there is no simple solution to compare the equivalency of sequence of expressions.
336+ // Expression class doesn't have order, so we couldn't sort them. We can neither use
337+ // set comparison as Set doesn't support custom compare function, which is semanticEquals.
338+ // To check the equivalency of elements1 and elements2, we first compare their size. Then
339+ // for each element in elements2, we remove its first semantically equivalent expression from
340+ // elements1. If they are semantically equivalent, elements1 should be empty at the end.
341+ elements1.size == elements2.size && {
342+ for (e <- elements2) elements1 = removeFirstSemanticEquivalent(elements1, e)
343+ elements1.isEmpty
344+ }
328345 }
329346
330347 override def genCode (ctx : CodeGenContext , ev : GeneratedExpressionCode ): String = {
0 commit comments