in paimon-codegen/src/main/scala/org/apache/paimon/codegen/ScalarOperatorGens.scala [239:313]
private def generateMapComparison(
ctx: CodeGeneratorContext,
left: GeneratedExpression,
right: GeneratedExpression,
keyType: DataType,
valueType: DataType,
resultType: DataType): GeneratedExpression =
generateCallWithStmtIfArgsNotNull(ctx, resultType, Seq(left, right)) {
args =>
val leftTerm = args.head
val rightTerm = args(1)
val resultTerm = newName("compareResult")
val mapCls = className[java.util.Map[_, _]]
val keyCls = boxedTypeTermForType(keyType)
val valueCls = boxedTypeTermForType(valueType)
val leftMapTerm = newName("leftMap")
val leftKeyTerm = newName("leftKey")
val leftValueTerm = newName("leftValue")
val leftValueNullTerm = newName("leftValueIsNull")
val leftValueExpr =
GeneratedExpression(leftValueTerm, leftValueNullTerm, "", valueType)
val rightMapTerm = newName("rightMap")
val rightValueTerm = newName("rightValue")
val rightValueNullTerm = newName("rightValueIsNull")
val rightValueExpr =
GeneratedExpression(rightValueTerm, rightValueNullTerm, "", valueType)
val entryTerm = newName("entry")
val entryCls = classOf[java.util.Map.Entry[AnyRef, AnyRef]].getCanonicalName
val valueEqualsExpr =
generateEquals(ctx, leftValueExpr, rightValueExpr, new BooleanType(valueType.isNullable))
val internalTypeCls = classOf[DataType].getCanonicalName
val keyTypeTerm = ctx.addReusableObject(keyType, "keyType", internalTypeCls)
val valueTypeTerm = ctx.addReusableObject(valueType, "valueType", internalTypeCls)
val mapDataUtil = className[InternalMapSerializer]
val stmt =
s"""
|boolean $resultTerm;
|if ($leftTerm.size() == $rightTerm.size()) {
| $resultTerm = true;
| $mapCls $leftMapTerm = $mapDataUtil
| .convertToJavaMap($leftTerm, $keyTypeTerm, $valueTypeTerm);
| $mapCls $rightMapTerm = $mapDataUtil
| .convertToJavaMap($rightTerm, $keyTypeTerm, $valueTypeTerm);
|
| for ($entryCls $entryTerm : $leftMapTerm.entrySet()) {
| $keyCls $leftKeyTerm = ($keyCls) $entryTerm.getKey();
| if ($rightMapTerm.containsKey($leftKeyTerm)) {
| $valueCls $leftValueTerm = ($valueCls) $entryTerm.getValue();
| $valueCls $rightValueTerm = ($valueCls) $rightMapTerm.get($leftKeyTerm);
| boolean $leftValueNullTerm = ($leftValueTerm == null);
| boolean $rightValueNullTerm = ($rightValueTerm == null);
|
| ${valueEqualsExpr.code}
| if (!${valueEqualsExpr.resultTerm}) {
| $resultTerm = false;
| break;
| }
| } else {
| $resultTerm = false;
| break;
| }
| }
|} else {
| $resultTerm = false;
|}
""".stripMargin
(stmt, resultTerm)
}