Skip to content

examples: ExpressionStringify prints day-time intervals under the IntervalYearLiteral label #1237

Description

@nielspardon

ExpressionStringify.visit(IntervalDayLiteral, ...) (examples/substrait-spark/src/main/java/io/substrait/examples/util/ExpressionStringify.java:133) prints its output under the IntervalYearLiteral label — a copy-paste from the method directly above it:

public String visit(IntervalYearLiteral expr, EmptyVisitationContext context) {
  return "<IntervalYearLiteral " + expr.months() + " " + expr.years() + ">";
}

public String visit(IntervalDayLiteral expr, EmptyVisitationContext context) {
  return "<IntervalYearLiteral " + expr.seconds() + " " + expr.days() + ">";
}

So a plan carrying both interval kinds dumps two entries that both say IntervalYearLiteral, and nothing distinguishes them.

Compounding it, both methods print their components in reverse declaration order with no field labels — months before years, seconds before days — as does visit(IntervalCompoundLiteral, ...) for all five of its fields. <IntervalYearLiteral 1 12> could be 1 year 12 months, 12 years 1 month, or a day-time interval of 1 second and 12 days.

ExpressionStringify is one of the direct ExpressionVisitor implementors, so it is the tool a maintainer reaches for when chasing exactly the kind of interval mis-conversion #1138 describes.

Fix

Correct the label, and label the components while there:

return "<IntervalDayLiteral days=" + expr.days() + " seconds=" + expr.seconds() + ">";

with the same treatment for IntervalYearLiteral and IntervalCompoundLiteral.

Found while reviewing #1140.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions