Skip to content

Commit 9d50bcb

Browse files
committed
Support Sort pushdown (opensearch-project#3620)
* Support Sort pushdown Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> Copy traits to logical index scan after pushing down sort Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> Allow pushing down multiple times Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Merge multiple sort when occurs Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Update trendline explain IT Additionally correct merge collation method Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Re-index collations when pushing down projection Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Support sort pushdown with aggregation when aggregated fields are not in sort by fields Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Update explain_output.json Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Support multi-sort Additionally remove sort when pushing down aggregation after adding collation by pushing down sort Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Sanitize collations when sort can't be pushed down Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Test explaining sort | stats avg Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Test sort date Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Chores: reorder util functions Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Pass null direction when pushing down sort Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Convert to keyword fields when sorting opensearch text fields Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Test explaining sort after rename Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Push down sort-then-limit, while only pushdown limit when limit-then-sort Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Fix flaky test related to irregular number in some locales in datetime IT Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> * Override existing collations where there are more than one order clauses Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> --------- Signed-off-by: Yuanchun Shen <yuanchu@amazon.com> (cherry picked from commit 870b82c)
1 parent 5175d78 commit 9d50bcb

27 files changed

Lines changed: 616 additions & 29 deletions

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalcitePPLSortIT.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,4 +218,22 @@ public void testSortWithNullValue() throws IOException {
218218
rows("Elinor", null),
219219
rows("Virginia", null));
220220
}
221+
222+
@Test
223+
public void testSortDate() throws IOException {
224+
JSONObject result =
225+
executeQuery(
226+
String.format(
227+
"source=%s | sort birthdate | fields firstname, birthdate", TEST_INDEX_BANK));
228+
verifySchema(result, schema("firstname", "string"), schema("birthdate", "timestamp"));
229+
verifyDataRowsInOrder(
230+
result,
231+
rows("Amber JOHnny", "2017-10-23 00:00:00"),
232+
rows("Hattie", "2017-11-20 00:00:00"),
233+
rows("Nanette", "2018-06-23 00:00:00"),
234+
rows("Elinor", "2018-06-27 00:00:00"),
235+
rows("Dillard", "2018-08-11 00:00:00"),
236+
rows("Virginia", "2018-08-19 00:00:00"),
237+
rows("Dale", "2018-11-13 23:33:20"));
238+
}
221239
}

integ-test/src/test/java/org/opensearch/sql/calcite/remote/CalciteSortCommandIT.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55

66
package org.opensearch.sql.calcite.remote;
77

8+
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_BANK;
9+
import static org.opensearch.sql.util.MatcherUtils.rows;
10+
import static org.opensearch.sql.util.MatcherUtils.verifyOrder;
11+
12+
import java.io.IOException;
13+
import org.json.JSONObject;
14+
import org.junit.Test;
815
import org.opensearch.sql.ppl.SortCommandIT;
916

1017
public class CalciteSortCommandIT extends SortCommandIT {
@@ -14,4 +21,12 @@ public void init() throws Exception {
1421
enableCalcite();
1522
disallowCalciteFallback();
1623
}
24+
25+
// TODO: Move this test to SortCommandIT once head-then-sort is fixed in v2.
26+
@Test
27+
public void testHeadThenSort() throws IOException {
28+
JSONObject result =
29+
executeQuery(String.format("source=%s | head 2 | sort age | fields age", TEST_INDEX_BANK));
30+
verifyOrder(result, rows(32), rows(36));
31+
}
1732
}

integ-test/src/test/java/org/opensearch/sql/calcite/standalone/CalcitePPLDateTimeBuiltinFunctionIT.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -423,15 +423,18 @@ public void testWeekAndWeekOfYear() throws IOException {
423423

424424
@Test
425425
public void testWeekAndWeekOfYearWithFilter() throws IOException {
426+
int week19840412 = getYearWeek(LocalDate.of(1984, 4, 12), 0) % 100;
426427
JSONObject actual =
427428
executeQuery(
428429
String.format(
430+
Locale.ROOT,
429431
"source=%s | fields strict_date_optional_time"
430432
+ "| where YEAR(strict_date_optional_time) < 2000"
431-
+ "| where WEEK(DATE(strict_date_optional_time)) = 15"
433+
+ "| where WEEK(DATE(strict_date_optional_time)) = %d"
432434
+ "| stats COUNT() AS CNT "
433435
+ "| head 1 ",
434-
TEST_INDEX_DATE_FORMATS));
436+
TEST_INDEX_DATE_FORMATS,
437+
week19840412));
435438

436439
verifySchema(actual, schema("CNT", "bigint"));
437440

@@ -1005,6 +1008,8 @@ public void testDateFormatAndDatetimeAndFromDays() throws IOException {
10051008
offsetUTC.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
10061009
String expectedDatetimeAtPlus8 =
10071010
offsetPlus8.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
1011+
int week19840412 = getYearWeek(LocalDate.of(1984, 4, 12), 0) % 100;
1012+
int week19840412Mode1 = getYearWeek(LocalDate.of(1984, 4, 12), 1) % 100;
10081013

10091014
verifyDataRows(
10101015
actual,
@@ -1017,8 +1022,8 @@ public void testDateFormatAndDatetimeAndFromDays() throws IOException {
10171022
"2017-11-02",
10181023
expectedDatetimeAtPlus8,
10191024
expectedDatetimeAtUTC,
1020-
"15 1984 15",
1021-
"15 15 1984",
1025+
String.format(Locale.ROOT, "%d 1984 %d", week19840412, week19840412),
1026+
String.format(Locale.ROOT, "%d %d 1984", week19840412Mode1, week19840412Mode1),
10221027
"09:07:42.000123"));
10231028
}
10241029

@@ -1453,4 +1458,8 @@ public void testMicrosecond() throws IOException {
14531458
schema("m5", "int"));
14541459
verifyDataRows(actual, rows(0, 0, 0, 123456, 123456));
14551460
}
1461+
1462+
private static int getYearWeek(LocalDate date, int mode) {
1463+
return exprYearweek(new ExprDateValue(date), new ExprIntegerValue(mode)).integerValue();
1464+
}
14561465
}

integ-test/src/test/java/org/opensearch/sql/ppl/ExplainIT.java

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ public void testFilterAndAggPushDownExplain() throws IOException {
7474

7575
@Test
7676
public void testSortPushDownExplain() throws IOException {
77-
// TODO fix after https://github.com/opensearch-project/sql/issues/3380
7877
String expected =
7978
isCalciteEnabled()
8079
? loadFromFile("expectedOutput/calcite/explain_sort_push.json")
@@ -89,6 +88,117 @@ public void testSortPushDownExplain() throws IOException {
8988
+ "| fields age"));
9089
}
9190

91+
@Test
92+
public void testSortWithAggregationExplain() throws IOException {
93+
// Sorts whose by fields are aggregators should not be pushed down
94+
String expected =
95+
isCalciteEnabled()
96+
? loadFromFile("expectedOutput/calcite/explain_sort_agg_push.json")
97+
: loadFromFile("expectedOutput/ppl/explain_sort_agg_push.json");
98+
99+
assertJsonEqualsIgnoreId(
100+
expected,
101+
explainQueryToString(
102+
"source=opensearch-sql_test_index_account"
103+
+ "| stats avg(age) AS avg_age by state, city "
104+
+ "| sort avg_age"));
105+
106+
// sorts whose by fields are not aggregators can be pushed down.
107+
// This test is covered in testExplain
108+
}
109+
110+
@Test
111+
public void testMultiSortPushDownExplain() throws IOException {
112+
// TODO: Fix the expected output in expectedOutput/ppl/explain_multi_sort_push.json (v2)
113+
// balance and gender should take precedence over account_number and firstname
114+
String expected =
115+
isCalciteEnabled()
116+
? loadFromFile("expectedOutput/calcite/explain_multi_sort_push.json")
117+
: loadFromFile("expectedOutput/ppl/explain_multi_sort_push.json");
118+
119+
assertJsonEqualsIgnoreId(
120+
expected,
121+
explainQueryToString(
122+
"source=opensearch-sql_test_index_account "
123+
+ "| sort account_number, firstname, address, balance "
124+
+ "| sort - balance, - gender, address "
125+
+ "| fields account_number, firstname, address, balance, gender"));
126+
}
127+
128+
@Test
129+
public void testSortThenAggregatePushDownExplain() throws IOException {
130+
// TODO: Remove pushed-down sort in DSL in expectedOutput/ppl/explain_sort_then_agg_push.json
131+
// existing collations should be eliminated when pushing down aggregations (v2)
132+
String expected =
133+
isCalciteEnabled()
134+
? loadFromFile("expectedOutput/calcite/explain_sort_then_agg_push.json")
135+
: loadFromFile("expectedOutput/ppl/explain_sort_then_agg_push.json");
136+
137+
assertJsonEqualsIgnoreId(
138+
expected,
139+
explainQueryToString(
140+
"source=opensearch-sql_test_index_account"
141+
+ "| sort balance, age "
142+
+ "| stats avg(balance) by state"));
143+
}
144+
145+
@Test
146+
public void testSortWithRenameExplain() throws IOException {
147+
String expected =
148+
isCalciteEnabled()
149+
? loadFromFile("expectedOutput/calcite/explain_sort_rename_push.json")
150+
: loadFromFile("expectedOutput/ppl/explain_sort_rename_push.json");
151+
152+
assertJsonEqualsIgnoreId(
153+
expected,
154+
explainQueryToString(
155+
"source=opensearch-sql_test_index_account "
156+
+ "| rename firstname as name "
157+
+ "| eval alias = name "
158+
+ "| sort alias "
159+
+ "| fields alias"));
160+
}
161+
162+
/**
163+
* Pushdown SORT and LIMIT Sort should be pushed down since DSL process sort before limit when
164+
* they coexist
165+
*/
166+
@Test
167+
public void testSortThenLimitExplain() throws IOException {
168+
String expected =
169+
isCalciteEnabled()
170+
? loadFromFile("expectedOutput/calcite/explain_sort_then_limit_push.json")
171+
: loadFromFile("expectedOutput/ppl/explain_sort_then_limit_push.json");
172+
assertJsonEqualsIgnoreId(
173+
expected,
174+
explainQueryToString(
175+
"source=opensearch-sql_test_index_account"
176+
+ "| sort age "
177+
+ "| head 5 "
178+
+ "| fields age"));
179+
}
180+
181+
/**
182+
* Push down LIMIT only Sort should NOT be pushed down since DSL process limit before sort when
183+
* they coexist
184+
*/
185+
@Test
186+
public void testLimitThenSortExplain() throws IOException {
187+
// TODO: Fix the expected output in expectedOutput/ppl/explain_limit_then_sort_push.json (v2)
188+
// limit-then-sort should not be pushed down.
189+
String expected =
190+
isCalciteEnabled()
191+
? loadFromFile("expectedOutput/calcite/explain_limit_then_sort_push.json")
192+
: loadFromFile("expectedOutput/ppl/explain_limit_then_sort_push.json");
193+
assertJsonEqualsIgnoreId(
194+
expected,
195+
explainQueryToString(
196+
"source=opensearch-sql_test_index_account"
197+
+ "| head 5 "
198+
+ "| sort age "
199+
+ "| fields age"));
200+
}
201+
92202
@Test
93203
public void testLimitPushDownExplain() throws IOException {
94204
String expected =
@@ -240,6 +350,7 @@ public void testTrendlineWithSortPushDownExplain() throws IOException {
240350
? loadFromFile("expectedOutput/calcite/explain_trendline_sort_push.json")
241351
: loadFromFile("expectedOutput/ppl/explain_trendline_sort_push.json");
242352

353+
// Sort will not be pushed down because there's a head before it.
243354
assertJsonEqualsIgnoreId(
244355
expected,
245356
explainQueryToString(

integ-test/src/test/java/org/opensearch/sql/ppl/SortCommandIT.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,4 +155,11 @@ public void testSortMultipleFields() throws IOException {
155155
String.format("source=%s | sort dog_name, age | fields dog_name, age", TEST_INDEX_DOG));
156156
verifyOrder(result, rows("rex", 2), rows("snoopy", 4));
157157
}
158+
159+
@Test
160+
public void testSortThenHead() throws IOException {
161+
JSONObject result =
162+
executeQuery(String.format("source=%s | sort age | head 2 | fields age", TEST_INDEX_BANK));
163+
verifyOrder(result, rows(28), rows(32));
164+
}
158165
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"calcite": {
3+
"logical": "LogicalSort(sort0=[$0], dir0=[ASC])\n LogicalProject(age=[$8])\n LogicalSort(sort0=[$8], dir0=[ASC])\n LogicalSort(fetch=[5])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4+
"physical": "EnumerableSort(sort0=[$0], dir0=[ASC])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[LIMIT->5, PROJECT->[age]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":5,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"age\"],\"excludes\":[]}}, requestedTotalSize=5, pageSize=null, startFrom=0)])\n"
5+
}
6+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"calcite": {
3+
"logical": "LogicalSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC], dir1=[DESC], dir2=[ASC])\n LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4])\n LogicalSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC], dir1=[DESC], dir2=[ASC])\n LogicalSort(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC], dir1=[ASC], dir2=[ASC], dir3=[ASC])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4+
"physical": "CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[account_number, firstname, address, balance, gender], SORT->[{\n \"balance\" : {\n \"order\" : \"desc\",\n \"missing\" : \"_first\"\n }\n}, {\n \"gender\" : {\n \"order\" : \"desc\",\n \"missing\" : \"_first\"\n }\n}, {\n \"address\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_last\"\n }\n}]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"account_number\",\"firstname\",\"address\",\"balance\",\"gender\"],\"excludes\":[]},\"sort\":[{\"balance\":{\"order\":\"desc\",\"missing\":\"_first\"}},{\"gender\":{\"order\":\"desc\",\"missing\":\"_first\"}},{\"address\":{\"order\":\"asc\",\"missing\":\"_last\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
5+
}
6+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"calcite": {
33
"logical": "LogicalProject(age2=[$2])\n LogicalFilter(condition=[<=($3, 1)])\n LogicalProject(avg_age=[$0], state=[$1], age2=[$2], _row_number_=[ROW_NUMBER() OVER (PARTITION BY $2 ORDER BY $2)])\n LogicalFilter(condition=[IS NOT NULL($2)])\n LogicalProject(avg_age=[$0], state=[$1], age2=[+($0, 2)])\n LogicalSort(sort0=[$1], dir0=[ASC])\n LogicalProject(avg_age=[$2], state=[$0], city=[$1])\n LogicalAggregate(group=[{0, 1}], avg_age=[AVG($2)])\n LogicalProject(state=[$7], city=[$5], age=[$8])\n LogicalFilter(condition=[>($8, 30)])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4-
"physical": "EnumerableCalc(expr#0..2=[{inputs}], expr#3=[1], expr#4=[<=($t2, $t3)], age2=[$t1], $condition=[$t4])\n EnumerableWindow(window#0=[window(partition {1} order by [1] rows between UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])\n EnumerableCalc(expr#0..2=[{inputs}], expr#3=[2], expr#4=[+($t2, $t3)], expr#5=[IS NOT NULL($t2)], state=[$t0], age2=[$t4], $condition=[$t5])\n EnumerableSort(sort0=[$0], dir0=[ASC])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[FILTER->>($8, 30), PROJECT->[state, city, age], AGGREGATION->rel#:LogicalAggregate.NONE.[](input=RelSubset#,group={0, 1},avg_age=AVG($2))], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":0,\"timeout\":\"1m\",\"query\":{\"range\":{\"age\":{\"from\":30,\"to\":null,\"include_lower\":false,\"include_upper\":true,\"boost\":1.0}}},\"_source\":{\"includes\":[\"state\",\"city\",\"age\"],\"excludes\":[]},\"sort\":[{\"_doc\":{\"order\":\"asc\"}}],\"aggregations\":{\"composite_buckets\":{\"composite\":{\"size\":1000,\"sources\":[{\"state\":{\"terms\":{\"field\":\"state.keyword\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}},{\"city\":{\"terms\":{\"field\":\"city.keyword\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}}]},\"aggregations\":{\"avg_age\":{\"avg\":{\"field\":\"age\"}}}}}}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
4+
"physical": "EnumerableCalc(expr#0..2=[{inputs}], expr#3=[1], expr#4=[<=($t2, $t3)], age2=[$t1], $condition=[$t4])\n EnumerableWindow(window#0=[window(partition {1} order by [1] rows between UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])\n EnumerableCalc(expr#0..2=[{inputs}], expr#3=[2], expr#4=[+($t2, $t3)], expr#5=[IS NOT NULL($t2)], state=[$t1], age2=[$t4], $condition=[$t5])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[city, state, age], FILTER->>($2, 30), AGGREGATION->rel#1142:LogicalAggregate.NONE.[](input=RelSubset#1097,group={0, 1},avg_age=AVG($2)), SORT->[{\n \"state.keyword\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_last\"\n }\n}]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":0,\"timeout\":\"1m\",\"query\":{\"range\":{\"age\":{\"from\":30,\"to\":null,\"include_lower\":false,\"include_upper\":true,\"boost\":1.0}}},\"_source\":{\"includes\":[\"city\",\"state\",\"age\"],\"excludes\":[]},\"sort\":[{\"state.keyword\":{\"order\":\"asc\",\"missing\":\"_last\"}}],\"aggregations\":{\"composite_buckets\":{\"composite\":{\"size\":1000,\"sources\":[{\"city\":{\"terms\":{\"field\":\"city.keyword\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}},{\"state\":{\"terms\":{\"field\":\"state.keyword\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}}]},\"aggregations\":{\"avg_age\":{\"avg\":{\"field\":\"age\"}}}}}}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
55
}
66
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"calcite": {
3+
"logical": "LogicalSort(sort0=[$0], dir0=[ASC])\n LogicalProject(avg_age=[$2], state=[$0], city=[$1])\n LogicalAggregate(group=[{0, 1}], avg_age=[AVG($2)])\n LogicalProject(state=[$7], city=[$5], age=[$8])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4+
"physical": "EnumerableSort(sort0=[$0], dir0=[ASC])\n EnumerableCalc(expr#0..2=[{inputs}], avg_age=[$t2], state=[$t0], city=[$t1])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[state, city, age], AGGREGATION->rel#2023:LogicalAggregate.NONE.[](input=RelSubset#2022,group={0, 1},avg_age=AVG($2))], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"state\",\"city\",\"age\"],\"excludes\":[]},\"aggregations\":{\"composite_buckets\":{\"composite\":{\"size\":1000,\"sources\":[{\"state\":{\"terms\":{\"field\":\"state.keyword\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}},{\"city\":{\"terms\":{\"field\":\"city.keyword\",\"missing_bucket\":true,\"missing_order\":\"first\",\"order\":\"asc\"}}}]},\"aggregations\":{\"avg_age\":{\"avg\":{\"field\":\"age\"}}}}}}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
5+
}
6+
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"calcite": {
33
"logical": "LogicalSort(sort0=[$0], dir0=[ASC])\n LogicalProject(age=[$8])\n LogicalFilter(condition=[>($8, 30)])\n LogicalSort(sort0=[$8], dir0=[ASC])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4-
"physical": "EnumerableCalc(expr#0=[{inputs}], expr#1=[30], expr#2=[>($t0, $t1)], age=[$t0], $condition=[$t2])\n EnumerableSort(sort0=[$0], dir0=[ASC])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[age]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"age\"],\"excludes\":[]}}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
4+
"physical": "CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[age], SORT->[{\n \"age\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_last\"\n }\n}], FILTER->>($0, 30)], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"query\":{\"range\":{\"age\":{\"from\":30,\"to\":null,\"include_lower\":false,\"include_upper\":true,\"boost\":1.0}}},\"_source\":{\"includes\":[\"age\"],\"excludes\":[]},\"sort\":[{\"age\":{\"order\":\"asc\",\"missing\":\"_last\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
55
}
66
}

0 commit comments

Comments
 (0)