Skip to content

Commit 4bf5c9c

Browse files
authored
Pushdown join with max=n option to TopHits aggregation (#4929)
* Pushdown join with max=n option to TopHits aggregation Signed-off-by: Lantao Jin <ltjin@amazon.com> * Fix UT Signed-off-by: Lantao Jin <ltjin@amazon.com> * Stabilize the dashboard IT Signed-off-by: Lantao Jin <ltjin@amazon.com> * address comment Signed-off-by: Lantao Jin <ltjin@amazon.com> --------- Signed-off-by: Lantao Jin <ltjin@amazon.com>
1 parent bcfcd00 commit 4bf5c9c

27 files changed

+170
-132
lines changed

core/src/main/java/org/opensearch/sql/calcite/CalciteRelNodeVisitor.java

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1256,15 +1256,6 @@ private Optional<RexLiteral> extractAliasLiteral(RexNode node) {
12561256
public RelNode visitJoin(Join node, CalcitePlanContext context) {
12571257
List<UnresolvedPlan> children = node.getChildren();
12581258
children.forEach(c -> analyze(c, context));
1259-
// add join.subsearch_maxout limit to subsearch side, 0 and negative means unlimited.
1260-
if (context.sysLimit.joinSubsearchLimit() > 0) {
1261-
PlanUtils.replaceTop(
1262-
context.relBuilder,
1263-
LogicalSystemLimit.create(
1264-
SystemLimitType.JOIN_SUBSEARCH_MAXOUT,
1265-
context.relBuilder.peek(),
1266-
context.relBuilder.literal(context.sysLimit.joinSubsearchLimit())));
1267-
}
12681259
if (node.getJoinCondition().isEmpty()) {
12691260
// join-with-field-list grammar
12701261
List<String> leftColumns = context.relBuilder.peek(1).getRowType().getFieldNames();
@@ -1321,23 +1312,25 @@ public RelNode visitJoin(Join node, CalcitePlanContext context) {
13211312
.toList();
13221313
buildDedupNotNull(context, dedupeFields, allowedDuplication, true);
13231314
}
1315+
// add LogicalSystemLimit after dedup
1316+
addSysLimitForJoinSubsearch(context);
13241317
context.relBuilder.join(
13251318
JoinAndLookupUtils.translateJoinType(node.getJoinType()), joinCondition);
13261319
if (!toBeRemovedFields.isEmpty()) {
13271320
context.relBuilder.projectExcept(toBeRemovedFields);
13281321
}
1329-
return context.relBuilder.peek();
1330-
}
1331-
// The join-with-criteria grammar doesn't allow empty join condition
1332-
RexNode joinCondition =
1333-
node.getJoinCondition()
1334-
.map(c -> rexVisitor.analyzeJoinCondition(c, context))
1335-
.orElse(context.relBuilder.literal(true));
1336-
if (node.getJoinType() == SEMI || node.getJoinType() == ANTI) {
1337-
// semi and anti join only return left table outputs
1338-
context.relBuilder.join(
1339-
JoinAndLookupUtils.translateJoinType(node.getJoinType()), joinCondition);
13401322
} else {
1323+
// The join-with-criteria grammar doesn't allow empty join condition
1324+
RexNode joinCondition =
1325+
node.getJoinCondition()
1326+
.map(c -> rexVisitor.analyzeJoinCondition(c, context))
1327+
.orElse(context.relBuilder.literal(true));
1328+
if (node.getJoinType() == SEMI || node.getJoinType() == ANTI) {
1329+
// semi and anti join only return left table outputs
1330+
context.relBuilder.join(
1331+
JoinAndLookupUtils.translateJoinType(node.getJoinType()), joinCondition);
1332+
return context.relBuilder.peek();
1333+
}
13411334
// Join condition could contain duplicated column name, Calcite will rename the duplicated
13421335
// column name with numeric suffix, e.g. ON t1.id = t2.id, the output contains `id` and `id0`
13431336
// when a new project add to stack. To avoid `id0`, we will rename the `id0` to `alias.id`
@@ -1377,6 +1370,8 @@ public RelNode visitJoin(Join node, CalcitePlanContext context) {
13771370

13781371
buildDedupNotNull(context, dedupeFields, allowedDuplication, true);
13791372
}
1373+
// add LogicalSystemLimit after dedup
1374+
addSysLimitForJoinSubsearch(context);
13801375
context.relBuilder.join(
13811376
JoinAndLookupUtils.translateJoinType(node.getJoinType()), joinCondition);
13821377
JoinAndLookupUtils.renameToExpectedFields(
@@ -1385,6 +1380,18 @@ public RelNode visitJoin(Join node, CalcitePlanContext context) {
13851380
return context.relBuilder.peek();
13861381
}
13871382

1383+
private static void addSysLimitForJoinSubsearch(CalcitePlanContext context) {
1384+
// add join.subsearch_maxout limit to subsearch side, 0 and negative means unlimited.
1385+
if (context.sysLimit.joinSubsearchLimit() > 0) {
1386+
PlanUtils.replaceTop(
1387+
context.relBuilder,
1388+
LogicalSystemLimit.create(
1389+
SystemLimitType.JOIN_SUBSEARCH_MAXOUT,
1390+
context.relBuilder.peek(),
1391+
context.relBuilder.literal(context.sysLimit.joinSubsearchLimit())));
1392+
}
1393+
}
1394+
13881395
private List<RexNode> getRightColumnsInJoinCriteria(
13891396
RelBuilder relBuilder, RexNode joinCondition) {
13901397
int stackSize = relBuilder.size();
@@ -1560,7 +1567,6 @@ private static void buildDedupOrNull(
15601567
.aggregateCall(SqlStdOperatorTable.ROW_NUMBER)
15611568
.over()
15621569
.partitionBy(dedupeFields)
1563-
.orderBy(dedupeFields)
15641570
.rowsTo(RexWindowBounds.CURRENT_ROW)
15651571
.as(ROW_NUMBER_COLUMN_FOR_DEDUP);
15661572
context.relBuilder.projectPlus(rowNumber);
@@ -1602,7 +1608,6 @@ private static void buildDedupNotNull(
16021608
.aggregateCall(SqlStdOperatorTable.ROW_NUMBER)
16031609
.over()
16041610
.partitionBy(dedupeFields)
1605-
.orderBy(dedupeFields)
16061611
.rowsTo(RexWindowBounds.CURRENT_ROW)
16071612
.as(rowNumberAlias);
16081613
context.relBuilder.projectPlus(rowNumber);

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -460,7 +460,11 @@ static RexNode derefMapCall(RexNode rexNode) {
460460

461461
/** Check if contains dedup */
462462
static boolean containsRowNumberDedup(RelNode node) {
463-
return node.getRowType().getFieldNames().stream().anyMatch(ROW_NUMBER_COLUMN_FOR_DEDUP::equals);
463+
return node.getRowType().getFieldNames().stream()
464+
.anyMatch(
465+
name ->
466+
name.equals(ROW_NUMBER_COLUMN_FOR_DEDUP)
467+
|| name.equals(ROW_NUMBER_COLUMN_FOR_JOIN_MAX_DEDUP));
464468
}
465469

466470
/** Check if contains dedup for top/rare */

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,6 @@ public void supportSearchSargPushDown_timeRange() throws IOException {
8686
// Only for Calcite
8787
@Test
8888
public void testJoinWithCriteriaAndMaxOption() throws IOException {
89-
// TODO could be optimized with https://github.com/opensearch-project/OpenSearch/issues/3725
90-
enabledOnlyWhenPushdownIsEnabled();
9189
String query =
9290
"source=opensearch-sql_test_index_bank | join max=1 left=l right=r on"
9391
+ " l.account_number=r.account_number opensearch-sql_test_index_bank";
@@ -99,8 +97,6 @@ public void testJoinWithCriteriaAndMaxOption() throws IOException {
9997
// Only for Calcite
10098
@Test
10199
public void testJoinWithFieldListAndMaxOption() throws IOException {
102-
// TODO could be optimized with https://github.com/opensearch-project/OpenSearch/issues/3725
103-
enabledOnlyWhenPushdownIsEnabled();
104100
String query =
105101
"source=opensearch-sql_test_index_bank | join type=inner max=1 account_number"
106102
+ " opensearch-sql_test_index_bank";

integ-test/src/test/java/org/opensearch/sql/ppl/dashboard/NfwPplDashboardIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,8 @@ public void testTopTCPFlowsByBytes() throws IOException {
436436
public void testTopTCPFlags() throws IOException {
437437
String query =
438438
String.format(
439-
"source=%s | STATS count() as Count by `event.tcp.tcp_flags` | SORT - Count | HEAD 10",
439+
"source=%s | STATS count() as Count by `event.tcp.tcp_flags` | SORT - Count,"
440+
+ " `event.tcp.tcp_flags` | HEAD 10",
440441
NFW_LOGS_INDEX);
441442
JSONObject response = executeQuery(query);
442443
verifySchema(response, schema("Count", "bigint"), schema("event.tcp.tcp_flags", "string"));

integ-test/src/test/java/org/opensearch/sql/ppl/dashboard/VpcFlowLogsPplDashboardIT.java

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

66
package org.opensearch.sql.ppl.dashboard;
77

8-
import static org.junit.jupiter.api.Assertions.assertEquals;
98
import static org.opensearch.sql.util.MatcherUtils.rows;
109
import static org.opensearch.sql.util.MatcherUtils.schema;
1110
import static org.opensearch.sql.util.MatcherUtils.verifyDataRows;
@@ -167,7 +166,8 @@ public void testTopTalkersByBytes() throws IOException {
167166
public void testTopTalkersByPackets() throws IOException {
168167
String query =
169168
String.format(
170-
"source=%s | stats sum(packets) as Packets by srcaddr | sort - Packets | head 10",
169+
"source=%s | stats sum(packets) as Packets by srcaddr | sort - Packets, srcaddr | head"
170+
+ " 10",
171171
VPC_FLOW_LOGS_INDEX);
172172
JSONObject response = executeQuery(query);
173173
verifySchema(response, schema("Packets", null, "bigint"), schema("srcaddr", null, "string"));
@@ -189,7 +189,8 @@ public void testTopTalkersByPackets() throws IOException {
189189
public void testTopDestinationsByPackets() throws IOException {
190190
String query =
191191
String.format(
192-
"source=%s | stats sum(packets) as Packets by dstaddr | sort - Packets | head 10",
192+
"source=%s | stats sum(packets) as Packets by dstaddr | sort - Packets, dstaddr | head"
193+
+ " 10",
193194
VPC_FLOW_LOGS_INDEX);
194195
JSONObject response = executeQuery(query);
195196
verifySchema(response, schema("Packets", null, "bigint"), schema("dstaddr", null, "string"));
@@ -211,7 +212,7 @@ public void testTopDestinationsByPackets() throws IOException {
211212
public void testTopTalkersByIPs() throws IOException {
212213
String query =
213214
String.format(
214-
"source=%s | STATS count() as Count by srcaddr | SORT - Count | HEAD 10",
215+
"source=%s | STATS count() as Count by srcaddr | SORT - Count, srcaddr | HEAD 10",
215216
VPC_FLOW_LOGS_INDEX);
216217
JSONObject response = executeQuery(query);
217218
verifySchema(response, schema("Count", null, "bigint"), schema("srcaddr", null, "string"));
@@ -233,7 +234,7 @@ public void testTopTalkersByIPs() throws IOException {
233234
public void testTopDestinationsByIPs() throws IOException {
234235
String query =
235236
String.format(
236-
"source=%s | stats count() as Requests by dstaddr | sort - Requests | head 10",
237+
"source=%s | stats count() as Requests by dstaddr | sort - Requests, dstaddr | head 10",
237238
VPC_FLOW_LOGS_INDEX);
238239
JSONObject response = executeQuery(query);
239240
verifySchema(response, schema("Requests", null, "bigint"), schema("dstaddr", null, "string"));

integ-test/src/test/java/org/opensearch/sql/ppl/dashboard/WafPplDashboardIT.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,8 @@ public void testTopCountries() throws IOException {
144144
public void testTopTerminatingRules() throws IOException {
145145
String query =
146146
String.format(
147-
"source=%s | stats count() as Count by `terminatingRuleId` | sort - Count | head 10",
147+
"source=%s | stats count() as Count by `terminatingRuleId` | sort - Count,"
148+
+ " `terminatingRuleId` | head 10",
148149
WAF_LOGS_INDEX);
149150

150151
JSONObject response = executeQuery(query);

integ-test/src/test/resources/expectedOutput/calcite/explain_complex_sort_expr_pushdown_for_smj_w_max_option.yaml

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@ calcite:
55
LogicalJoin(condition=[=($12, $19)], joinType=[left])
66
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], birthdate=[$3], gender=[$4], city=[$5], balance=[$7], employer=[$8], state=[$9], age=[$10], email=[$11], male=[$12], lastname=[REX_EXTRACT($6, '(?<lastname>^[A-Z])', 'lastname')])
77
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
8-
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])
9-
LogicalFilter(condition=[<=($13, 1)])
10-
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], _row_number_join_max_dedup_=[ROW_NUMBER() OVER (PARTITION BY $6 ORDER BY $6)])
11-
LogicalFilter(condition=[IS NOT NULL($6)])
12-
LogicalSystemLimit(fetch=[50000], type=[JOIN_SUBSEARCH_MAXOUT])
8+
LogicalSystemLimit(fetch=[50000], type=[JOIN_SUBSEARCH_MAXOUT])
9+
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])
10+
LogicalFilter(condition=[<=($13, 1)])
11+
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], _row_number_join_max_dedup_=[ROW_NUMBER() OVER (PARTITION BY $6)])
12+
LogicalFilter(condition=[IS NOT NULL($6)])
1313
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])
1414
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]])
1515
physical: |
@@ -18,8 +18,4 @@ calcite:
1818
EnumerableMergeJoin(condition=[=($0, $7)], joinType=[left])
1919
EnumerableCalc(expr#0=[{inputs}], expr#1=['(?<lastname>^[A-Z])'], expr#2=['lastname'], expr#3=[REX_EXTRACT($t0, $t1, $t2)], $f0=[$t3])
2020
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[lastname], LIMIT->10000, SORT_EXPR->[REX_EXTRACT($0, '(?<lastname>^[A-Z])', 'lastname') ASCENDING NULLS_LAST]], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":10000,"timeout":"1m","_source":{"includes":["lastname"],"excludes":[]},"sort":[{"_script":{"script":{"source":"{\"langType\":\"calcite\",\"script\":\"rO0ABXQC63sKICAib3AiOiB7CiAgICAibmFtZSI6ICJSRVhfRVhUUkFDVCIsCiAgICAia2luZCI6ICJPVEhFUl9GVU5DVElPTiIsCiAgICAic3ludGF4IjogIkZVTkNUSU9OIgogIH0sCiAgIm9wZXJhbmRzIjogWwogICAgewogICAgICAiZHluYW1pY1BhcmFtIjogMCwKICAgICAgInR5cGUiOiB7CiAgICAgICAgInR5cGUiOiAiVkFSQ0hBUiIsCiAgICAgICAgIm51bGxhYmxlIjogdHJ1ZSwKICAgICAgICAicHJlY2lzaW9uIjogLTEKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgImR5bmFtaWNQYXJhbSI6IDEsCiAgICAgICJ0eXBlIjogewogICAgICAgICJ0eXBlIjogIlZBUkNIQVIiLAogICAgICAgICJudWxsYWJsZSI6IHRydWUsCiAgICAgICAgInByZWNpc2lvbiI6IC0xCiAgICAgIH0KICAgIH0sCiAgICB7CiAgICAgICJkeW5hbWljUGFyYW0iOiAyLAogICAgICAidHlwZSI6IHsKICAgICAgICAidHlwZSI6ICJWQVJDSEFSIiwKICAgICAgICAibnVsbGFibGUiOiB0cnVlLAogICAgICAgICJwcmVjaXNpb24iOiAtMQogICAgICB9CiAgICB9CiAgXSwKICAiY2xhc3MiOiAib3JnLm9wZW5zZWFyY2guc3FsLmV4cHJlc3Npb24uZnVuY3Rpb24uVXNlckRlZmluZWRGdW5jdGlvbkJ1aWxkZXIkMSIsCiAgInR5cGUiOiB7CiAgICAidHlwZSI6ICJWQVJDSEFSIiwKICAgICJudWxsYWJsZSI6IHRydWUsCiAgICAicHJlY2lzaW9uIjogMjAwMAogIH0sCiAgImRldGVybWluaXN0aWMiOiB0cnVlLAogICJkeW5hbWljIjogZmFsc2UKfQ==\"}","lang":"opensearch_compounded_script","params":{"MISSING_MAX":true,"utcTimestamp": 0,"SOURCES":[0,2,2],"DIGESTS":["lastname","(?<lastname>^[A-Z])","lastname"]}},"type":"string","order":"asc"}}]}, requestedTotalSize=10000, pageSize=null, startFrom=0)])
21-
EnumerableSort(sort0=[$6], dir0=[ASC])
22-
EnumerableCalc(expr#0..13=[{inputs}], expr#14=[1], expr#15=[<=($t13, $t14)], proj#0..12=[{exprs}], $condition=[$t15])
23-
EnumerableWindow(window#0=[window(partition {6} order by [6] rows between UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])
24-
EnumerableCalc(expr#0..12=[{inputs}], expr#13=[IS NOT NULL($t6)], proj#0..12=[{exprs}], $condition=[$t13])
25-
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[account_number, firstname, address, birthdate, gender, city, lastname, balance, employer, state, age, email, male], LIMIT->50000], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":50000,"timeout":"1m","_source":{"includes":["account_number","firstname","address","birthdate","gender","city","lastname","balance","employer","state","age","email","male"],"excludes":[]}}, requestedTotalSize=50000, pageSize=null, startFrom=0)])
21+
CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_bank]], PushDownContext=[[PROJECT->[account_number, firstname, address, birthdate, gender, city, lastname, balance, employer, state, age, email, male], AGGREGATION->rel#:LogicalAggregate.NONE.[](input=LogicalProject#,group={0},agg#0=LITERAL_AGG(1)), LIMIT->50000, SORT->[6]], OpenSearchRequestBuilder(sourceBuilder={"from":0,"size":0,"timeout":"1m","_source":{"includes":["account_number","firstname","address","birthdate","gender","city","lastname","balance","employer","state","age","email","male"],"excludes":[]},"aggregations":{"composite_buckets":{"composite":{"size":1000,"sources":[{"lastname":{"terms":{"field":"lastname","missing_bucket":false,"order":"asc"}}}]},"aggregations":{"$f1":{"top_hits":{"from":0,"size":1,"version":false,"seq_no_primary_term":false,"explain":false,"_source":{"includes":["lastname","account_number","firstname","address","birthdate","gender","city","balance","employer","state","age","email","male"],"excludes":[]},"script_fields":{}}}}}}}, requestedTotalSize=50000, pageSize=null, startFrom=0)])

integ-test/src/test/resources/expectedOutput/calcite/explain_dedup_complex1.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ calcite:
33
LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])
44
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4], city=[$5], employer=[$6], state=[$7], age=[$8], email=[$9], lastname=[$10])
55
LogicalFilter(condition=[<=($17, 1)])
6-
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4], city=[$5], employer=[$6], state=[$7], age=[$8], email=[$9], lastname=[$10], _id=[$11], _index=[$12], _score=[$13], _maxscore=[$14], _sort=[$15], _routing=[$16], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $4 ORDER BY $4)])
6+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4], city=[$5], employer=[$6], state=[$7], age=[$8], email=[$9], lastname=[$10], _id=[$11], _index=[$12], _score=[$13], _maxscore=[$14], _sort=[$15], _routing=[$16], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $4)])
77
LogicalFilter(condition=[IS NOT NULL($4)])
88
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])
99
physical: |

integ-test/src/test/resources/expectedOutput/calcite/explain_dedup_complex2.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ calcite:
33
LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])
44
LogicalProject(account_number=[$0], gender=[$1], age=[$2], state=[$3])
55
LogicalFilter(condition=[<=($4, 1)])
6-
LogicalProject(account_number=[$0], gender=[$1], age=[$2], state=[$3], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $1, $3 ORDER BY $1, $3)])
6+
LogicalProject(account_number=[$0], gender=[$1], age=[$2], state=[$3], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $1, $3)])
77
LogicalFilter(condition=[AND(IS NOT NULL($1), IS NOT NULL($3))])
88
LogicalProject(account_number=[$0], gender=[$4], age=[$8], state=[$7])
99
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])

integ-test/src/test/resources/expectedOutput/calcite/explain_dedup_complex3.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ calcite:
33
LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])
44
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4], city=[$5], employer=[$6], state=[$7], age=[$8], email=[$9], lastname=[$10])
55
LogicalFilter(condition=[<=($17, 2)])
6-
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4], city=[$5], employer=[$6], state=[$7], age=[$8], email=[$9], lastname=[$10], _id=[$11], _index=[$12], _score=[$13], _maxscore=[$14], _sort=[$15], _routing=[$16], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $4, $7 ORDER BY $4, $7)])
6+
LogicalProject(account_number=[$0], firstname=[$1], address=[$2], balance=[$3], gender=[$4], city=[$5], employer=[$6], state=[$7], age=[$8], email=[$9], lastname=[$10], _id=[$11], _index=[$12], _score=[$13], _maxscore=[$14], _sort=[$15], _routing=[$16], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $4, $7)])
77
LogicalFilter(condition=[AND(IS NOT NULL($4), IS NOT NULL($7))])
88
CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])
99
physical: |

0 commit comments

Comments
 (0)