Skip to content

Commit 32fc251

Browse files
authored
Merge pull request #3448 from penghuo/calciteEngineMergeV2
Signed-off-by: Yuanchun Shen <[email protected]>
2 parents f805df0 + abf69e6 commit 32fc251

File tree

206 files changed

+18496
-327
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

206 files changed

+18496
-327
lines changed

benchmarks/build.gradle

+9
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,13 @@ dependencies {
2020
annotationProcessor group: 'org.openjdk.jmh', name: 'jmh-generator-annprocess', version: '1.36'
2121
}
2222

23+
spotless {
24+
java {
25+
target fileTree('.') {
26+
include '**/*.java'
27+
exclude '**/jmh_generated/**'
28+
}
29+
}
30+
}
31+
2332
compileJava.options.compilerArgs.addAll(["-processor", "org.openjdk.jmh.generators.BenchmarkProcessor"])

build.gradle

+17
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,23 @@ allprojects {
130130
resolutionStrategy.force "org.jetbrains.kotlin:kotlin-stdlib:1.9.10"
131131
resolutionStrategy.force "org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10"
132132
resolutionStrategy.force "net.bytebuddy:byte-buddy:1.14.19"
133+
resolutionStrategy.force "org.apache.httpcomponents.client5:httpclient5:${versions.httpclient5}"
134+
resolutionStrategy.force "org.apache.httpcomponents.core5:httpcore5:${versions.httpcore5}"
135+
resolutionStrategy.force "org.apache.httpcomponents.core5:httpcore5-h2:${versions.httpcore5}"
136+
resolutionStrategy.force "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}"
137+
resolutionStrategy.force "com.fasterxml.jackson.core:jackson-core:${versions.jackson}"
138+
resolutionStrategy.force "com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}"
139+
resolutionStrategy.force "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:${versions.jackson}"
140+
resolutionStrategy.force "com.fasterxml.jackson.dataformat:jackson-dataformat-smile:${versions.jackson}"
141+
resolutionStrategy.force "com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:${versions.jackson}"
142+
resolutionStrategy.force 'com.google.protobuf:protobuf-java:3.25.5'
143+
resolutionStrategy.force 'org.locationtech.jts:jts-core:1.19.0'
144+
resolutionStrategy.force 'com.google.errorprone:error_prone_annotations:2.28.0'
145+
resolutionStrategy.force 'org.checkerframework:checker-qual:3.43.0'
146+
resolutionStrategy.force 'org.apache.commons:commons-lang3:3.13.0'
147+
resolutionStrategy.force 'org.apache.commons:commons-text:1.11.0'
148+
resolutionStrategy.force 'commons-io:commons-io:2.15.0'
149+
resolutionStrategy.force 'org.yaml:snakeyaml:2.2'
133150
}
134151
}
135152

common/src/main/java/org/opensearch/sql/common/setting/Settings.java

+5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,11 @@ public enum Key {
2727
PPL_ENABLED("plugins.ppl.enabled"),
2828
DEFAULT_PATTERN_METHOD("plugins.ppl.default.pattern.method"),
2929

30+
/** Enable Calcite as execution engine */
31+
CALCITE_ENGINE_ENABLED("plugins.calcite.enabled"),
32+
CALCITE_FALLBACK_ALLOWED("plugins.calcite.fallback.allowed"),
33+
CALCITE_PUSHDOWN_ENABLED("plugins.calcite.pushdown.enabled"),
34+
3035
/** Query Settings. */
3136
FIELD_TYPE_TOLERANCE("plugins.query.field_type_tolerance"),
3237

core/build.gradle

+9-4
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,14 @@ dependencies {
5656
api "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}"
5757
api group: 'com.google.code.gson', name: 'gson', version: '2.8.9'
5858
api group: 'com.tdunning', name: 't-digest', version: '3.3'
59+
api 'org.apache.calcite:calcite-core:1.38.0'
60+
api 'org.apache.calcite:calcite-linq4j:1.38.0'
5961
api project(':common')
6062
implementation "com.github.seancfoley:ipaddress:5.4.2"
6163

64+
annotationProcessor('org.immutables:value:2.8.8')
65+
compileOnly('org.immutables:value-annotations:2.8.8')
66+
6267
testImplementation('org.junit.jupiter:junit-jupiter:5.9.3')
6368
testImplementation group: 'org.hamcrest', name: 'hamcrest-library', version: "${hamcrest_version}"
6469
testImplementation group: 'org.mockito', name: 'mockito-core', version: "${mockito_version}"
@@ -113,22 +118,22 @@ jacocoTestCoverageVerification {
113118
'org.opensearch.sql.utils.Constants',
114119
'org.opensearch.sql.datasource.model.DataSource',
115120
'org.opensearch.sql.datasource.model.DataSourceStatus',
116-
'org.opensearch.sql.datasource.model.DataSourceType'
121+
'org.opensearch.sql.datasource.model.DataSourceType',
117122
]
118123
limit {
119124
counter = 'LINE'
120-
minimum = 1.0
125+
minimum = 0.0 // calcite dev only
121126
}
122127
limit {
123128
counter = 'BRANCH'
124-
minimum = 1.0
129+
minimum = 0.0 // calcite dev only
125130
}
126131
}
127132
}
128133
afterEvaluate {
129134
classDirectories.setFrom(files(classDirectories.files.collect {
130135
fileTree(dir: it,
131-
exclude: ['**/ast/**'])
136+
exclude: ['**/ast/**', '**/calcite/**']) // calcite dev only
132137
}))
133138
}
134139
}

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

+22-6
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import org.opensearch.sql.ast.tree.Rename;
6666
import org.opensearch.sql.ast.tree.Sort;
6767
import org.opensearch.sql.ast.tree.Sort.SortOption;
68+
import org.opensearch.sql.ast.tree.SubqueryAlias;
6869
import org.opensearch.sql.ast.tree.TableFunction;
6970
import org.opensearch.sql.ast.tree.Trendline;
7071
import org.opensearch.sql.ast.tree.UnresolvedPlan;
@@ -145,6 +146,27 @@ public LogicalPlan analyze(UnresolvedPlan unresolved, AnalysisContext context) {
145146
return unresolved.accept(this, context);
146147
}
147148

149+
@Override
150+
public LogicalPlan visitSubqueryAlias(SubqueryAlias node, AnalysisContext context) {
151+
LogicalPlan child = analyze(node.getChild().get(0), context);
152+
if (child instanceof LogicalRelation) {
153+
// Put index name or its alias in index namespace on type environment so qualifier
154+
// can be removed when analyzing qualified name. The value (expr type) here doesn't matter.
155+
TypeEnvironment curEnv = context.peek();
156+
curEnv.define(
157+
new Symbol(
158+
Namespace.INDEX_NAME,
159+
(node.getAlias() == null)
160+
? ((LogicalRelation) child).getRelationName()
161+
: node.getAlias()),
162+
STRUCT);
163+
return child;
164+
} else {
165+
// TODO
166+
throw new UnsupportedOperationException("SubqueryAlias is only supported in table alias");
167+
}
168+
}
169+
148170
@Override
149171
public LogicalPlan visitRelation(Relation node, AnalysisContext context) {
150172
QualifiedName qualifiedName = node.getTableQualifiedName();
@@ -172,12 +194,6 @@ public LogicalPlan visitRelation(Relation node, AnalysisContext context) {
172194
.getReservedFieldTypes()
173195
.forEach((k, v) -> curEnv.define(new Symbol(Namespace.HIDDEN_FIELD_NAME, k), v));
174196

175-
// Put index name or its alias in index namespace on type environment so qualifier
176-
// can be removed when analyzing qualified name. The value (expr type) here doesn't matter.
177-
curEnv.define(
178-
new Symbol(Namespace.INDEX_NAME, (node.getAlias() == null) ? tableName : node.getAlias()),
179-
STRUCT);
180-
181197
return new LogicalRelation(tableName, table);
182198
}
183199

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

+30
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@
3636
import org.opensearch.sql.ast.expression.When;
3737
import org.opensearch.sql.ast.expression.WindowFunction;
3838
import org.opensearch.sql.ast.expression.Xor;
39+
import org.opensearch.sql.ast.expression.subquery.ExistsSubquery;
40+
import org.opensearch.sql.ast.expression.subquery.InSubquery;
41+
import org.opensearch.sql.ast.expression.subquery.ScalarSubquery;
3942
import org.opensearch.sql.ast.statement.Explain;
4043
import org.opensearch.sql.ast.statement.Query;
4144
import org.opensearch.sql.ast.statement.Statement;
@@ -48,8 +51,10 @@
4851
import org.opensearch.sql.ast.tree.FillNull;
4952
import org.opensearch.sql.ast.tree.Filter;
5053
import org.opensearch.sql.ast.tree.Head;
54+
import org.opensearch.sql.ast.tree.Join;
5155
import org.opensearch.sql.ast.tree.Kmeans;
5256
import org.opensearch.sql.ast.tree.Limit;
57+
import org.opensearch.sql.ast.tree.Lookup;
5358
import org.opensearch.sql.ast.tree.ML;
5459
import org.opensearch.sql.ast.tree.Paginate;
5560
import org.opensearch.sql.ast.tree.Parse;
@@ -59,6 +64,7 @@
5964
import org.opensearch.sql.ast.tree.RelationSubquery;
6065
import org.opensearch.sql.ast.tree.Rename;
6166
import org.opensearch.sql.ast.tree.Sort;
67+
import org.opensearch.sql.ast.tree.SubqueryAlias;
6268
import org.opensearch.sql.ast.tree.TableFunction;
6369
import org.opensearch.sql.ast.tree.Trendline;
6470
import org.opensearch.sql.ast.tree.Values;
@@ -312,6 +318,10 @@ public T visitExplain(Explain node, C context) {
312318
return visitStatement(node, context);
313319
}
314320

321+
public T visitInSubquery(InSubquery node, C context) {
322+
return visitChildren(node, context);
323+
}
324+
315325
public T visitPaginate(Paginate paginate, C context) {
316326
return visitChildren(paginate, context);
317327
}
@@ -331,4 +341,24 @@ public T visitFillNull(FillNull fillNull, C context) {
331341
public T visitWindow(Window window, C context) {
332342
return visitChildren(window, context);
333343
}
344+
345+
public T visitJoin(Join node, C context) {
346+
return visitChildren(node, context);
347+
}
348+
349+
public T visitLookup(Lookup node, C context) {
350+
return visitChildren(node, context);
351+
}
352+
353+
public T visitSubqueryAlias(SubqueryAlias node, C context) {
354+
return visitChildren(node, context);
355+
}
356+
357+
public T visitScalarSubquery(ScalarSubquery node, C context) {
358+
return visitChildren(node, context);
359+
}
360+
361+
public T visitExistsSubquery(ExistsSubquery node, C context) {
362+
return visitChildren(node, context);
363+
}
334364
}

core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.opensearch.sql.ast.expression.Xor;
5252
import org.opensearch.sql.ast.tree.Aggregation;
5353
import org.opensearch.sql.ast.tree.Dedupe;
54+
import org.opensearch.sql.ast.tree.DescribeRelation;
5455
import org.opensearch.sql.ast.tree.Eval;
5556
import org.opensearch.sql.ast.tree.FillNull;
5657
import org.opensearch.sql.ast.tree.Filter;
@@ -65,6 +66,7 @@
6566
import org.opensearch.sql.ast.tree.Rename;
6667
import org.opensearch.sql.ast.tree.Sort;
6768
import org.opensearch.sql.ast.tree.Sort.SortOption;
69+
import org.opensearch.sql.ast.tree.SubqueryAlias;
6870
import org.opensearch.sql.ast.tree.TableFunction;
6971
import org.opensearch.sql.ast.tree.Trendline;
7072
import org.opensearch.sql.ast.tree.UnresolvedPlan;
@@ -93,7 +95,15 @@ public UnresolvedPlan relation(QualifiedName tableName) {
9395
}
9496

9597
public UnresolvedPlan relation(String tableName, String alias) {
96-
return new Relation(qualifiedName(tableName), alias);
98+
return new SubqueryAlias(alias, new Relation(qualifiedName(tableName)));
99+
}
100+
101+
public UnresolvedPlan describe(String tableName) {
102+
return new DescribeRelation(qualifiedName(tableName));
103+
}
104+
105+
public UnresolvedPlan subqueryAlias(UnresolvedPlan child, String alias) {
106+
return new SubqueryAlias(child, alias);
97107
}
98108

99109
public UnresolvedPlan tableFunction(List<String> functionName, UnresolvedExpression... args) {
@@ -389,6 +399,7 @@ public Alias alias(String name, UnresolvedExpression expr) {
389399
return new Alias(name, expr);
390400
}
391401

402+
@Deprecated
392403
public Alias alias(String name, UnresolvedExpression expr, String alias) {
393404
return new Alias(name, expr, alias);
394405
}

core/src/main/java/org/opensearch/sql/ast/expression/Alias.java

+6-6
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
import org.opensearch.sql.ast.AbstractNodeVisitor;
1414

1515
/**
16-
* Alias abstraction that associate an unnamed expression with a name and an optional alias. The
17-
* name and alias information preserved is useful for semantic analysis and response formatting
18-
* eventually. This can avoid restoring the info in toString() method which is inaccurate because
19-
* original info is already lost.
16+
* Alias abstraction that associate an unnamed expression with a name. The name information
17+
* preserved is useful for semantic analysis and response formatting eventually. This can avoid
18+
* restoring the info in toString() method which is inaccurate because original info is already
19+
* lost.
2020
*/
2121
@AllArgsConstructor
2222
@EqualsAndHashCode(callSuper = false)
@@ -25,13 +25,13 @@
2525
@ToString
2626
public class Alias extends UnresolvedExpression {
2727

28-
/** Original field name. */
28+
/** The name to be associated with the result of computing delegated expression. */
2929
private final String name;
3030

3131
/** Expression aliased. */
3232
private final UnresolvedExpression delegated;
3333

34-
/** Optional field alias. */
34+
/** TODO. Optional field alias. */
3535
private String alias;
3636

3737
@Override

core/src/main/java/org/opensearch/sql/ast/expression/Cast.java

+14
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,20 @@ public static boolean isCastFunction(FunctionName name) {
7676
return CONVERTED_TYPE_FUNCTION_NAME_MAP.containsValue(name);
7777
}
7878

79+
/** Get the data type expression of the converted type. */
80+
public DataType getDataType() {
81+
String type = convertedType.toString().toUpperCase(Locale.ROOT);
82+
if ("INT".equals(type)) {
83+
type = "INTEGER";
84+
}
85+
// JSON is not a data type for now, we convert it to STRING.
86+
// TODO Maybe its data type could be VARIANT in future?
87+
if ("JSON".equals(type)) {
88+
type = "STRING";
89+
}
90+
return DataType.valueOf(type);
91+
}
92+
7993
/**
8094
* Get the cast function name for a given target data type.
8195
*

core/src/main/java/org/opensearch/sql/ast/expression/DataType.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ public enum DataType {
2626
DATE(ExprCoreType.DATE),
2727
TIME(ExprCoreType.TIME),
2828
TIMESTAMP(ExprCoreType.TIMESTAMP),
29-
INTERVAL(ExprCoreType.INTERVAL);
29+
INTERVAL(ExprCoreType.INTERVAL),
30+
31+
IP(ExprCoreType.IP);
3032

3133
@Getter private final ExprCoreType coreType;
3234
}
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.expression.subquery;
7+
8+
import com.google.common.collect.ImmutableList;
9+
import java.util.List;
10+
import lombok.EqualsAndHashCode;
11+
import lombok.Getter;
12+
import lombok.RequiredArgsConstructor;
13+
import org.opensearch.sql.ast.AbstractNodeVisitor;
14+
import org.opensearch.sql.ast.expression.UnresolvedExpression;
15+
import org.opensearch.sql.ast.tree.UnresolvedPlan;
16+
import org.opensearch.sql.common.utils.StringUtils;
17+
18+
@Getter
19+
@EqualsAndHashCode(callSuper = true)
20+
@RequiredArgsConstructor
21+
public class ExistsSubquery extends SubqueryExpression {
22+
private final UnresolvedPlan query;
23+
24+
@Override
25+
public <R, C> R accept(AbstractNodeVisitor<R, C> nodeVisitor, C context) {
26+
return nodeVisitor.visitExistsSubquery(this, context);
27+
}
28+
29+
@Override
30+
public List<UnresolvedExpression> getChild() {
31+
return ImmutableList.of();
32+
}
33+
34+
@Override
35+
public String toString() {
36+
return StringUtils.format("exists ( %s )", query);
37+
}
38+
}
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.expression.subquery;
7+
8+
import java.util.List;
9+
import lombok.EqualsAndHashCode;
10+
import lombok.Getter;
11+
import lombok.RequiredArgsConstructor;
12+
import org.opensearch.sql.ast.AbstractNodeVisitor;
13+
import org.opensearch.sql.ast.expression.UnresolvedExpression;
14+
import org.opensearch.sql.ast.tree.UnresolvedPlan;
15+
import org.opensearch.sql.common.utils.StringUtils;
16+
17+
@Getter
18+
@EqualsAndHashCode(callSuper = true)
19+
@RequiredArgsConstructor
20+
public class InSubquery extends SubqueryExpression {
21+
private final List<UnresolvedExpression> value;
22+
private final UnresolvedPlan query;
23+
24+
@Override
25+
public List<UnresolvedExpression> getChild() {
26+
return value;
27+
}
28+
29+
@Override
30+
public <R, C> R accept(AbstractNodeVisitor<R, C> nodeVisitor, C context) {
31+
return nodeVisitor.visitInSubquery(this, context);
32+
}
33+
34+
@Override
35+
public String toString() {
36+
return StringUtils.format("%s in ( %s )", value, query);
37+
}
38+
}

0 commit comments

Comments
 (0)