class ComparisonExpression extends Expression {

    public enum Type {
        EQUAL("="),
        NOT_EQUAL("<>"),
        LESS_THAN("<"),
        LESS_THAN_OR_EQUAL("<="),
        GREATER_THAN(">"),
        GREATER_THAN_OR_EQUAL(">="),
        CONTAINED_WITHIN("<<"),
        IS_DISTINCT_FROM("IS DISTINCT FROM"),
        REGEX_MATCH("~"),
        REGEX_NO_MATCH("!~"),
        REGEX_MATCH_CI("~*"),
        REGEX_NO_MATCH_CI("!~*");

        private final String value;

        Type(String value) {
            this.value = value;
        }

        public String getValue() {
            return value;
        }

    }

    private final Type type;
    private final Expression left;
    private final Expression right;

    public ComparisonExpression(Type type, Expression left, Expression right) {
        this.type = type;
        this.left = requireNonNull(left, "left is null");
        this.right = requireNonNull(right, "right is null");
    }

    public Type getType() {
        return type;
    }

    public Expression getLeft() {
        return left;
    }

    public Expression getRight() {
        return right;
    }

    @Override
    public <R, C> R accept(AstVisitor<R, C> visitor, C context) {
        return visitor.visitComparisonExpression(this, context);
    }

    @Override
    public boolean equals(Object o) {<FILL_FUNCTION_BODY>}

    @Override
    public int hashCode() {
        return Objects.hash(type, left, right);
    }
}

        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        ComparisonExpression that = (ComparisonExpression) o;
        return type == that.type &&
               Objects.equals(left, that.left) &&
               Objects.equals(right, that.right);
    
<methods>public non-sealed void <init>() ,public R accept(AstVisitor<R,C>, C) ,public final java.lang.String toString() <variables>