Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
import java.util.Map;
import org.openjdk.jmh.annotations.Benchmark;
import org.opensearch.sql.opensearch.data.type.OpenSearchDataType;
import org.opensearch.sql.opensearch.request.system.OpenSearchDescribeIndexRequest;
import org.opensearch.sql.opensearch.util.MergeRules.MergeRuleHelper;

public class MergeArrayAndObjectMapBenchmark {
private static final List<Map<String, OpenSearchDataType>> candidateMaps = prepareListOfMaps(120);
Expand All @@ -21,7 +21,7 @@ public class MergeArrayAndObjectMapBenchmark {
public void testMerge() {
Map<String, OpenSearchDataType> finalResult = new HashMap<>();
for (Map<String, OpenSearchDataType> map : candidateMaps) {
OpenSearchDescribeIndexRequest.mergeObjectAndArrayInsideMap(finalResult, map);
MergeRuleHelper.merge(finalResult, map);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not related. just fix a compile error in benchmarks module.

}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,23 @@ public void supportSearchSargPushDown_multiRange() throws IOException {
// Only for Calcite
@Test
public void supportSearchSargPushDown_timeRange() throws IOException {
String query =
"source=opensearch-sql_test_index_bank"
+ "| where birthdate >= '2016-12-08 00:00:00.000000000' "
+ "and birthdate < '2018-11-09 00:00:00.000000000'";
var result = explainQueryToString(query);
String expected = loadExpectedPlan("explain_sarg_filter_push_time_range.json");
assertJsonEqualsIgnoreId(
expected,
explainQueryToString(
"source=opensearch-sql_test_index_bank"
+ "| where birthdate >= '2016-12-08 00:00:00.000000000' "
+ "and birthdate < '2018-11-09 00:00:00.000000000' "));
assertJsonEqualsIgnoreId(expected, result);
}

// Only for Calcite
@Test
public void supportPushDownSortMergeJoin() throws IOException {
String query =
"source=opensearch-sql_test_index_bank| join left=l right=r on"
+ " l.account_number=r.account_number opensearch-sql_test_index_bank";
var result = explainQueryToString(query);
String expected = loadExpectedPlan("explain_merge_join_sort_push.json");
assertJsonEqualsIgnoreId(expected, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public void hasGroupKeyAvgOnIntegerShouldPass() {
Index.BANK.getName()));

verifySchema(response, schema("gender", null, "text"), schema("AVG(age)", "avg", "double"));
verifyDataRows(response, rows("m", 34.25), rows("f", 33.666666666666664d));
verifyDataRows(response, rows("M", 34.25), rows("F", 33.666666666666664d));
}

@Test
Expand All @@ -86,7 +86,7 @@ public void hasGroupKeyMaxAddMinShouldPass() {
response,
schema("gender", null, "text"),
schema("MAX(age) + MIN(age)", "addValue", "long"));
verifyDataRows(response, rows("m", 60), rows("f", 60));
verifyDataRows(response, rows("M", 60), rows("F", 60));
}

@Test
Expand All @@ -98,7 +98,7 @@ public void hasGroupKeyMaxAddLiteralShouldPass() {
Index.ACCOUNT.getName()));

verifySchema(response, schema("gender", null, "text"), schema("MAX(age) + 1", "add", "long"));
verifyDataRows(response, rows("m", 41), rows("f", 41));
verifyDataRows(response, rows("M", 41), rows("F", 41));
}

@Test
Expand Down Expand Up @@ -126,7 +126,7 @@ public void hasGroupKeyLogMaxAddMinShouldPass() {
response,
schema("gender", null, "text"),
schema("Log(MAX(age) + MIN(age))", "logValue", "double"));
verifyDataRows(response, rows("m", 4.0943445622221d), rows("f", 4.0943445622221d));
verifyDataRows(response, rows("M", 4.0943445622221d), rows("F", 4.0943445622221d));
}

@Test
Expand All @@ -136,7 +136,7 @@ public void AddLiteralOnGroupKeyShouldPass() {
String.format(
"SELECT gender, age+10, max(balance) as `max` "
+ "FROM %s "
+ "WHERE gender = 'm' and age < 22 "
+ "WHERE gender = 'M' and age < 22 "
+ "GROUP BY gender, age "
+ "ORDER BY age",
Index.ACCOUNT.getName()));
Expand All @@ -146,7 +146,7 @@ public void AddLiteralOnGroupKeyShouldPass() {
schema("gender", null, "text"),
schema("age+10", null, "long"),
schema("max(balance)", "max", "long"));
verifyDataRows(response, rows("m", 30, 49568), rows("m", 31, 49433));
verifyDataRows(response, rows("M", 30, 49568), rows("M", 31, 49433));
}

@Test
Expand All @@ -156,7 +156,7 @@ public void logWithAddLiteralOnGroupKeyShouldPass() {
String.format(
"SELECT gender, Log(age+10) as logAge, max(balance) as max "
+ "FROM %s "
+ "WHERE gender = 'm' and age < 22 "
+ "WHERE gender = 'M' and age < 22 "
+ "GROUP BY gender, age "
+ "ORDER BY age",
Index.ACCOUNT.getName()));
Expand All @@ -167,7 +167,7 @@ public void logWithAddLiteralOnGroupKeyShouldPass() {
schema("Log(age+10)", "logAge", "double"),
schema("max(balance)", "max", "long"));
verifyDataRows(
response, rows("m", 3.4011973816621555d, 49568), rows("m", 3.4339872044851463d, 49433));
response, rows("M", 3.4011973816621555d, 49568), rows("M", 3.4339872044851463d, 49433));
}

@Test
Expand All @@ -177,7 +177,7 @@ public void logWithAddLiteralOnGroupKeyAndMaxSubtractLiteralShouldPass() {
String.format(
"SELECT gender, Log(age+10) as logAge, max(balance) - 100 as max "
+ "FROM %s "
+ "WHERE gender = 'm' and age < 22 "
+ "WHERE gender = 'M' and age < 22 "
+ "GROUP BY gender, age "
+ "ORDER BY age",
Index.ACCOUNT.getName()));
Expand All @@ -188,7 +188,7 @@ public void logWithAddLiteralOnGroupKeyAndMaxSubtractLiteralShouldPass() {
schema("Log(age+10)", "logAge", "double"),
schema("max(balance) - 100", "max", "long"));
verifyDataRows(
response, rows("m", 3.4011973816621555d, 49468), rows("m", 3.4339872044851463d, 49333));
response, rows("M", 3.4011973816621555d, 49468), rows("M", 3.4339872044851463d, 49333));
}

/** The date is in JDBC format. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ public void aggregationFunctionInHaving() throws IOException {

JSONArray dataRows = getDataRows(response);
assertEquals(1, dataRows.length());
assertEquals("m", dataRows.getJSONArray(0).getString(0));
assertEquals("M", dataRows.getJSONArray(0).getString(0));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ public void testMultiSortPushDownExplain() throws IOException {
explainQueryToString(
"source=opensearch-sql_test_index_account "
+ "| sort account_number, firstname, address, balance "
+ "| sort - balance, - gender, address "
Copy link
Member Author

@LantaoJin LantaoJin Jul 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not sort on text type without keyword subfield in v3. Even sorting on text type with fielddata=true will get unexpected order:
For example, if gender is a text type field with fielddata=true.

Check following queries and their outputs in v2.

index=test1:

gender
M a 1
M b 1
F c 2
F d d 1

source = test1 | sort gender returns

gender
M a 1
M b 1
F d d 1
F c 2

source = test1 | sort - gender returns

gender
M a 1
M b 1
F c 2
F d d 1

index=test2:

gender
F d d 1
M a 1
F c 2
M b 1

source=test2 | sort gender returns

gender
F d d 1
M a 1
M b 1
F c 2

source = test2 | sort - gender returns

gender
M a 1
M b 1
F d d 1
F c 2

The logic of sorting a fielddata is 1) tokenization 2) internal sort by token 3) sort by first token
ASC: "F d d 1" =tokenization=> "f", "d", "d", "1" =internal sort by token=> "1", "f", "d", "d" =sort by first token=> "1"
DESC: "F d d 1" =tokenization=> "f", "d", "d", "1" =internal sort by token=> "f", "d", "d", "1" =sort by first token=> "f"

+ "| sort - balance, - gender, account_number "
+ "| fields account_number, firstname, address, balance, gender"));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ public void testRareWithGroup() throws IOException {
rows("F", "OK", 7),
rows("F", "KS", 7),
rows("F", "CO", 7),
rows("F", "NV", 8),
isPushdownEnabled() ? rows("F", "AR", 8) : rows("F", "NV", 8),
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do we introduce this disparity between with&without pushdown?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added "keyword" subfield for the gender, agg pushdown by gender works in caclite.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why pushdown enable impact results?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why pushdown enable impact results?

This result difference is not introduced by code changes in this PR. You can reproduce it in main branch when change the schema from

      "gender": {
        "type": "text",
        "fielddata": true
      },

to

      "gender": {
        "type": "text",
        "fields": {
          "keyword": {
            "type": "keyword",
            "ignore_above": 256
          }
        }
      },

The three results (v2 non-pushdown, v3 non-pushdown, v3 pushdown) are different.

v2 non-pushdown v3 non-pushdown v3 pushdown
"F", "VA", 8 "F", "NV", 8 "F", "AR", 8

But they are all correct. The rare command is not a deterministic command, it result depends on the order of return from OpenSearch and implementation (for v2). When the bucket pushdown works (by gender), the fetched data order is different with data order in non-pushdown.

rows("M", "NE", 5),
rows("M", "RI", 5),
rows("M", "NV", 5),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import static org.opensearch.sql.util.MatcherUtils.rows;
import static org.opensearch.sql.util.MatcherUtils.schema;
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
import static org.opensearch.sql.util.MatcherUtils.verifyDataRowsInOrder;
import static org.opensearch.sql.util.MatcherUtils.verifySchema;
import static org.opensearch.sql.util.MatcherUtils.verifySchemaInOrder;

Expand Down Expand Up @@ -358,27 +357,15 @@ public void testStatsBySpanAndMultipleFields() throws IOException {
schema("span(age,10)", null, "int"),
schema("gender", null, "string"),
schema("state", null, "string"));
if (isCalciteEnabled()) {
verifyDataRows(
response,
rows(1, 20, "F", "VA"),
rows(1, 30, "F", "IN"),
rows(1, 30, "F", "PA"),
rows(1, 30, "M", "IL"),
rows(1, 30, "M", "MD"),
rows(1, 30, "M", "TN"),
rows(1, 30, "M", "WA"));
} else {
verifyDataRowsInOrder(
response,
rows(1, 20, "f", "VA"),
rows(1, 30, "f", "IN"),
rows(1, 30, "f", "PA"),
rows(1, 30, "m", "IL"),
rows(1, 30, "m", "MD"),
rows(1, 30, "m", "TN"),
rows(1, 30, "m", "WA"));
Comment on lines -374 to -380
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this lower case values in v2 were caused by grouping by a fielddata field.

}
verifyDataRows(
response,
rows(1, 20, "F", "VA"),
rows(1, 30, "F", "IN"),
rows(1, 30, "F", "PA"),
rows(1, 30, "M", "IL"),
rows(1, 30, "M", "MD"),
rows(1, 30, "M", "TN"),
rows(1, 30, "M", "WA"));
}

@Test
Expand All @@ -395,27 +382,15 @@ public void testStatsByMultipleFieldsAndSpan() throws IOException {
schema("span(age,10)", null, "int"),
schema("gender", null, "string"),
schema("state", null, "string"));
if (isCalciteEnabled()) {
verifyDataRows(
response,
rows(1, 20, "F", "VA"),
rows(1, 30, "F", "IN"),
rows(1, 30, "F", "PA"),
rows(1, 30, "M", "IL"),
rows(1, 30, "M", "MD"),
rows(1, 30, "M", "TN"),
rows(1, 30, "M", "WA"));
} else {
verifyDataRowsInOrder(
response,
rows(1, 20, "f", "VA"),
rows(1, 30, "f", "IN"),
rows(1, 30, "f", "PA"),
rows(1, 30, "m", "IL"),
rows(1, 30, "m", "MD"),
rows(1, 30, "m", "TN"),
rows(1, 30, "m", "WA"));
}
verifyDataRows(
response,
rows(1, 20, "F", "VA"),
rows(1, 30, "F", "IN"),
rows(1, 30, "F", "PA"),
rows(1, 30, "M", "IL"),
rows(1, 30, "M", "MD"),
rows(1, 30, "M", "TN"),
rows(1, 30, "M", "WA"));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"calcite": {
"logical": "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], r.account_number=[$13], r.firstname=[$14], r.address=[$15], r.birthdate=[$16], r.gender=[$17], r.city=[$18], r.lastname=[$19], r.balance=[$20], r.employer=[$21], r.state=[$22], r.age=[$23], r.email=[$24], r.male=[$25])\n LogicalJoin(condition=[=($0, $13)], joinType=[inner])\n 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])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])\n 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])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])\n",
"physical": "EnumerableMergeJoin(condition=[=($0, $13)], joinType=[inner])\n 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->[{\n \"account_number\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_last\"\n }\n}]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"account_number\",\"firstname\",\"address\",\"birthdate\",\"gender\",\"city\",\"lastname\",\"balance\",\"employer\",\"state\",\"age\",\"email\",\"male\"],\"excludes\":[]},\"sort\":[{\"account_number\":{\"order\":\"asc\",\"missing\":\"_last\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n 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->[{\n \"account_number\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_last\"\n }\n}]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"account_number\",\"firstname\",\"address\",\"birthdate\",\"gender\",\"city\",\"lastname\",\"balance\",\"employer\",\"state\",\"age\",\"email\",\"male\"],\"excludes\":[]},\"sort\":[{\"account_number\":{\"order\":\"asc\",\"missing\":\"_last\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"calcite": {
"logical": "LogicalSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4])\n LogicalSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalSort(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC-nulls-first], dir1=[ASC-nulls-first], dir2=[ASC-nulls-first], dir3=[ASC-nulls-first])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
"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\" : \"_last\"\n }\n}, {\n \"gender\" : {\n \"order\" : \"desc\",\n \"missing\" : \"_last\"\n }\n}, {\n \"address\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_first\"\n }\n}]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"account_number\",\"firstname\",\"address\",\"balance\",\"gender\"],\"excludes\":[]},\"sort\":[{\"balance\":{\"order\":\"desc\",\"missing\":\"_last\"}},{\"gender\":{\"order\":\"desc\",\"missing\":\"_last\"}},{\"address\":{\"order\":\"asc\",\"missing\":\"_first\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
"logical": "LogicalSort(sort0=[$3], sort1=[$4], sort2=[$0], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4])\n LogicalSort(sort0=[$3], sort1=[$4], sort2=[$0], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalSort(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC-nulls-first], dir1=[ASC-nulls-first], dir2=[ASC-nulls-first], dir3=[ASC-nulls-first])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
"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\" : \"_last\"\n }\n}, {\n \"gender.keyword\" : {\n \"order\" : \"desc\",\n \"missing\" : \"_last\"\n }\n}, {\n \"account_number\" : {\n \"order\" : \"asc\",\n \"missing\" : \"_first\"\n }\n}]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"account_number\",\"firstname\",\"address\",\"balance\",\"gender\"],\"excludes\":[]},\"sort\":[{\"balance\":{\"order\":\"desc\",\"missing\":\"_last\"}},{\"gender.keyword\":{\"order\":\"desc\",\"missing\":\"_last\"}},{\"account_number\":{\"order\":\"asc\",\"missing\":\"_first\"}}]}, requestedTotalSize=2147483647, pageSize=null, startFrom=0)])\n"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"calcite": {
"logical": "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], r.account_number=[$13], r.firstname=[$14], r.address=[$15], r.birthdate=[$16], r.gender=[$17], r.city=[$18], r.lastname=[$19], r.balance=[$20], r.employer=[$21], r.state=[$22], r.age=[$23], r.email=[$24], r.male=[$25])\n LogicalJoin(condition=[=($0, $13)], joinType=[inner])\n 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])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])\n 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])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])\n",
"physical": "EnumerableMergeJoin(condition=[=($0, $13)], joinType=[inner])\n EnumerableSort(sort0=[$0], dir0=[ASC])\n EnumerableCalc(expr#0..18=[{inputs}], proj#0..12=[{exprs}])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])\n EnumerableSort(sort0=[$0], dir0=[ASC])\n EnumerableCalc(expr#0..18=[{inputs}], proj#0..12=[{exprs}])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])\n"
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"calcite": {
"logical": "LogicalSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4])\n LogicalSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalSort(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC-nulls-first], dir1=[ASC-nulls-first], dir2=[ASC-nulls-first], dir3=[ASC-nulls-first])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
"physical": "EnumerableSort(sort0=[$3], sort1=[$4], sort2=[$2], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n EnumerableCalc(expr#0..16=[{inputs}], proj#0..4=[{exprs}])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n"
"logical": "LogicalSort(sort0=[$3], sort1=[$4], sort2=[$0], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4])\n LogicalSort(sort0=[$3], sort1=[$4], sort2=[$0], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n LogicalSort(sort0=[$0], sort1=[$1], sort2=[$2], sort3=[$3], dir0=[ASC-nulls-first], dir1=[ASC-nulls-first], dir2=[ASC-nulls-first], dir3=[ASC-nulls-first])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
"physical": "EnumerableSort(sort0=[$3], sort1=[$4], sort2=[$0], dir0=[DESC-nulls-last], dir1=[DESC-nulls-last], dir2=[ASC-nulls-first])\n EnumerableCalc(expr#0..16=[{inputs}], proj#0..4=[{exprs}])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n"
}
}
Loading
Loading