Skip to content

Commit e83f741

Browse files
authored
Pushdown sort by complex expressions to scan (#4750)
* Pushdown sort expression to scan Signed-off-by: Songkan Tang <[email protected]> * Refactor a bit of SortExprIndexScanRule Signed-off-by: Songkan Tang <[email protected]> * Simplify some code and add more explain tests Signed-off-by: Songkan Tang <[email protected]> * Support null ordering for sort expression pushdown Signed-off-by: Songkan Tang <[email protected]> * Attempt to fix security tests and add more test cases Signed-off-by: Songkan Tang <[email protected]> * Address comments Signed-off-by: Songkan Tang <[email protected]> * Address more comments Signed-off-by: Songkan Tang <[email protected]> --------- Signed-off-by: Songkan Tang <[email protected]>
1 parent b5c8a54 commit e83f741

File tree

39 files changed

+1820
-41
lines changed

39 files changed

+1820
-41
lines changed

core/src/main/java/org/opensearch/sql/calcite/utils/PlanUtils.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ public interface PlanUtils {
6868
String ROW_NUMBER_COLUMN_FOR_STREAMSTATS = "__stream_seq__";
6969
String ROW_NUMBER_COLUMN_FOR_CHART = "_row_number_chart_";
7070

71+
String DIRECTION = "DIRECTION";
72+
String NULL_DIRECTION = "NULL_DIRECTION";
73+
7174
static SpanUnit intervalUnitToSpanUnit(IntervalUnit unit) {
7275
return switch (unit) {
7376
case MICROSECOND -> SpanUnit.MICROSECOND;
@@ -532,6 +535,23 @@ static boolean sortByFieldsOnly(Sort sort) {
532535
return !sort.getCollation().getFieldCollations().isEmpty() && sort.fetch == null;
533536
}
534537

538+
/**
539+
* Check if the sort collation points to non field project expression.
540+
*
541+
* @param sort the sort operator adding sort order over project
542+
* @param project project operation that may contain non field expressions
543+
* @return flag to indicate whether non field project expression will be sorted
544+
*/
545+
static boolean sortReferencesExpr(Sort sort, Project project) {
546+
if (sort.getCollation().getFieldCollations().isEmpty()) {
547+
return false;
548+
}
549+
return sort.getCollation().getFieldCollations().stream()
550+
.anyMatch(
551+
relFieldCollation ->
552+
project.getProjects().get(relFieldCollation.getFieldIndex()) instanceof RexCall);
553+
}
554+
535555
/**
536556
* Get a string representation of the argument types expressed in ExprType for error messages.
537557
*

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -872,6 +872,80 @@ public void testSimpleSortExpressionPushDownWithOnlyExprProjected() throws Excep
872872
assertJsonEqualsIgnoreId(expected, result);
873873
}
874874

875+
@Test
876+
public void testComplexSortExpressionPushDownExplain() throws Exception {
877+
String query =
878+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance | sort age2 | fields age,"
879+
+ " age2";
880+
var result = explainQueryYaml(query);
881+
String expected = loadExpectedPlan("explain_complex_sort_expr_push.yaml");
882+
assertYamlEqualsIgnoreId(expected, result);
883+
}
884+
885+
@Test
886+
public void testComplexSortExpressionPushDownWithOnlyExprProjected() throws Exception {
887+
String query =
888+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance | sort age2 | fields"
889+
+ " age2";
890+
var result = explainQueryYaml(query);
891+
String expected = loadExpectedPlan("explain_complex_sort_expr_single_expr_output_push.yaml");
892+
assertYamlEqualsIgnoreId(expected, result);
893+
}
894+
895+
@Test
896+
public void testComplexSortExpressionPushDownWithoutExprProjected() throws Exception {
897+
String query =
898+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance | sort age2 | fields age";
899+
var result = explainQueryYaml(query);
900+
String expected = loadExpectedPlan("explain_complex_sort_expr_no_expr_output_push.yaml");
901+
assertYamlEqualsIgnoreId(expected, result);
902+
}
903+
904+
@Test
905+
public void testComplexSortExpressionProjectThenSort() throws Exception {
906+
String query =
907+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance | fields age, age2 | sort"
908+
+ " age2";
909+
var result = explainQueryYaml(query);
910+
String expected = loadExpectedPlan("explain_complex_sort_expr_project_then_sort.yaml");
911+
assertYamlEqualsIgnoreId(expected, result);
912+
}
913+
914+
/*
915+
* TODO: A potential optimization is to leverage RexSimplify to simplify -(+($10, $7), $10) to $7
916+
* Above simplification can only work when $10 is nonnull and there is no precision loss of
917+
* expression calculation
918+
*/
919+
@Test
920+
public void testSortNestedComplexExpression() throws Exception {
921+
String query =
922+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance, age3 = age2 - age | sort"
923+
+ " age3";
924+
var result = explainQueryYaml(query);
925+
String expected = loadExpectedPlan("explain_complex_sort_nested_expr.yaml");
926+
assertYamlEqualsIgnoreId(expected, result);
927+
}
928+
929+
@Test
930+
public void testSortComplexExpressionThenSortField() throws Exception {
931+
String query =
932+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance | sort age2, age | eval"
933+
+ " balance2 = abs(balance) | sort age";
934+
var result = explainQueryYaml(query);
935+
String expected = loadExpectedPlan("explain_complex_sort_then_field_sort.yaml");
936+
assertYamlEqualsIgnoreId(expected, result);
937+
}
938+
939+
@Test
940+
public void testSortComplexExprMixedWithSimpleExpr() throws Exception {
941+
String query =
942+
"source=opensearch-sql_test_index_bank| eval age2 = age + balance, balance2 = balance + 1 |"
943+
+ " sort age2, balance2 ";
944+
var result = explainQueryYaml(query);
945+
String expected = loadExpectedPlan("explain_sort_complex_and_simple_expr.yaml");
946+
assertYamlEqualsIgnoreId(expected, result);
947+
}
948+
875949
@Test
876950
public void testRexExplain() throws IOException {
877951
String query =

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

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_DOG;
1111
import static org.opensearch.sql.legacy.TestsConstants.TEST_INDEX_WEBLOGS;
1212
import static org.opensearch.sql.util.MatcherUtils.rows;
13+
import static org.opensearch.sql.util.MatcherUtils.schema;
1314
import static org.opensearch.sql.util.MatcherUtils.verifyOrder;
15+
import static org.opensearch.sql.util.MatcherUtils.verifySchema;
1416

1517
import java.io.IOException;
1618
import java.util.ArrayList;
@@ -321,4 +323,95 @@ public void testHeadThenSort() throws IOException {
321323
verifyOrder(result, rows(28), rows(32));
322324
}
323325
}
326+
327+
@Test
328+
public void testSortComplexExpression() throws IOException {
329+
JSONObject result =
330+
executeQuery(
331+
String.format(
332+
"source=%s | eval age2 = age + balance | sort age2 | fields age, balance, age2",
333+
TEST_INDEX_BANK));
334+
verifyOrder(
335+
result,
336+
rows(33, 4180, 4213),
337+
rows(36, 5686, 5722),
338+
rows(36, 16418, 16454),
339+
rows(28, 32838, 32866),
340+
rows(32, 39225, 39257),
341+
rows(39, 40540, 40579),
342+
rows(34, 48086, 48120));
343+
}
344+
345+
@Test
346+
public void testSortComplexExpressionThenHead() throws IOException {
347+
JSONObject result =
348+
executeQuery(
349+
String.format(
350+
"source=%s | eval age2 = age + balance | sort age2 | fields age, balance, age2 |"
351+
+ " head 2",
352+
TEST_INDEX_BANK));
353+
verifyOrder(result, rows(33, 4180, 4213), rows(36, 5686, 5722));
354+
}
355+
356+
@Test
357+
public void testPushdownSortStringExpression() throws IOException {
358+
String ppl =
359+
String.format(
360+
"source=%s | eval firstname2 = substring(firstname, 1, 3) | sort firstname2 | fields"
361+
+ " firstname2, firstname",
362+
TEST_INDEX_BANK_WITH_NULL_VALUES);
363+
364+
JSONObject result = executeQuery(ppl);
365+
verifySchema(result, schema("firstname2", "string"), schema("firstname", "string"));
366+
verifyOrder(
367+
result,
368+
rows("Amb", "Amber JOHnny"),
369+
rows("Dal", "Dale"),
370+
rows("Dil", "Dillard"),
371+
rows("Eli", "Elinor"),
372+
rows("Hat", "Hattie"),
373+
rows("Nan", "Nanette"),
374+
rows("Vir", "Virginia"));
375+
}
376+
377+
@Test
378+
public void testPushdownSortExpressionContainsNull() throws IOException {
379+
String ppl =
380+
String.format(
381+
"source=%s | eval balance2 = abs(balance) | sort -balance2 | fields balance, balance2",
382+
TEST_INDEX_BANK_WITH_NULL_VALUES);
383+
384+
JSONObject result = executeQuery(ppl);
385+
verifySchema(result, schema("balance", "bigint"), schema("balance2", "bigint"));
386+
verifyOrder(
387+
result,
388+
rows(48086, 48086),
389+
rows(39225, 39225),
390+
rows(32838, 32838),
391+
rows(4180, 4180),
392+
rows(null, null),
393+
rows(null, null),
394+
rows(null, null));
395+
}
396+
397+
@Test
398+
public void testPushdownSortExpressionWithMixedFieldSort() throws IOException {
399+
String ppl =
400+
String.format(
401+
"source=%s | eval balance2 = abs(balance) | sort -balance2, account_number | fields"
402+
+ " balance2, account_number",
403+
TEST_INDEX_BANK_WITH_NULL_VALUES);
404+
405+
JSONObject result = executeQuery(ppl);
406+
verifySchema(result, schema("balance2", "bigint"), schema("account_number", "bigint"));
407+
verifyOrder(
408+
result,
409+
rows(48086, 32),
410+
rows(39225, 1),
411+
rows(32838, 13),
412+
rows(4180, 18),
413+
rows(null, 6),
414+
rows(null, 20),
415+
rows(null, 25));
416+
}
324417
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
calcite:
2+
logical: |
3+
LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])
4+
LogicalProject(age=[$10])
5+
LogicalSort(sort0=[$19], dir0=[ASC-nulls-first])
6+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], birthdate=[$3], gender=[$4], city=[$5], lastname=[$6], balance=[$7], employer=[$8], state=[$9], age=[$10], email=[$11], male=[$12], _id=[$13], _index=[$14], _score=[$15], _maxscore=[$16], _sort=[$17], _routing=[$18], age2=[+($10, $7)])
7+
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
8+
physical: |
9+
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[SORT_EXPR->[+($10, $7) ASCENDING NULLS_FIRST], LIMIT->10000, PROJECT->[age]], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":10000,"timeout":"1m","_source":{"includes":["age"],"excludes":[]},"sort":[{"_script":{"script":{"source":"{\"langType\":\"calcite\",\"script\":\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQA0HsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJJTlRFR0VSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYmFsYW5jZSIKICAgIH0KICBdLAogICJudWxsYWJsZSI6IGZhbHNlCn10AARleHBydADFewogICJvcCI6IHsKICAgICJuYW1lIjogIisiLAogICAgImtpbmQiOiAiUExVUyIsCiAgICAic3ludGF4IjogIkJJTkFSWSIKICB9LAogICJvcGVyYW5kcyI6IFsKICAgIHsKICAgICAgImlucHV0IjogMCwKICAgICAgIm5hbWUiOiAiJDAiCiAgICB9LAogICAgewogICAgICAiaW5wdXQiOiAxLAogICAgICAibmFtZSI6ICIkMSIKICAgIH0KICBdCn10AApmaWVsZFR5cGVzc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAJ0AAdiYWxhbmNlfnIAKW9yZy5vcGVuc2VhcmNoLnNxbC5kYXRhLnR5cGUuRXhwckNvcmVUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAETE9OR3QAA2FnZX5xAH4ACnQAB0lOVEVHRVJ4eA==\"}","lang":"opensearch_compounded_script","params":{"NULL_DIRECTION":"FIRST","DIRECTION":"ASCENDING","utcTimestamp": 0}},"type":"number","order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
calcite:
2+
logical: |
3+
LogicalSystemLimit(sort0=[$1], dir0=[ASC-nulls-first], fetch=[10000], type=[QUERY_SIZE_LIMIT])
4+
LogicalSort(sort0=[$1], dir0=[ASC-nulls-first])
5+
LogicalProject(age=[$10], age2=[+($10, $7)])
6+
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
7+
physical: |
8+
EnumerableCalc(expr#0..1=[{inputs}], expr#2=[+($t0, $t1)], age=[$t0], $f1=[$t2])
9+
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[age, balance], SORT_EXPR->[+($0, $1) ASCENDING NULLS_FIRST], LIMIT->10000], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":10000,"timeout":"1m","_source":{"includes":["age","balance"],"excludes":[]},"sort":[{"_script":{"script":{"source":"{\"langType\":\"calcite\",\"script\":\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQA0HsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJJTlRFR0VSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYmFsYW5jZSIKICAgIH0KICBdLAogICJudWxsYWJsZSI6IGZhbHNlCn10AARleHBydADFewogICJvcCI6IHsKICAgICJuYW1lIjogIisiLAogICAgImtpbmQiOiAiUExVUyIsCiAgICAic3ludGF4IjogIkJJTkFSWSIKICB9LAogICJvcGVyYW5kcyI6IFsKICAgIHsKICAgICAgImlucHV0IjogMCwKICAgICAgIm5hbWUiOiAiJDAiCiAgICB9LAogICAgewogICAgICAiaW5wdXQiOiAxLAogICAgICAibmFtZSI6ICIkMSIKICAgIH0KICBdCn10AApmaWVsZFR5cGVzc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAJ0AAdiYWxhbmNlfnIAKW9yZy5vcGVuc2VhcmNoLnNxbC5kYXRhLnR5cGUuRXhwckNvcmVUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAETE9OR3QAA2FnZX5xAH4ACnQAB0lOVEVHRVJ4eA==\"}","lang":"opensearch_compounded_script","params":{"NULL_DIRECTION":"FIRST","DIRECTION":"ASCENDING","utcTimestamp": 0}},"type":"number","order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
calcite:
2+
logical: |
3+
LogicalSystemLimit(sort0=[$1], dir0=[ASC-nulls-first], fetch=[10000], type=[QUERY_SIZE_LIMIT])
4+
LogicalProject(age=[$10], age2=[$19])
5+
LogicalSort(sort0=[$19], dir0=[ASC-nulls-first])
6+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], birthdate=[$3], gender=[$4], city=[$5], lastname=[$6], balance=[$7], employer=[$8], state=[$9], age=[$10], email=[$11], male=[$12], _id=[$13], _index=[$14], _score=[$15], _maxscore=[$16], _sort=[$17], _routing=[$18], age2=[+($10, $7)])
7+
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
8+
physical: |
9+
EnumerableCalc(expr#0..1=[{inputs}], expr#2=[+($t0, $t1)], age=[$t0], $f1=[$t2])
10+
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[age, balance], SORT_EXPR->[+($0, $1) ASCENDING NULLS_FIRST], LIMIT->10000], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":10000,"timeout":"1m","_source":{"includes":["age","balance"],"excludes":[]},"sort":[{"_script":{"script":{"source":"{\"langType\":\"calcite\",\"script\":\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQA0HsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJJTlRFR0VSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYmFsYW5jZSIKICAgIH0KICBdLAogICJudWxsYWJsZSI6IGZhbHNlCn10AARleHBydADFewogICJvcCI6IHsKICAgICJuYW1lIjogIisiLAogICAgImtpbmQiOiAiUExVUyIsCiAgICAic3ludGF4IjogIkJJTkFSWSIKICB9LAogICJvcGVyYW5kcyI6IFsKICAgIHsKICAgICAgImlucHV0IjogMCwKICAgICAgIm5hbWUiOiAiJDAiCiAgICB9LAogICAgewogICAgICAiaW5wdXQiOiAxLAogICAgICAibmFtZSI6ICIkMSIKICAgIH0KICBdCn10AApmaWVsZFR5cGVzc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAJ0AAdiYWxhbmNlfnIAKW9yZy5vcGVuc2VhcmNoLnNxbC5kYXRhLnR5cGUuRXhwckNvcmVUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAETE9OR3QAA2FnZX5xAH4ACnQAB0lOVEVHRVJ4eA==\"}","lang":"opensearch_compounded_script","params":{"NULL_DIRECTION":"FIRST","DIRECTION":"ASCENDING","utcTimestamp": 0}},"type":"number","order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
calcite:
2+
logical: |
3+
LogicalSystemLimit(sort0=[$0], dir0=[ASC-nulls-first], fetch=[10000], type=[QUERY_SIZE_LIMIT])
4+
LogicalProject(age2=[$19])
5+
LogicalSort(sort0=[$19], dir0=[ASC-nulls-first])
6+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], birthdate=[$3], gender=[$4], city=[$5], lastname=[$6], balance=[$7], employer=[$8], state=[$9], age=[$10], email=[$11], male=[$12], _id=[$13], _index=[$14], _score=[$15], _maxscore=[$16], _sort=[$17], _routing=[$18], age2=[+($10, $7)])
7+
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
8+
physical: |
9+
EnumerableCalc(expr#0..1=[{inputs}], expr#2=[+($t0, $t1)], $f0=[$t2])
10+
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[age, balance], SORT_EXPR->[+($0, $1) ASCENDING NULLS_FIRST], LIMIT->10000], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":10000,"timeout":"1m","_source":{"includes":["age","balance"],"excludes":[]},"sort":[{"_script":{"script":{"source":"{\"langType\":\"calcite\",\"script\":\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQA0HsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJJTlRFR0VSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYmFsYW5jZSIKICAgIH0KICBdLAogICJudWxsYWJsZSI6IGZhbHNlCn10AARleHBydADFewogICJvcCI6IHsKICAgICJuYW1lIjogIisiLAogICAgImtpbmQiOiAiUExVUyIsCiAgICAic3ludGF4IjogIkJJTkFSWSIKICB9LAogICJvcGVyYW5kcyI6IFsKICAgIHsKICAgICAgImlucHV0IjogMCwKICAgICAgIm5hbWUiOiAiJDAiCiAgICB9LAogICAgewogICAgICAiaW5wdXQiOiAxLAogICAgICAibmFtZSI6ICIkMSIKICAgIH0KICBdCn10AApmaWVsZFR5cGVzc3IAEWphdmEudXRpbC5IYXNoTWFwBQfawcMWYNEDAAJGAApsb2FkRmFjdG9ySQAJdGhyZXNob2xkeHA/QAAAAAAADHcIAAAAEAAAAAJ0AAdiYWxhbmNlfnIAKW9yZy5vcGVuc2VhcmNoLnNxbC5kYXRhLnR5cGUuRXhwckNvcmVUeXBlAAAAAAAAAAASAAB4cgAOamF2YS5sYW5nLkVudW0AAAAAAAAAABIAAHhwdAAETE9OR3QAA2FnZX5xAH4ACnQAB0lOVEVHRVJ4eA==\"}","lang":"opensearch_compounded_script","params":{"NULL_DIRECTION":"FIRST","DIRECTION":"ASCENDING","utcTimestamp": 0}},"type":"number","order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
calcite:
2+
logical: |
3+
LogicalSystemLimit(sort0=[$14], dir0=[ASC-nulls-first], fetch=[10000], type=[QUERY_SIZE_LIMIT])
4+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], birthdate=[$3], gender=[$4], city=[$5], lastname=[$6], balance=[$7], employer=[$8], state=[$9], age=[$10], email=[$11], male=[$12], age2=[$19], age3=[$20])
5+
LogicalSort(sort0=[$20], dir0=[ASC-nulls-first])
6+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], birthdate=[$3], gender=[$4], city=[$5], lastname=[$6], balance=[$7], employer=[$8], state=[$9], age=[$10], email=[$11], male=[$12], _id=[$13], _index=[$14], _score=[$15], _maxscore=[$16], _sort=[$17], _routing=[$18], age2=[+($10, $7)], age3=[-(+($10, $7), $10)])
7+
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
8+
physical: |
9+
EnumerableCalc(expr#0..12=[{inputs}], expr#13=[+($t10, $t7)], expr#14=[-($t13, $t10)], proj#0..14=[{exprs}])
10+
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[account_number, firstname, address, birthdate, gender, city, lastname, balance, employer, state, age, email, male], SORT_EXPR->[-(+($10, $7), $10) ASCENDING NULLS_FIRST], LIMIT->10000], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":10000,"timeout":"1m","_source":{"includes":["account_number","firstname","address","birthdate","gender","city","lastname","balance","employer","state","age","email","male"],"excludes":[]},"sort":[{"_script":{"script":{"source":"{\"langType\":\"calcite\",\"script\":\"rO0ABXNyABFqYXZhLnV0aWwuQ29sbFNlcleOq7Y6G6gRAwABSQADdGFneHAAAAADdwQAAAAGdAAHcm93VHlwZXQA0HsKICAiZmllbGRzIjogWwogICAgewogICAgICAidHlwZSI6ICJJTlRFR0VSIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYWdlIgogICAgfSwKICAgIHsKICAgICAgInR5cGUiOiAiQklHSU5UIiwKICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgIm5hbWUiOiAiYmFsYW5jZSIKICAgIH0KICBdLAogICJudWxsYWJsZSI6IGZhbHNlCn10AARleHBydAHbewogICJvcCI6IHsKICAgICJuYW1lIjogIi0iLAogICAgImtpbmQiOiAiTUlOVVMiLAogICAgInN5bnRheCI6ICJCSU5BUlkiCiAgfSwKICAib3BlcmFuZHMiOiBbCiAgICB7CiAgICAgICJvcCI6IHsKICAgICAgICAibmFtZSI6ICIrIiwKICAgICAgICAia2luZCI6ICJQTFVTIiwKICAgICAgICAic3ludGF4IjogIkJJTkFSWSIKICAgICAgfSwKICAgICAgIm9wZXJhbmRzIjogWwogICAgICAgIHsKICAgICAgICAgICJpbnB1dCI6IDAsCiAgICAgICAgICAibmFtZSI6ICIkMCIKICAgICAgICB9LAogICAgICAgIHsKICAgICAgICAgICJpbnB1dCI6IDEsCiAgICAgICAgICAibmFtZSI6ICIkMSIKICAgICAgICB9CiAgICAgIF0KICAgIH0sCiAgICB7CiAgICAgICJpbnB1dCI6IDAsCiAgICAgICJuYW1lIjogIiQwIgogICAgfQogIF0sCiAgInR5cGUiOiB7CiAgICAidHlwZSI6ICJCSUdJTlQiLAogICAgIm51bGxhYmxlIjogdHJ1ZQogIH0KfXQACmZpZWxkVHlwZXNzcgARamF2YS51dGlsLkhhc2hNYXAFB9rBwxZg0QMAAkYACmxvYWRGYWN0b3JJAAl0aHJlc2hvbGR4cD9AAAAAAAAMdwgAAAAQAAAAAnQAB2JhbGFuY2V+cgApb3JnLm9wZW5zZWFyY2guc3FsLmRhdGEudHlwZS5FeHByQ29yZVR5cGUAAAAAAAAAABIAAHhyAA5qYXZhLmxhbmcuRW51bQAAAAAAAAAAEgAAeHB0AARMT05HdAADYWdlfnEAfgAKdAAHSU5URUdFUnh4\"}","lang":"opensearch_compounded_script","params":{"NULL_DIRECTION":"FIRST","DIRECTION":"ASCENDING","utcTimestamp": 0}},"type":"number","order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])

0 commit comments

Comments
 (0)