What is the bug?
On a multi-shard index, FIRST(), LAST(), and TAKE() appear not to preserve a preceding PPL sort.
The same query returns the expected values on a one-shard index. earliest() and latest() remain correct over the same documents.
Reproduction
Create identical one-shard and five-shard indices:
for SH in 1 5; do
curl -XDELETE "localhost:9200/rp_$SH"
curl -XPUT "localhost:9200/rp_$SH" -H 'Content-Type: application/json' -d "{
\"settings\":{\"number_of_shards\":$SH,\"number_of_replicas\":0},
\"mappings\":{\"properties\":{\"@timestamp\":{\"type\":\"date\"},\"txt\":{\"type\":\"keyword\"}}}}
}"
curl -XPOST "localhost:9200/rp_$SH/_bulk?refresh=true" \
-H 'Content-Type: application/x-ndjson' --data-binary '
{"index":{"_id":"1"}}
{"@timestamp":"2024-01-01T10:00:00Z","txt":"a"}
{"index":{"_id":"2"}}
{"@timestamp":"2024-01-02T10:00:00Z","txt":"b"}
{"index":{"_id":"3"}}
{"@timestamp":"2024-01-03T10:00:00Z","txt":"c"}
'
done
Run against each index:
source=rp_N
| sort @timestamp
| stats FIRST(@timestamp), LAST(@timestamp), TAKE(@timestamp, 2),
earliest(@timestamp), latest(@timestamp)
Observed results:
1 shard: FIRST=01-01 LAST=01-03 TAKE=[01-01,01-02] earliest=01-01 latest=01-03
5 shards: FIRST=01-03 LAST=01-03 TAKE=[01-03,01-02] earliest=01-01 latest=01-03
The five-shard result is repeatable, but does not follow the explicit timestamp ordering.
Existing integration-test failures
The existing alias-field tests show the same issue with different shard placement:
CalciteAliasFieldAggregationIT::testFirstWithAliasField
query: source=%s | sort @timestamp | stats FIRST(@timestamp)
expected: 2024-01-01 10:00:00
actual: 2024-01-02 10:00:00
CalciteAliasFieldAggregationIT::testLastWithAliasField
query: source=%s | sort @timestamp | stats LAST(@timestamp)
expected: 2024-01-03 10:00:00
actual: 2024-01-02 10:00:00
CalciteAliasFieldAggregationIT::testTakeWithAliasField
query: source=%s | sort @timestamp | stats TAKE(@timestamp, 2)
expected: [2024-01-01, 2024-01-02]
actual: [2024-01-01, 2024-01-03]
Expected behavior
After sort @timestamp, FIRST() and LAST() should return the first and last values in that order, independent of shard count.
For TAKE(), the documentation currently says result order is not guaranteed. However, it would be useful to clarify whether the preceding sort should at least determine which values are selected.
Possible implementation clue
This may be related to how these aggregations are pushed down as top_hits:
FIRST -> createTopHitsBuilder(..., 1, true, false, null, null)
TAKE -> createTopHitsBuilder(..., size, true, false, null, null)
LAST -> createTopHitsBuilder(..., 1, true, true, "_doc", SortOrder.DESC)
FIRST and TAKE do not pass a sort key, while LAST uses _doc, which is not a globally comparable document-order key across shards. The preceding PPL collation may therefore not reach the generated top_hits aggregation. This is only a possible explanation and needs maintainer confirmation.
This also appears consistent with the limitation noted in #5537: adding an explicit sort does not stabilize stats first()/last()/take() on multi-shard execution.
Environment
- OpenSearch 3.7.0
opensearch-sql plugin
- Single node
- One versus five primary shards
- No replicas
What is the bug?
On a multi-shard index,
FIRST(),LAST(), andTAKE()appear not to preserve a preceding PPLsort.The same query returns the expected values on a one-shard index.
earliest()andlatest()remain correct over the same documents.Reproduction
Create identical one-shard and five-shard indices:
Run against each index:
Observed results:
The five-shard result is repeatable, but does not follow the explicit timestamp ordering.
Existing integration-test failures
The existing alias-field tests show the same issue with different shard placement:
Expected behavior
After
sort @timestamp,FIRST()andLAST()should return the first and last values in that order, independent of shard count.For
TAKE(), the documentation currently says result order is not guaranteed. However, it would be useful to clarify whether the preceding sort should at least determine which values are selected.Possible implementation clue
This may be related to how these aggregations are pushed down as
top_hits:FIRSTandTAKEdo not pass a sort key, whileLASTuses_doc, which is not a globally comparable document-order key across shards. The preceding PPL collation may therefore not reach the generatedtop_hitsaggregation. This is only a possible explanation and needs maintainer confirmation.This also appears consistent with the limitation noted in #5537: adding an explicit sort does not stabilize
stats first()/last()/take()on multi-shard execution.Environment
opensearch-sqlplugin