Skip to content

Commit bc5bede

Browse files
Add Close Cursor API in v2. (#1660)
Signed-off-by: Yury-Fridlyand <[email protected]>
1 parent 9ebdda5 commit bc5bede

File tree

35 files changed

+876
-114
lines changed

35 files changed

+876
-114
lines changed

core/src/main/java/org/opensearch/sql/analysis/Analyzer.java

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.opensearch.sql.ast.expression.UnresolvedExpression;
4444
import org.opensearch.sql.ast.tree.AD;
4545
import org.opensearch.sql.ast.tree.Aggregation;
46+
import org.opensearch.sql.ast.tree.CloseCursor;
4647
import org.opensearch.sql.ast.tree.Dedupe;
4748
import org.opensearch.sql.ast.tree.Eval;
4849
import org.opensearch.sql.ast.tree.FetchCursor;
@@ -83,6 +84,7 @@
8384
import org.opensearch.sql.expression.parse.ParseExpression;
8485
import org.opensearch.sql.planner.logical.LogicalAD;
8586
import org.opensearch.sql.planner.logical.LogicalAggregation;
87+
import org.opensearch.sql.planner.logical.LogicalCloseCursor;
8688
import org.opensearch.sql.planner.logical.LogicalDedupe;
8789
import org.opensearch.sql.planner.logical.LogicalEval;
8890
import org.opensearch.sql.planner.logical.LogicalFetchCursor;
@@ -572,6 +574,17 @@ public LogicalPlan visitPaginate(Paginate paginate, AnalysisContext context) {
572574
return new LogicalPaginate(paginate.getPageSize(), List.of(child));
573575
}
574576

577+
@Override
578+
public LogicalPlan visitFetchCursor(FetchCursor cursor, AnalysisContext context) {
579+
return new LogicalFetchCursor(cursor.getCursor(),
580+
dataSourceService.getDataSource(DEFAULT_DATASOURCE_NAME).getStorageEngine());
581+
}
582+
583+
@Override
584+
public LogicalPlan visitCloseCursor(CloseCursor closeCursor, AnalysisContext context) {
585+
return new LogicalCloseCursor(closeCursor.getChild().get(0).accept(this, context));
586+
}
587+
575588
/**
576589
* The first argument is always "asc", others are optional.
577590
* Given nullFirst argument, use its value. Otherwise just use DEFAULT_ASC/DESC.
@@ -587,10 +600,4 @@ private SortOption analyzeSortOption(List<Argument> fieldArgs) {
587600
}
588601
return asc ? SortOption.DEFAULT_ASC : SortOption.DEFAULT_DESC;
589602
}
590-
591-
@Override
592-
public LogicalPlan visitFetchCursor(FetchCursor cursor, AnalysisContext context) {
593-
return new LogicalFetchCursor(cursor.getCursor(),
594-
dataSourceService.getDataSource(DEFAULT_DATASOURCE_NAME).getStorageEngine());
595-
}
596603
}

core/src/main/java/org/opensearch/sql/ast/AbstractNodeVisitor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.opensearch.sql.ast.statement.Statement;
4242
import org.opensearch.sql.ast.tree.AD;
4343
import org.opensearch.sql.ast.tree.Aggregation;
44+
import org.opensearch.sql.ast.tree.CloseCursor;
4445
import org.opensearch.sql.ast.tree.Dedupe;
4546
import org.opensearch.sql.ast.tree.Eval;
4647
import org.opensearch.sql.ast.tree.FetchCursor;
@@ -302,6 +303,10 @@ public T visitPaginate(Paginate paginate, C context) {
302303
}
303304

304305
public T visitFetchCursor(FetchCursor cursor, C context) {
305-
return visit(cursor, context);
306+
return visitChildren(cursor, context);
307+
}
308+
309+
public T visitCloseCursor(CloseCursor closeCursor, C context) {
310+
return visitChildren(closeCursor, context);
306311
}
307312
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.ast.tree;
7+
8+
import java.util.List;
9+
import org.opensearch.sql.ast.AbstractNodeVisitor;
10+
import org.opensearch.sql.ast.Node;
11+
12+
/**
13+
* AST node to represent close cursor operation.
14+
* Actually a wrapper to the AST.
15+
*/
16+
public class CloseCursor extends UnresolvedPlan {
17+
18+
/**
19+
* An instance of {@link FetchCursor}.
20+
*/
21+
private UnresolvedPlan cursor;
22+
23+
@Override
24+
public <T, C> T accept(AbstractNodeVisitor<T, C> nodeVisitor, C context) {
25+
return nodeVisitor.visitCloseCursor(this, context);
26+
}
27+
28+
@Override
29+
public UnresolvedPlan attach(UnresolvedPlan child) {
30+
this.cursor = child;
31+
return this;
32+
}
33+
34+
@Override
35+
public List<? extends Node> getChild() {
36+
return List.of(cursor);
37+
}
38+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
*
4+
* The OpenSearch Contributors require contributions made to
5+
* this file be licensed under the Apache-2.0 license or a
6+
* compatible open source license.
7+
*/
8+
9+
package org.opensearch.sql.executor.execution;
10+
11+
import org.opensearch.sql.ast.tree.UnresolvedPlan;
12+
import org.opensearch.sql.common.response.ResponseListener;
13+
import org.opensearch.sql.executor.ExecutionEngine;
14+
import org.opensearch.sql.executor.QueryId;
15+
import org.opensearch.sql.executor.QueryService;
16+
17+
/**
18+
* Query plan which does not reflect a search query being executed.
19+
* It contains a command or an action, for example, a DDL query.
20+
*/
21+
public class CommandPlan extends AbstractPlan {
22+
23+
/**
24+
* The query plan ast.
25+
*/
26+
protected final UnresolvedPlan plan;
27+
28+
/**
29+
* Query service.
30+
*/
31+
protected final QueryService queryService;
32+
33+
protected final ResponseListener<ExecutionEngine.QueryResponse> listener;
34+
35+
/** Constructor. */
36+
public CommandPlan(QueryId queryId, UnresolvedPlan plan, QueryService queryService,
37+
ResponseListener<ExecutionEngine.QueryResponse> listener) {
38+
super(queryId);
39+
this.plan = plan;
40+
this.queryService = queryService;
41+
this.listener = listener;
42+
}
43+
44+
@Override
45+
public void execute() {
46+
queryService.execute(plan, listener);
47+
}
48+
49+
@Override
50+
public void explain(ResponseListener<ExecutionEngine.ExplainResponse> listener) {
51+
throw new UnsupportedOperationException("CommandPlan does not support explain");
52+
}
53+
}

core/src/main/java/org/opensearch/sql/executor/execution/QueryPlan.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
import org.opensearch.sql.executor.QueryService;
1919

2020
/**
21-
* Query plan. Which includes.
22-
*
23-
* <p>select query.
21+
* Query plan which includes a <em>select</em> query.
2422
*/
2523
public class QueryPlan extends AbstractPlan {
2624

core/src/main/java/org/opensearch/sql/executor/execution/QueryPlanFactory.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import org.opensearch.sql.ast.statement.Explain;
1818
import org.opensearch.sql.ast.statement.Query;
1919
import org.opensearch.sql.ast.statement.Statement;
20+
import org.opensearch.sql.ast.tree.CloseCursor;
2021
import org.opensearch.sql.ast.tree.FetchCursor;
2122
import org.opensearch.sql.ast.tree.UnresolvedPlan;
2223
import org.opensearch.sql.common.response.ResponseListener;
@@ -88,6 +89,15 @@ boolean canConvertToCursor(UnresolvedPlan plan) {
8889
return plan.accept(new CanPaginateVisitor(), null);
8990
}
9091

92+
/**
93+
* Creates a {@link CloseCursor} command on a cursor.
94+
*/
95+
public AbstractPlan createCloseCursor(String cursor,
96+
ResponseListener<ExecutionEngine.QueryResponse> queryResponseListener) {
97+
return new CommandPlan(QueryId.queryId(), new CloseCursor().attach(new FetchCursor(cursor)),
98+
queryService, queryResponseListener);
99+
}
100+
91101
@Override
92102
public AbstractPlan visitQuery(
93103
Query node,

core/src/main/java/org/opensearch/sql/planner/DefaultImplementor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
76
package org.opensearch.sql.planner;
87

98
import org.opensearch.sql.executor.pagination.PlanSerializer;
109
import org.opensearch.sql.planner.logical.LogicalAggregation;
10+
import org.opensearch.sql.planner.logical.LogicalCloseCursor;
1111
import org.opensearch.sql.planner.logical.LogicalDedupe;
1212
import org.opensearch.sql.planner.logical.LogicalEval;
1313
import org.opensearch.sql.planner.logical.LogicalFetchCursor;
@@ -25,6 +25,7 @@
2525
import org.opensearch.sql.planner.logical.LogicalValues;
2626
import org.opensearch.sql.planner.logical.LogicalWindow;
2727
import org.opensearch.sql.planner.physical.AggregationOperator;
28+
import org.opensearch.sql.planner.physical.CursorCloseOperator;
2829
import org.opensearch.sql.planner.physical.DedupeOperator;
2930
import org.opensearch.sql.planner.physical.EvalOperator;
3031
import org.opensearch.sql.planner.physical.FilterOperator;
@@ -155,6 +156,11 @@ public PhysicalPlan visitFetchCursor(LogicalFetchCursor plan, C context) {
155156
return new PlanSerializer(plan.getEngine()).convertToPlan(plan.getCursor());
156157
}
157158

159+
@Override
160+
public PhysicalPlan visitCloseCursor(LogicalCloseCursor node, C context) {
161+
return new CursorCloseOperator(visitChild(node, context));
162+
}
163+
158164
protected PhysicalPlan visitChild(LogicalPlan node, C context) {
159165
// Logical operators visited here must have a single child
160166
return node.getChild().get(0).accept(this, context);
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.sql.planner.logical;
7+
8+
import java.util.List;
9+
import lombok.EqualsAndHashCode;
10+
import lombok.ToString;
11+
12+
/**
13+
* A logical plan node which wraps {@link org.opensearch.sql.planner.LogicalCursor}
14+
* and represent a cursor close operation.
15+
*/
16+
@ToString
17+
@EqualsAndHashCode(callSuper = false)
18+
public class LogicalCloseCursor extends LogicalPlan {
19+
20+
public LogicalCloseCursor(LogicalPlan child) {
21+
super(List.of(child));
22+
}
23+
24+
@Override
25+
public <R, C> R accept(LogicalPlanNodeVisitor<R, C> visitor, C context) {
26+
return visitor.visitCloseCursor(this, context);
27+
}
28+
}

core/src/main/java/org/opensearch/sql/planner/logical/LogicalFetchCursor.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
import org.opensearch.sql.planner.logical.LogicalPlanNodeVisitor;
1414
import org.opensearch.sql.storage.StorageEngine;
1515

16+
/**
17+
* A plan node which represents operation of fetching a next page from the cursor.
18+
*/
1619
@EqualsAndHashCode(callSuper = false)
1720
@ToString
1821
public class LogicalFetchCursor extends LogicalPlan {

core/src/main/java/org/opensearch/sql/planner/logical/LogicalPlanNodeVisitor.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,4 +112,8 @@ public R visitPaginate(LogicalPaginate plan, C context) {
112112
public R visitFetchCursor(LogicalFetchCursor plan, C context) {
113113
return visitNode(plan, context);
114114
}
115+
116+
public R visitCloseCursor(LogicalCloseCursor plan, C context) {
117+
return visitNode(plan, context);
118+
}
115119
}

0 commit comments

Comments
 (0)