public void visitComparison()

in modules/lang-painless/src/main/java/org/opensearch/painless/phase/DefaultConstantFoldingOptimizationPhase.java [735:953]


    public void visitComparison(ComparisonNode irComparisonNode, Consumer<ExpressionNode> scope) {
        irComparisonNode.getLeftNode().visit(this, irComparisonNode::setLeftNode);
        irComparisonNode.getRightNode().visit(this, irComparisonNode::setRightNode);

        if ((irComparisonNode.getLeftNode() instanceof ConstantNode || irComparisonNode.getLeftNode() instanceof NullNode)
            && (irComparisonNode.getRightNode() instanceof ConstantNode || irComparisonNode.getRightNode() instanceof NullNode)) {

            ConstantNode irLeftConstantNode = irComparisonNode.getLeftNode() instanceof NullNode
                ? null
                : (ConstantNode) irComparisonNode.getLeftNode();
            ConstantNode irRightConstantNode = irComparisonNode.getRightNode() instanceof NullNode
                ? null
                : (ConstantNode) irComparisonNode.getRightNode();
            Operation operation = irComparisonNode.getOperation();
            Class<?> type = irComparisonNode.getComparisonType();

            if (operation == Operation.EQ || operation == Operation.EQR) {
                if (type == boolean.class) {
                    irLeftConstantNode.setConstant(
                        (boolean) irLeftConstantNode.getConstant() == (boolean) irRightConstantNode.getConstant()
                    );
                } else if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() == (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() == (long) irRightConstantNode.getConstant());
                } else if (type == float.class) {
                    irLeftConstantNode.setConstant((float) irLeftConstantNode.getConstant() == (float) irRightConstantNode.getConstant());
                } else if (type == double.class) {
                    irLeftConstantNode.setConstant((double) irLeftConstantNode.getConstant() == (double) irRightConstantNode.getConstant());
                } else if (irLeftConstantNode == null && irRightConstantNode == null) {
                    irLeftConstantNode = new ConstantNode(irComparisonNode.getLeftNode().getLocation());
                    irLeftConstantNode.setConstant(true);
                } else if (irLeftConstantNode == null || irRightConstantNode == null) {
                    irLeftConstantNode = new ConstantNode(irComparisonNode.getLeftNode().getLocation());
                    irLeftConstantNode.setConstant(false);
                } else {
                    if (operation == Operation.EQ) {
                        irLeftConstantNode.setConstant(irLeftConstantNode.getConstant().equals(irRightConstantNode.getConstant()));
                    } else {
                        irLeftConstantNode.setConstant(irLeftConstantNode.getConstant() == irRightConstantNode.getConstant());
                    }
                }

                irLeftConstantNode.setExpressionType(boolean.class);
                scope.accept(irLeftConstantNode);
            } else if (operation == Operation.NE || operation == Operation.NER) {
                if (type == boolean.class) {
                    irLeftConstantNode.setConstant(
                        (boolean) irLeftConstantNode.getConstant() != (boolean) irRightConstantNode.getConstant()
                    );
                } else if (type == int.class) {
                    irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() != (int) irRightConstantNode.getConstant());
                } else if (type == long.class) {
                    irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() != (long) irRightConstantNode.getConstant());
                } else if (type == float.class) {
                    irLeftConstantNode.setConstant((float) irLeftConstantNode.getConstant() != (float) irRightConstantNode.getConstant());
                } else if (type == double.class) {
                    irLeftConstantNode.setConstant((double) irLeftConstantNode.getConstant() != (double) irRightConstantNode.getConstant());
                } else if (irLeftConstantNode == null && irRightConstantNode == null) {
                    irLeftConstantNode = new ConstantNode(irComparisonNode.getLeftNode().getLocation());
                    irLeftConstantNode.setConstant(false);
                } else if (irLeftConstantNode == null || irRightConstantNode == null) {
                    irLeftConstantNode = new ConstantNode(irComparisonNode.getLeftNode().getLocation());
                    irLeftConstantNode.setConstant(true);
                } else {
                    if (operation == Operation.NE) {
                        irLeftConstantNode.setConstant(irLeftConstantNode.getConstant().equals(irRightConstantNode.getConstant()) == false);
                    } else {
                        irLeftConstantNode.setConstant(irLeftConstantNode.getConstant() != irRightConstantNode.getConstant());
                    }
                }

                irLeftConstantNode.setExpressionType(boolean.class);
                scope.accept(irLeftConstantNode);
            } else if (irLeftConstantNode != null && irRightConstantNode != null) {
                if (operation == Operation.GT) {
                    if (type == int.class) {
                        irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() > (int) irRightConstantNode.getConstant());
                    } else if (type == long.class) {
                        irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() > (long) irRightConstantNode.getConstant());
                    } else if (type == float.class) {
                        irLeftConstantNode.setConstant(
                            (float) irLeftConstantNode.getConstant() > (float) irRightConstantNode.getConstant()
                        );
                    } else if (type == double.class) {
                        irLeftConstantNode.setConstant(
                            (double) irLeftConstantNode.getConstant() > (double) irRightConstantNode.getConstant()
                        );
                    } else {
                        throw irComparisonNode.getLocation()
                            .createError(
                                new IllegalStateException(
                                    "constant folding error: "
                                        + "unexpected type ["
                                        + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                        + "] for "
                                        + "comparison operation ["
                                        + operation.symbol
                                        + "] on "
                                        + "constants ["
                                        + irLeftConstantNode.getConstant()
                                        + "] and ["
                                        + irRightConstantNode.getConstant()
                                        + "]"
                                )
                            );
                    }

                    irLeftConstantNode.setExpressionType(boolean.class);
                    scope.accept(irLeftConstantNode);
                } else if (operation == Operation.GTE) {
                    if (type == int.class) {
                        irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() >= (int) irRightConstantNode.getConstant());
                    } else if (type == long.class) {
                        irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() >= (long) irRightConstantNode.getConstant());
                    } else if (type == float.class) {
                        irLeftConstantNode.setConstant(
                            (float) irLeftConstantNode.getConstant() >= (float) irRightConstantNode.getConstant()
                        );
                    } else if (type == double.class) {
                        irLeftConstantNode.setConstant(
                            (double) irLeftConstantNode.getConstant() >= (double) irRightConstantNode.getConstant()
                        );
                    } else {
                        throw irComparisonNode.getLocation()
                            .createError(
                                new IllegalStateException(
                                    "constant folding error: "
                                        + "unexpected type ["
                                        + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                        + "] for "
                                        + "comparison operation ["
                                        + operation.symbol
                                        + "] on "
                                        + "constants ["
                                        + irLeftConstantNode.getConstant()
                                        + "] and ["
                                        + irRightConstantNode.getConstant()
                                        + "]"
                                )
                            );
                    }

                    irLeftConstantNode.setExpressionType(boolean.class);
                    scope.accept(irLeftConstantNode);
                } else if (operation == Operation.LT) {
                    if (type == int.class) {
                        irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() < (int) irRightConstantNode.getConstant());
                    } else if (type == long.class) {
                        irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() < (long) irRightConstantNode.getConstant());
                    } else if (type == float.class) {
                        irLeftConstantNode.setConstant(
                            (float) irLeftConstantNode.getConstant() < (float) irRightConstantNode.getConstant()
                        );
                    } else if (type == double.class) {
                        irLeftConstantNode.setConstant(
                            (double) irLeftConstantNode.getConstant() < (double) irRightConstantNode.getConstant()
                        );
                    } else {
                        throw irComparisonNode.getLocation()
                            .createError(
                                new IllegalStateException(
                                    "constant folding error: "
                                        + "unexpected type ["
                                        + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                        + "] for "
                                        + "comparison operation ["
                                        + operation.symbol
                                        + "] on "
                                        + "constants ["
                                        + irLeftConstantNode.getConstant()
                                        + "] and ["
                                        + irRightConstantNode.getConstant()
                                        + "]"
                                )
                            );
                    }

                    irLeftConstantNode.setExpressionType(boolean.class);
                    scope.accept(irLeftConstantNode);
                } else if (operation == Operation.LTE) {
                    if (type == int.class) {
                        irLeftConstantNode.setConstant((int) irLeftConstantNode.getConstant() <= (int) irRightConstantNode.getConstant());
                    } else if (type == long.class) {
                        irLeftConstantNode.setConstant((long) irLeftConstantNode.getConstant() <= (long) irRightConstantNode.getConstant());
                    } else if (type == float.class) {
                        irLeftConstantNode.setConstant(
                            (float) irLeftConstantNode.getConstant() <= (float) irRightConstantNode.getConstant()
                        );
                    } else if (type == double.class) {
                        irLeftConstantNode.setConstant(
                            (double) irLeftConstantNode.getConstant() <= (double) irRightConstantNode.getConstant()
                        );
                    } else {
                        throw irComparisonNode.getLocation()
                            .createError(
                                new IllegalStateException(
                                    "constant folding error: "
                                        + "unexpected type ["
                                        + PainlessLookupUtility.typeToCanonicalTypeName(type)
                                        + "] for "
                                        + "comparison operation ["
                                        + operation.symbol
                                        + "] on "
                                        + "constants ["
                                        + irLeftConstantNode.getConstant()
                                        + "] and ["
                                        + irRightConstantNode.getConstant()
                                        + "]"
                                )
                            );
                    }

                    irLeftConstantNode.setExpressionType(boolean.class);
                    scope.accept(irLeftConstantNode);
                }
            }
        }
    }