-
Notifications
You must be signed in to change notification settings - Fork 24.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SQL: add "format" for "full" date range queries #48073
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,11 +108,13 @@ | |
import org.elasticsearch.xpack.sql.tree.Source; | ||
import org.elasticsearch.xpack.sql.util.Check; | ||
import org.elasticsearch.xpack.sql.util.DateUtils; | ||
import org.elasticsearch.xpack.sql.util.Holder; | ||
import org.elasticsearch.xpack.sql.util.ReflectionUtils; | ||
|
||
import java.time.OffsetTime; | ||
import java.time.Period; | ||
import java.time.ZonedDateTime; | ||
import java.time.temporal.TemporalAccessor; | ||
import java.util.Arrays; | ||
import java.util.LinkedHashMap; | ||
import java.util.List; | ||
|
@@ -821,9 +823,36 @@ protected QueryTranslation asQuery(Range r, boolean onAggs) { | |
if (onAggs) { | ||
aggFilter = new AggFilter(at.id().toString(), r.asScript()); | ||
} else { | ||
Holder<Object> lower = new Holder<>(valueOf(r.lower())); | ||
Holder<Object> upper = new Holder<>(valueOf(r.upper())); | ||
Holder<String> format = new Holder<>(dateFormat(r.value())); | ||
|
||
// for a date constant comparison, we need to use a format for the date, to make sure that the format is the same | ||
// no matter the timezone provided by the user | ||
if (format.get() == null) { | ||
DateFormatter formatter = null; | ||
if (lower.get() instanceof ZonedDateTime || upper.get() instanceof ZonedDateTime) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a chance to have different formats between upper and lower? I think so so it might make sense to have two formatters in case of two different formats. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @costin, I tried to test something that has two different formats (like Also, we need to have one format only because that's the one to be used in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for explaining. |
||
formatter = DateFormatter.forPattern(DATE_FORMAT); | ||
} else if (lower.get() instanceof OffsetTime || upper.get() instanceof OffsetTime) { | ||
formatter = DateFormatter.forPattern(TIME_FORMAT); | ||
} | ||
if (formatter != null) { | ||
// RangeQueryBuilder accepts an Object as its parameter, but it will call .toString() on the ZonedDateTime | ||
// instance which can have a slightly different format depending on the ZoneId used to create the ZonedDateTime | ||
// Since RangeQueryBuilder can handle date as String as well, we'll format it as String and provide the format. | ||
if (lower.get() instanceof ZonedDateTime || lower.get() instanceof OffsetTime) { | ||
lower.set(formatter.format((TemporalAccessor) lower.get())); | ||
} | ||
if (upper.get() instanceof ZonedDateTime || upper.get() instanceof OffsetTime) { | ||
upper.set(formatter.format((TemporalAccessor) upper.get())); | ||
} | ||
format.set(formatter.pattern()); | ||
} | ||
} | ||
|
||
query = handleQuery(r, r.value(), | ||
() -> new RangeQuery(r.source(), nameOf(r.value()), valueOf(r.lower()), r.includeLower(), | ||
valueOf(r.upper()), r.includeUpper(), dateFormat(r.value()))); | ||
() -> new RangeQuery(r.source(), nameOf(r.value()), lower.get(), r.includeLower(), | ||
upper.get(), r.includeUpper(), format.get())); | ||
} | ||
return new QueryTranslation(query, aggFilter); | ||
} else { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use the holder? Does the closure require a final variable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@costin yes.