Skip to content

Commit f358e5d

Browse files
authored
Support pushdown dedup with Calcite (#3972)
* Support pushdown dedup with Calcite Signed-off-by: Lantao Jin <ltjin@amazon.com> * Fix IT Signed-off-by: Lantao Jin <ltjin@amazon.com> * Address comments Signed-off-by: Lantao Jin <ltjin@amazon.com> * Fix flaky test Signed-off-by: Lantao Jin <ltjin@amazon.com> * Address comment Signed-off-by: Lantao Jin <ltjin@amazon.com> * delete useless codes Signed-off-by: Lantao Jin <ltjin@amazon.com> * Add more ITs Signed-off-by: Lantao Jin <ltjin@amazon.com> --------- Signed-off-by: Lantao Jin <ltjin@amazon.com>
1 parent a15babf commit f358e5d

File tree

23 files changed

+453
-54
lines changed

23 files changed

+453
-54
lines changed

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

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import static org.opensearch.sql.ast.tree.Sort.SortOption.DEFAULT_DESC;
1414
import static org.opensearch.sql.ast.tree.Sort.SortOrder.ASC;
1515
import static org.opensearch.sql.ast.tree.Sort.SortOrder.DESC;
16+
import static org.opensearch.sql.calcite.utils.PlanUtils.ROW_NUMBER_COLUMN_FOR_DEDUP;
1617
import static org.opensearch.sql.calcite.utils.PlanUtils.ROW_NUMBER_COLUMN_NAME;
1718
import static org.opensearch.sql.calcite.utils.PlanUtils.ROW_NUMBER_COLUMN_NAME_MAIN;
1819
import static org.opensearch.sql.calcite.utils.PlanUtils.ROW_NUMBER_COLUMN_NAME_SUBSEARCH;
@@ -848,13 +849,14 @@ public RelNode visitDedupe(Dedupe node, CalcitePlanContext context) {
848849
if (keepEmpty) {
849850
/*
850851
* | dedup 2 a, b keepempty=false
851-
* DropColumns('_row_number_)
852-
* +- Filter ('_row_number_ <= n OR isnull('a) OR isnull('b))
853-
* +- Window [row_number() windowspecdefinition('a, 'b, 'a ASC NULLS FIRST, 'b ASC NULLS FIRST, specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_], ['a, 'b], ['a ASC NULLS FIRST, 'b ASC NULLS FIRST]
852+
* DropColumns('_row_number_dedup_)
853+
* +- Filter ('_row_number_dedup_ <= n OR isnull('a) OR isnull('b))
854+
* +- Window [row_number() windowspecdefinition('a, 'b, 'a ASC NULLS FIRST, 'b ASC NULLS FIRST, specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_dedup_], ['a, 'b], ['a ASC NULLS FIRST, 'b ASC NULLS FIRST]
854855
* +- ...
855856
*/
856857
// Window [row_number() windowspecdefinition('a, 'b, 'a ASC NULLS FIRST, 'b ASC NULLS FIRST,
857-
// specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_], ['a, 'b], ['a ASC
858+
// specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_dedup_], ['a, 'b], ['a
859+
// ASC
858860
// NULLS FIRST, 'b ASC NULLS FIRST]
859861
RexNode rowNumber =
860862
context
@@ -864,23 +866,23 @@ public RelNode visitDedupe(Dedupe node, CalcitePlanContext context) {
864866
.partitionBy(dedupeFields)
865867
.orderBy(dedupeFields)
866868
.rowsTo(RexWindowBounds.CURRENT_ROW)
867-
.as("_row_number_");
869+
.as(ROW_NUMBER_COLUMN_FOR_DEDUP);
868870
context.relBuilder.projectPlus(rowNumber);
869-
RexNode _row_number_ = context.relBuilder.field("_row_number_");
870-
// Filter (isnull('a) OR isnull('b) OR '_row_number_ <= n)
871+
RexNode _row_number_dedup_ = context.relBuilder.field(ROW_NUMBER_COLUMN_FOR_DEDUP);
872+
// Filter (isnull('a) OR isnull('b) OR '_row_number_dedup_ <= n)
871873
context.relBuilder.filter(
872874
context.relBuilder.or(
873875
context.relBuilder.or(dedupeFields.stream().map(context.relBuilder::isNull).toList()),
874876
context.relBuilder.lessThanOrEqual(
875-
_row_number_, context.relBuilder.literal(allowedDuplication))));
877+
_row_number_dedup_, context.relBuilder.literal(allowedDuplication))));
876878
// DropColumns('_row_number_)
877-
context.relBuilder.projectExcept(_row_number_);
879+
context.relBuilder.projectExcept(_row_number_dedup_);
878880
} else {
879881
/*
880882
* | dedup 2 a, b keepempty=false
881-
* DropColumns('_row_number_)
882-
* +- Filter ('_row_number_ <= n)
883-
* +- Window [row_number() windowspecdefinition('a, 'b, 'a ASC NULLS FIRST, 'b ASC NULLS FIRST, specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_], ['a, 'b], ['a ASC NULLS FIRST, 'b ASC NULLS FIRST]
883+
* DropColumns('_row_number_dedup_)
884+
* +- Filter ('_row_number_dedup_ <= n)
885+
* +- Window [row_number() windowspecdefinition('a, 'b, 'a ASC NULLS FIRST, 'b ASC NULLS FIRST, specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_dedup_], ['a, 'b], ['a ASC NULLS FIRST, 'b ASC NULLS FIRST]
884886
* +- Filter (isnotnull('a) AND isnotnull('b))
885887
* +- ...
886888
*/
@@ -889,7 +891,8 @@ public RelNode visitDedupe(Dedupe node, CalcitePlanContext context) {
889891
context.relBuilder.and(
890892
dedupeFields.stream().map(context.relBuilder::isNotNull).toList()));
891893
// Window [row_number() windowspecdefinition('a, 'b, 'a ASC NULLS FIRST, 'b ASC NULLS FIRST,
892-
// specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_], ['a, 'b], ['a ASC
894+
// specifiedwindowoundedpreceding$(), currentrow$())) AS _row_number_dedup_], ['a, 'b], ['a
895+
// ASC
893896
// NULLS FIRST, 'b ASC NULLS FIRST]
894897
RexNode rowNumber =
895898
context
@@ -899,15 +902,15 @@ public RelNode visitDedupe(Dedupe node, CalcitePlanContext context) {
899902
.partitionBy(dedupeFields)
900903
.orderBy(dedupeFields)
901904
.rowsTo(RexWindowBounds.CURRENT_ROW)
902-
.as("_row_number_");
905+
.as(ROW_NUMBER_COLUMN_FOR_DEDUP);
903906
context.relBuilder.projectPlus(rowNumber);
904-
RexNode _row_number_ = context.relBuilder.field("_row_number_");
905-
// Filter ('_row_number_ <= n)
907+
RexNode _row_number_dedup_ = context.relBuilder.field(ROW_NUMBER_COLUMN_FOR_DEDUP);
908+
// Filter ('_row_number_dedup_ <= n)
906909
context.relBuilder.filter(
907910
context.relBuilder.lessThanOrEqual(
908-
_row_number_, context.relBuilder.literal(allowedDuplication)));
909-
// DropColumns('_row_number_)
910-
context.relBuilder.projectExcept(_row_number_);
911+
_row_number_dedup_, context.relBuilder.literal(allowedDuplication)));
912+
// DropColumns('_row_number_dedup_)
913+
context.relBuilder.projectExcept(_row_number_dedup_);
911914
}
912915
return context.relBuilder.peek();
913916
}

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

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,15 @@
2020
import org.apache.calcite.rel.RelNode;
2121
import org.apache.calcite.rel.RelShuttle;
2222
import org.apache.calcite.rel.core.TableScan;
23+
import org.apache.calcite.rel.logical.LogicalProject;
2324
import org.apache.calcite.rex.RexCall;
2425
import org.apache.calcite.rex.RexInputRef;
2526
import org.apache.calcite.rex.RexNode;
27+
import org.apache.calcite.rex.RexOver;
2628
import org.apache.calcite.rex.RexVisitorImpl;
29+
import org.apache.calcite.rex.RexWindow;
2730
import org.apache.calcite.rex.RexWindowBound;
31+
import org.apache.calcite.sql.SqlKind;
2832
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
2933
import org.apache.calcite.sql.type.SqlTypeName;
3034
import org.apache.calcite.tools.RelBuilder;
@@ -43,6 +47,9 @@
4347

4448
public interface PlanUtils {
4549

50+
/** this is only for dedup command, do not reuse it in other command */
51+
String ROW_NUMBER_COLUMN_FOR_DEDUP = "_row_number_dedup_";
52+
4653
String ROW_NUMBER_COLUMN_NAME = "_row_number_";
4754
String ROW_NUMBER_COLUMN_NAME_MAIN = "_row_number_main_";
4855
String ROW_NUMBER_COLUMN_NAME_SUBSEARCH = "_row_number_subsearch_";
@@ -347,4 +354,41 @@ static RexNode derefMapCall(RexNode rexNode) {
347354
}
348355
return rexNode;
349356
}
357+
358+
/** Check if contains RexOver */
359+
static boolean containsRowNumberDedup(LogicalProject project) {
360+
return project.getProjects().stream()
361+
.anyMatch(p -> p instanceof RexOver && p.getKind() == SqlKind.ROW_NUMBER);
362+
}
363+
364+
/** Get all RexWindow list from LogicalProject */
365+
static List<RexWindow> getRexWindowFromProject(LogicalProject project) {
366+
final List<RexWindow> res = new ArrayList<>();
367+
final RexVisitorImpl<Void> visitor =
368+
new RexVisitorImpl<>(true) {
369+
@Override
370+
public Void visitOver(RexOver over) {
371+
res.add(over.getWindow());
372+
return null;
373+
}
374+
};
375+
visitor.visitEach(project.getProjects());
376+
return res;
377+
}
378+
379+
static List<Integer> getSelectColumns(List<RexNode> rexNodes) {
380+
final List<Integer> selectedColumns = new ArrayList<>();
381+
final RexVisitorImpl<Void> visitor =
382+
new RexVisitorImpl<Void>(true) {
383+
@Override
384+
public Void visitInputRef(RexInputRef inputRef) {
385+
if (!selectedColumns.contains(inputRef.getIndex())) {
386+
selectedColumns.add(inputRef.getIndex());
387+
}
388+
return null;
389+
}
390+
};
391+
visitor.visitEach(rexNodes);
392+
return selectedColumns;
393+
}
350394
}

core/src/main/java/org/opensearch/sql/executor/QueryService.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import org.apache.calcite.rel.RelNode;
2424
import org.apache.calcite.rel.core.Sort;
2525
import org.apache.calcite.rel.logical.LogicalSort;
26-
import org.apache.calcite.rel.metadata.DefaultRelMetadataProvider;
2726
import org.apache.calcite.schema.SchemaPlus;
2827
import org.apache.calcite.sql.parser.SqlParser;
2928
import org.apache.calcite.tools.FrameworkConfig;
@@ -298,7 +297,7 @@ private FrameworkConfig buildFrameworkConfig() {
298297
.parserConfig(SqlParser.Config.DEFAULT) // TODO check
299298
.defaultSchema(opensearchSchema)
300299
.traitDefs((List<RelTraitDef>) null)
301-
.programs(Programs.calc(DefaultRelMetadataProvider.INSTANCE))
300+
.programs(Programs.standard())
302301
.typeSystem(OpenSearchTypeSystem.INSTANCE);
303302
return configBuilder.build();
304303
}

integ-test/src/test/java/org/opensearch/sql/calcite/tpch/CalcitePPLTpchIT.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void testQ1() throws IOException {
5454
schema("count_order", "bigint"));
5555
verifyDataRows(
5656
actual,
57-
rows(
57+
closeTo(
5858
"A",
5959
"F",
6060
37474,
@@ -65,7 +65,7 @@ public void testQ1() throws IOException {
6565
isPushdownEnabled() ? 25419.231826792962 : 25419.231826792948,
6666
isPushdownEnabled() ? 0.0508660351826793 : 0.050866035182679493,
6767
1478),
68-
rows(
68+
closeTo(
6969
"N",
7070
"F",
7171
1041,
@@ -76,7 +76,7 @@ public void testQ1() throws IOException {
7676
27402.659736842103,
7777
isPushdownEnabled() ? 0.04289473684210526 : 0.042894736842105284,
7878
38),
79-
rows(
79+
closeTo(
8080
"N",
8181
"O",
8282
75168,
@@ -87,7 +87,7 @@ public void testQ1() throws IOException {
8787
isPushdownEnabled() ? 25632.42277116627 : 25632.422771166166,
8888
isPushdownEnabled() ? 0.049697381842910573 : 0.04969738184291069,
8989
2941),
90-
rows(
90+
closeTo(
9191
"R",
9292
"F",
9393
36511,

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,36 @@ public void testStatsByTimeSpan() throws IOException {
468468
String.format("source=%s | stats count() by span(birthdate,1M)", TEST_INDEX_BANK)));
469469
}
470470

471+
@Test
472+
public void testDedupPushdown() throws IOException {
473+
String expected = loadExpectedPlan("explain_dedup_push.json");
474+
assertJsonEqualsIgnoreId(
475+
expected,
476+
explainQueryToString(
477+
"source=opensearch-sql_test_index_account | fields account_number, gender, age"
478+
+ " | dedup 1 gender"));
479+
}
480+
481+
@Test
482+
public void testDedupKeepEmptyTruePushdown() throws IOException {
483+
String expected = loadExpectedPlan("explain_dedup_keepempty_true_push.json");
484+
assertJsonEqualsIgnoreId(
485+
expected,
486+
explainQueryToString(
487+
"source=opensearch-sql_test_index_account | fields account_number, gender, age"
488+
+ " | dedup gender KEEPEMPTY=true"));
489+
}
490+
491+
@Test
492+
public void testDedupKeepEmptyFalsePushdown() throws IOException {
493+
String expected = loadExpectedPlan("explain_dedup_keepempty_false_push.json");
494+
assertJsonEqualsIgnoreId(
495+
expected,
496+
explainQueryToString(
497+
"source=opensearch-sql_test_index_account | fields account_number, gender, age"
498+
+ " | dedup gender KEEPEMPTY=false"));
499+
}
500+
471501
@Test
472502
public void testSingleFieldRelevanceQueryFunctionExplain() throws IOException {
473503
// This test is only applicable if pushdown is enabled

integ-test/src/test/java/org/opensearch/sql/util/MatcherUtils.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -292,16 +292,21 @@ protected boolean matchesSafely(JSONArray array) {
292292
};
293293
}
294294

295-
public static TypeSafeMatcher<JSONArray> closeTo(Number... values) {
295+
public static TypeSafeMatcher<JSONArray> closeTo(Object... values) {
296296
final double error = 1e-10;
297297
return new TypeSafeMatcher<JSONArray>() {
298298
@Override
299299
protected boolean matchesSafely(JSONArray item) {
300-
List<Number> expectedValues = new ArrayList<>(Arrays.asList(values));
301-
List<Number> actualValues = new ArrayList<>();
302-
item.iterator().forEachRemaining(v -> actualValues.add((Number) v));
300+
List<Object> expectedValues = new ArrayList<>(Arrays.asList(values));
301+
List<Object> actualValues = new ArrayList<>();
302+
item.iterator().forEachRemaining(v -> actualValues.add((Object) v));
303303
return actualValues.stream()
304-
.allMatch(v -> valuesAreClose(v, expectedValues.get(actualValues.indexOf(v))));
304+
.allMatch(
305+
v ->
306+
v instanceof Number
307+
? valuesAreClose(
308+
(Number) v, (Number) expectedValues.get(actualValues.indexOf(v)))
309+
: v.equals(expectedValues.get(actualValues.indexOf(v))));
305310
}
306311

307312
@Override
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"calcite": {
3+
"logical": "LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])\n LogicalProject(account_number=[$0], gender=[$1], age=[$2])\n LogicalFilter(condition=[<=($3, 1)])\n LogicalProject(account_number=[$0], gender=[$1], age=[$2], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $1 ORDER BY $1)])\n LogicalFilter(condition=[IS NOT NULL($1)])\n LogicalProject(account_number=[$0], gender=[$4], age=[$8])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4+
"physical": "CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[account_number, gender, age], FILTER->IS NOT NULL($1), COLLAPSE->gender, LIMIT->10000], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":10000,\"timeout\":\"1m\",\"query\":{\"exists\":{\"field\":\"gender\",\"boost\":1.0}},\"_source\":{\"includes\":[\"account_number\",\"gender\",\"age\"],\"excludes\":[]},\"sort\":[{\"_doc\":{\"order\":\"asc\"}}],\"collapse\":{\"field\":\"gender.keyword\"}}, requestedTotalSize=10000, 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": "LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])\n LogicalProject(account_number=[$0], gender=[$1], age=[$2])\n LogicalFilter(condition=[OR(IS NULL($1), <=($3, 1))])\n LogicalProject(account_number=[$0], gender=[$4], age=[$8], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $4 ORDER BY $4)])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4+
"physical": "EnumerableLimit(fetch=[10000])\n EnumerableCalc(expr#0..3=[{inputs}], expr#4=[IS NULL($t1)], expr#5=[1], expr#6=[<=($t3, $t5)], expr#7=[OR($t4, $t6)], proj#0..2=[{exprs}], $condition=[$t7])\n EnumerableWindow(window#0=[window(partition {1} order by [1] rows between UNBOUNDED PRECEDING and CURRENT ROW aggs [ROW_NUMBER()])])\n CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[account_number, gender, age]], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"timeout\":\"1m\",\"_source\":{\"includes\":[\"account_number\",\"gender\",\"age\"],\"excludes\":[]}}, requestedTotalSize=2147483647, 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": "LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])\n LogicalProject(account_number=[$0], gender=[$1], age=[$2])\n LogicalFilter(condition=[<=($3, 1)])\n LogicalProject(account_number=[$0], gender=[$1], age=[$2], _row_number_dedup_=[ROW_NUMBER() OVER (PARTITION BY $1 ORDER BY $1)])\n LogicalFilter(condition=[IS NOT NULL($1)])\n LogicalProject(account_number=[$0], gender=[$4], age=[$8])\n CalciteLogicalIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]])\n",
4+
"physical": "CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[account_number, gender, age], FILTER->IS NOT NULL($1), COLLAPSE->gender, LIMIT->10000], OpenSearchRequestBuilder(sourceBuilder={\"from\":0,\"size\":10000,\"timeout\":\"1m\",\"query\":{\"exists\":{\"field\":\"gender\",\"boost\":1.0}},\"_source\":{\"includes\":[\"account_number\",\"gender\",\"age\"],\"excludes\":[]},\"sort\":[{\"_doc\":{\"order\":\"asc\"}}],\"collapse\":{\"field\":\"gender.keyword\"}}, requestedTotalSize=10000, 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": {
3-
"logical": "LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])\n 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-nulls-first])\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",
3+
"logical": "LogicalSystemLimit(fetch=[10000], type=[QUERY_SIZE_LIMIT])\n LogicalProject(age2=[$2])\n LogicalFilter(condition=[<=($3, 1)])\n LogicalProject(avg_age=[$0], state=[$1], age2=[$2], _row_number_dedup_=[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-nulls-first])\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",
44
"physical": "EnumerableLimit(fetch=[10000])\n 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 CalciteEnumerableIndexScan(table=[[OpenSearch, opensearch-sql_test_index_account]], PushDownContext=[[PROJECT->[city, state, age], FILTER->>($2, 30), AGGREGATION->rel#:LogicalAggregate.NONE.[](input=RelSubset#,group={0, 1},avg_age=AVG($2)), SORT->[0 ASC FIRST]], 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\":[{\"_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"
55
}
66
}

0 commit comments

Comments
 (0)