Skip to content
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

Arithmetic_exception(long overflow) when using rangeQuery #52396

Closed
shirleysela opened this issue Feb 16, 2020 · 13 comments · Fixed by #73034
Closed

Arithmetic_exception(long overflow) when using rangeQuery #52396

shirleysela opened this issue Feb 16, 2020 · 13 comments · Fixed by #73034
Labels
:Core/Infra/Core Core issues without another label :Search Foundations/Mapping Index mappings, including merging and defining field types Team:Core/Infra Meta label for core/infra team Team:Search Foundations Meta label for the Search Foundations team in Elasticsearch

Comments

@shirleysela
Copy link

shirleysela commented Feb 16, 2020

Hi,

My index mapping is something like:
{
"properties": {
"datetime": {
"type": "date"
}
}
}

I am querying the following search query (post):

{
"query": {
"bool": {
"filter": [
{
"range": {
"dateTime": {
"from": -316800000,
"to": 345354353,
"include_lower": true,
"include_upper": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}

and then i receive ArithmeticException: long overflow. It seems like the formatter ([strict_date_optional_time||epoch_millis]) is paring the long to a wrong year and then get this error.
This didn't happen on ES 7.3.0.. we are now using 7.5.2, and it also happens on 7.6.0
When i am adding "format":"epoch_millis" to the query, it works without this exception.

Please advice.
Thanks,
Shirley.

Caused by: java.lang.ArithmeticException: long overflow
at java.lang.Math.multiplyExact(Math.java:892) ~[?:1.8.0_201-1-ojdkbuild]
at java.time.Instant.toEpochMilli(Instant.java:1237) ~[?:1.8.0_201-1-ojdkbuild]
at org.elasticsearch.index.mapper.DateFieldMapper$Resolution$1.convert(DateFieldMapper.java:83) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.mapper.DateFieldMapper$DateFieldType.parseToLong(DateFieldMapper.java:409) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.mapper.DateFieldMapper$DateFieldType.isFieldWithinQuery(DateFieldMapper.java:422) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.RangeQueryBuilder.getRelation(RangeQueryBuilder.java:447) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.RangeQueryBuilder.doRewrite(RangeQueryBuilder.java:464) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.AbstractQueryBuilder.rewrite(AbstractQueryBuilder.java:265) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.BoolQueryBuilder.rewriteClauses(BoolQueryBuilder.java:458) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.BoolQueryBuilder.doRewrite(BoolQueryBuilder.java:425) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.AbstractQueryBuilder.rewrite(AbstractQueryBuilder.java:265) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.builder.SearchSourceBuilder.rewrite(SearchSourceBuilder.java:962) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.builder.SearchSourceBuilder.rewrite(SearchSourceBuilder.java:82) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.Rewriteable.rewrite(Rewriteable.java:68) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.Rewriteable.rewrite(Rewriteable.java:51) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.internal.ShardSearchRequest$RequestRewritable.rewrite(ShardSearchRequest.java:333) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.internal.ShardSearchRequest$RequestRewritable.rewrite(ShardSearchRequest.java:323) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.index.query.Rewriteable.rewrite(Rewriteable.java:68) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.SearchService.createSearchContext(SearchService.java:639) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.SearchService.createSearchContext(SearchService.java:617) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.SearchService.createContext(SearchService.java:580) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.SearchService.createAndPutContext(SearchService.java:545) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.SearchService.executeQueryPhase(SearchService.java:348) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.search.SearchService.lambda$executeQueryPhase$1(SearchService.java:340) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.action.ActionListener.lambda$map$2(ActionListener.java:146) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.action.ActionListener$1.onResponse(ActionListener.java:63) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.action.ActionRunnable.lambda$supply$0(ActionRunnable.java:58) ~[elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.action.ActionRunnable$2.doRun(ActionRunnable.java:73) [elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.common.util.concurrent.TimedRunnable.doRun(TimedRunnable.java:44) [elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingAbstractRunnable.doRun(ThreadContext.java:773) [elasticsearch-7.5.2.jar:7.5.2]
at org.elasticsearch.common.util.concurrent.AbstractRunnable.run(AbstractRunnable.java:37) [elasticsearch-7.5.2.jar:7.5.2]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_201-1-ojdkbuild]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_201-1-ojdkbuild]
at java.lang.Thread.run(Thread.java:748) [?:1.8.0_201-1-ojdkbuild]
[2020-02-16T16:21:57,411][DEBUG][o.e.a.s.TransportSearchAction] [IL105580WIN] [test][0], node[Dbq1AHCtSy-UbRY6AgxKCQ], [P], s[STARTED], a[id=jIBJqNtSTZ2Zq8XIn10eHA]: Failed to execute [SearchRequest{searchType=QUERY_THEN_FETCH, indices=[], indicesOptions=IndicesOptions[ignore_unavailable=false, allow_no_indices=true, expand_wildcards_open=true, expand_wildcards_closed=false, allow_aliases_to_multiple_indices=true, forbid_closed_indices=true, ignore_aliases=false, ignore_throttled=true], types=[], routing='null', preference='null', requestCache=null, scroll=null, maxConcurrentShardRequests=0, batchedReduceSize=512, preFilterShardSize=128, allowPartialSearchResults=true, localClusterAlias=null, getOrCreateAbsoluteStartMillis=-1, ccsMinimizeRoundtrips=true, source={"query":{"bool":{"filter":[{"range":{"dateTime":{"from":-316800000,"to":345354353,"include_lower":true,"include_upper":true,"boost":1.0}}}],"adjust_pure_negative":true,"boost":1.0}}}}]

@shirleysela shirleysela changed the title arithmetic_exception when using rangeQuery Elasticsearch exception [type=arithmetic_exception, reason=long overflow when using rangeQuery with big long Feb 16, 2020
@shirleysela shirleysela changed the title Elasticsearch exception [type=arithmetic_exception, reason=long overflow when using rangeQuery with big long Arithmetic_exception(long overflow) when using rangeQuery Feb 16, 2020
@romseygeek romseygeek added :Core/Infra/Core Core issues without another label :Search Foundations/Mapping Index mappings, including merging and defining field types labels Feb 17, 2020
@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-core-infra (:Core/Infra/Core)

@elasticmachine
Copy link
Collaborator

Pinging @elastic/es-search (:Search/Mapping)

@pgomulka pgomulka self-assigned this Feb 17, 2020
@pgomulka
Copy link
Contributor

hey @shirleysela thank you for reaching out
this actually works as expected. The reason you see a difference between 7.3 and newer versions is that we allowed parsial parsing of dates when using strict_date_optional_time. This is in accordance to is8601 spec . #47872
This means that when using strict_date_optional_time||epoch_millis and -316800000 Es will consider this to be just a year.
That year in turn is being stored as a java.time Instant which represents it as number of seconds since epoch -9997304560819200
In next step ES is trying to convert that instant into milliseconds - therefore has to call Instant.toEpochMilli method, which multiplies by 1000. That causes ArithmeticException as expected https://docs.oracle.com/javase/8/docs/api/java/time/Instant.html#toEpochMilli--

@pgomulka
Copy link
Contributor

strict_date_optional_time allows maximum 10digits for a year field. You can workaround by padding your epoch timestmap with 0s like "-000316800000"

@shirleysela
Copy link
Author

Thanks for your comment ;)
Is this change documented anywhere? I mean, when i use RangeQuery, should i start using epoch millis format?
For example:

QueryBuilders.rangeQuery((datetime)).gte(fromCreated.getTime()).lte(toCreated.getTime()).format("epoch_millis")

@pgomulka
Copy link
Contributor

not necessarily. You can still use a range query against date formatted with strict_date_optional_time like 2020-01-01T01:02:03.123Z

GET indexname2/_search
{
"query": {
"bool": {
"filter": [
{
"range": {
"datetime": {
"from": "2000-01-01T01:01:01",
"to": "2001-01-01T01:01:01",
"include_lower": true,
"include_upper": true,
"boost": 1
}
}
}
],
"adjust_pure_negative": true,
"boost": 1
}
}
}

@shirleysela
Copy link
Author

Thanks again for your response. If i got you right, then it's a big change of the behavior. Till now we used to query the data using the long which represents the date, and from now on all those longs (which are shorter than 10 digits) are translated to year and not to the expected date.

@pgomulka
Copy link
Contributor

you can still use just a long shorter than 10digits, but you have to use epoch_millis format.
if you use a default format strict_date_optional_time||epoch_millis
then numbers with less then 10digits will match with a year field of strict_date_optional_time

@shirleysela
Copy link
Author

Many Thanks

@centic9
Copy link
Contributor

centic9 commented Mar 22, 2020

That is an unfortunate regression from previous releases as it means one now needs to take care about format() even when specifying millisecond values everywhere.

Also format() is only allowed for date fields, so you need to do this date-specific handling also in cases where you have a generic query framework as you now need to know what the datatype is in filters and aggregations.

I agree that epoch-values are larger than 10 digits almost all the time (every date around 12.1.1970 is), but this "10digit" rule causes very hard to find regression bugs during upgrade as suddenly a value is interpreted as year or milliseconds depending on the input.

Naturally the suggestion will be to use custom format "epoch_millis" for dates during mapping/write-time, but this does not cover cases where large amounts of data are already indexed and cannot easily be rewritten with different format during upgrading from 6. to 7.

@centic9
Copy link
Contributor

centic9 commented Mar 22, 2020

FYI, another related regression which seems related to this one is that missing-value "-1" was possible for date-values before, but now fails:

Caused by: java.lang.IllegalArgumentException: failed to parse date field [-1] with format [strict_date_optional_time||epoch_millis]
	at com.dynatrace.esshadow7.elasticsearch.common.time.JavaDateFormatter.parse(JavaDateFormatter.java:169)
	at com.dynatrace.esshadow7.elasticsearch.common.time.JavaDateMathParser.parseDateTime(JavaDateMathParser.java:223)
	... 26 more
Caused by: NotSerializableExceptionWrapper[date_time_parse_exception: Failed to parse with all enclosed parsers]
	at com.dynatrace.esshadow7.elasticsearch.common.time.JavaDateFormatter.doParse(JavaDateFormatter.java:196)
	at com.dynatrace.esshadow7.elasticsearch.common.time.JavaDateFormatter.parse(JavaDateFormatter.java:167)
	... 27 more

Forcing "epoch_millis" format does not fix this one.

@pgomulka
Copy link
Contributor

@centic9 negative values with epoch_millis are not allowed #36793 so -1 as milliseconds since epoch with strict_date_optional_time||epoch_millis will fail. See the reasoning on the linked PR.
If you want to parse year -1 as per -0001-01-01T00:00Z use -0001

I will look into the problem with parsing epoch_millis shorter then 10digits.

@rjernst rjernst added Team:Core/Infra Meta label for core/infra team Team:Search Meta label for search team labels May 4, 2020
@rjernst rjernst added the needs:triage Requires assignment of a team area label label Dec 3, 2020
@pgomulka
Copy link
Contributor

the problem still exists. The PR is open, but needs to be rebased against master.

@pgomulka pgomulka removed the needs:triage Requires assignment of a team area label label Dec 14, 2020
pgomulka added a commit that referenced this issue Jun 4, 2021
…l_time (#73034)

We changed the default joda behaviour in strict_date_optional_time to
max 4 digits in a year. Java.time implementation should behave the same way.
At the same time date_optional_time should have 9digits for year part.

closes #52396
closes #72191
pgomulka added a commit to pgomulka/elasticsearch that referenced this issue Jun 4, 2021
…l_time (elastic#73034)

We changed the default joda behaviour in strict_date_optional_time to
max 4 digits in a year. Java.time implementation should behave the same way.
At the same time date_optional_time should have 9digits for year part.

closes elastic#52396
closes elastic#72191
pgomulka added a commit that referenced this issue Jun 7, 2021
…l_time backports(#73034) (#73750)

We changed the default joda behaviour in strict_date_optional_time to
max 4 digits in a year. Java.time implementation should behave the same way.
At the same time date_optional_time should have 9digits for year part.

closes #52396
closes #72191
backports #73034
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
:Core/Infra/Core Core issues without another label :Search Foundations/Mapping Index mappings, including merging and defining field types Team:Core/Infra Meta label for core/infra team Team:Search Foundations Meta label for the Search Foundations team in Elasticsearch
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants