class IntervalLiteral extends Literal {

    public enum Sign {
        PLUS,
        MINUS
    }

    public enum IntervalField {
        YEAR,
        MONTH,
        DAY,
        HOUR,
        MINUTE,
        SECOND
    }

    private final String value;
    private final Sign sign;
    private final IntervalField startField;
    @Nullable
    private final IntervalField endField;

    public IntervalLiteral(String value, Sign sign, IntervalField startField, @Nullable IntervalField endField) {
        this.value = value;
        this.sign = sign;
        this.startField = startField;
        this.endField = endField;
    }

    public String getValue() {
        return value;
    }

    public Sign getSign() {
        return sign;
    }

    public IntervalField getStartField() {
        return startField;
    }

    @Nullable
    public IntervalField getEndField() {
        return endField;
    }

    public static String format(IntervalLiteral i) {
        StringBuilder builder = new StringBuilder("INTERVAL ");
        if (i.getSign() == IntervalLiteral.Sign.MINUS) {
            builder.append("- ");
        }
        builder.append("'");
        builder.append(i.getValue());
        builder.append("' ")
            .append(i.getStartField().name());
        IntervalLiteral.IntervalField endField = i.getEndField();
        if (endField != null) {
            builder.append(" TO ").append(endField.name());
        }
        return builder.toString();
    }

    @Override
    public int hashCode() {
        return Objects.hash(value, sign, startField, endField);
    }

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

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

        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        IntervalLiteral other = (IntervalLiteral) obj;
        return Objects.equals(this.value, other.value) &&
               Objects.equals(this.sign, other.sign) &&
               Objects.equals(this.startField, other.startField) &&
               Objects.equals(this.endField, other.endField);
    
<methods>public non-sealed void <init>() ,public R accept(AstVisitor<R,C>, C) ,public static io.crate.sql.tree.Literal fromObject(java.lang.Object) <variables>