Airblader commented on a change in pull request #16213: URL: https://github.com/apache/flink/pull/16213#discussion_r655386544
########## File path: flink-table/flink-table-planner-blink/src/main/scala/org/apache/flink/table/planner/codegen/EqualiserCodeGenerator.scala ########## @@ -121,17 +64,97 @@ class EqualiserCodeGenerator(fieldTypes: Array[LogicalType]) { public boolean equals($ROW_DATA $LEFT_INPUT, $ROW_DATA $RIGHT_INPUT) { if ($LEFT_INPUT instanceof $BINARY_ROW && $RIGHT_INPUT instanceof $BINARY_ROW) { return $LEFT_INPUT.equals($RIGHT_INPUT); - } else { - $header - ${ctx.reuseLocalVariableCode()} - ${codes.mkString("\n")} - return true; } + + if ($LEFT_INPUT.getRowKind() != $RIGHT_INPUT.getRowKind()) { + return false; + } + + boolean result = true; + ${equalsMethodCalls.mkString("\n")} + return result; } + + ${equalsMethodCodes.mkString("\n")} } """.stripMargin - new GeneratedRecordEqualiser(className, functionCode, ctx.references.toArray) + new GeneratedRecordEqualiser(className, classCode, ctx.references.toArray) + } + + private def getEqualsMethodName(idx: Int) = s"""equalsAtIndex$idx""" + + private def generateEqualsMethod(ctx: CodeGeneratorContext, idx: Int): String = { + val methodName = getEqualsMethodName(idx) + ctx.startNewLocalVariableStatement(methodName) + + val Seq(leftNullTerm, rightNullTerm) = ctx.addReusableLocalVariables( + ("boolean", "isNullLeft"), + ("boolean", "isNullRight") + ) + + val fieldType = fieldTypes(idx) + val fieldTypeTerm = primitiveTypeTermForType(fieldType) + val Seq(leftFieldTerm, rightFieldTerm) = ctx.addReusableLocalVariables( + (fieldTypeTerm, "leftField"), + (fieldTypeTerm, "rightField") + ) + + val leftReadCode = rowFieldReadAccess(ctx, idx, LEFT_INPUT, fieldType) + val rightReadCode = rowFieldReadAccess(ctx, idx, RIGHT_INPUT, fieldType) + + val (equalsCode, equalsResult) = generateEqualsCode(ctx, fieldType, + leftFieldTerm, rightFieldTerm, leftNullTerm, rightNullTerm) + + s""" + |private boolean $methodName($ROW_DATA $LEFT_INPUT, $ROW_DATA $RIGHT_INPUT) { + | ${ctx.reuseLocalVariableCode(methodName)} + | + | $leftNullTerm = $LEFT_INPUT.isNullAt($idx); + | $rightNullTerm = $RIGHT_INPUT.isNullAt($idx); + | if ($leftNullTerm && $rightNullTerm) { + | return true; + | } + | + | if ($leftNullTerm|| $rightNullTerm) { + | return false; + | } Review comment: Since the first `if` returns `true`, not `false`, and is required to come _before_ the second `if`, I don't see a good way of looping over both of these checks first. We could loop over the second one, but then the first one has to be evaluated twice. Maybe I'm missing something? -- 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. For queries about this service, please contact Infrastructure at: us...@infra.apache.org