Skip to content
This repository was archived by the owner on Aug 2, 2022. It is now read-only.

Commit 89c6e05

Browse files
authored
Merge develop to master for ODFE 1.10.1.0 release (#733)
Merge develop to master for ODFE 1.10.1.0 release
2 parents 9e82a91 + f40fed6 commit 89c6e05

File tree

188 files changed

+5717
-1307
lines changed

Some content is hidden

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

188 files changed

+5717
-1307
lines changed

.github/workflows/draft-release-notes-workflow.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ jobs:
1616
with:
1717
config-name: draft-release-notes-config.yml
1818
tag: (None)
19-
version: 1.10.0.0
19+
version: 1.10.1.0
2020
env:
2121
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

.github/workflows/sql-workbench-release-workflow.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,14 +27,14 @@ jobs:
2727
uses: actions/checkout@v1
2828
with:
2929
repository: opendistro-for-elasticsearch/kibana-oss
30-
ref: 7.9.0
30+
ref: 7.9.1
3131
token: ${{secrets.OD_ACCESS}}
3232
path: sql/kibana
3333

3434
- name: Setup Node
3535
uses: actions/setup-node@v1
3636
with:
37-
node-version: '10.21.0'
37+
node-version: '10.22.0'
3838

3939
- name: Move Workbench to Plugins Dir
4040
run: |

.github/workflows/sql-workbench-test-and-build-workflow.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ jobs:
1515
uses: actions/checkout@v1
1616
with:
1717
repository: elastic/kibana
18-
ref: v7.9.0
18+
ref: v7.9.1
1919
path: sql/kibana
2020
- name: Setup Node
2121
uses: actions/setup-node@v1
2222
with:
23-
node-version: '10.21.0'
23+
node-version: '10.22.0'
2424
- name: Move Workbench to Plugins Dir
2525
run: |
2626
mkdir kibana/plugins

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
buildscript {
1717
ext {
18-
es_version = "7.9.0"
18+
es_version = "7.9.1"
1919
}
2020

2121
repositories {
@@ -43,7 +43,7 @@ repositories {
4343
}
4444

4545
ext {
46-
opendistroVersion = '1.10.0'
46+
opendistroVersion = '1.10.1'
4747
isSnapshot = "true" == System.getProperty("build.snapshot", "true")
4848
}
4949

core/build.gradle

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,13 @@ jacocoTestCoverageVerification {
4949
violationRules {
5050
rule {
5151
limit {
52+
counter = 'LINE'
53+
minimum = 1.0
54+
}
55+
limit {
56+
counter = 'BRANCH'
5257
minimum = 1.0
5358
}
54-
5559
}
5660
}
5761
afterEvaluate {

core/src/main/java/com/amazon/opendistroforelasticsearch/sql/analysis/Analyzer.java

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
package com.amazon.opendistroforelasticsearch.sql.analysis;
1717

18+
import static com.amazon.opendistroforelasticsearch.sql.data.type.ExprCoreType.STRUCT;
19+
1820
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Namespace;
1921
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Symbol;
2022
import com.amazon.opendistroforelasticsearch.sql.ast.AbstractNodeVisitor;
@@ -29,6 +31,7 @@
2931
import com.amazon.opendistroforelasticsearch.sql.ast.tree.Eval;
3032
import com.amazon.opendistroforelasticsearch.sql.ast.tree.Filter;
3133
import com.amazon.opendistroforelasticsearch.sql.ast.tree.Project;
34+
import com.amazon.opendistroforelasticsearch.sql.ast.tree.RareTopN;
3235
import com.amazon.opendistroforelasticsearch.sql.ast.tree.Relation;
3336
import com.amazon.opendistroforelasticsearch.sql.ast.tree.Rename;
3437
import com.amazon.opendistroforelasticsearch.sql.ast.tree.Sort;
@@ -49,6 +52,7 @@
4952
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalFilter;
5053
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalPlan;
5154
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalProject;
55+
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalRareTopN;
5256
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalRelation;
5357
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalRemove;
5458
import com.amazon.opendistroforelasticsearch.sql.planner.logical.LogicalRename;
@@ -99,6 +103,11 @@ public LogicalPlan visitRelation(Relation node, AnalysisContext context) {
99103
TypeEnvironment curEnv = context.peek();
100104
Table table = storageEngine.getTable(node.getTableName());
101105
table.getFieldTypes().forEach((k, v) -> curEnv.define(new Symbol(Namespace.FIELD_NAME, k), v));
106+
107+
// Put index name or its alias in index namespace on type environment so qualifier
108+
// can be removed when analyzing qualified name. The value (expr type) here doesn't matter.
109+
curEnv.define(new Symbol(Namespace.INDEX_NAME, node.getTableNameOrAlias()), STRUCT);
110+
102111
return new LogicalRelation(node.getTableName());
103112
}
104113

@@ -166,6 +175,39 @@ public LogicalPlan visitAggregation(Aggregation node, AnalysisContext context) {
166175
return new LogicalAggregation(child, aggregators, groupBys);
167176
}
168177

178+
/**
179+
* Build {@link LogicalRareTopN}.
180+
*/
181+
@Override
182+
public LogicalPlan visitRareTopN(RareTopN node, AnalysisContext context) {
183+
final LogicalPlan child = node.getChild().get(0).accept(this, context);
184+
185+
ImmutableList.Builder<Expression> groupbyBuilder = new ImmutableList.Builder<>();
186+
for (UnresolvedExpression expr : node.getGroupExprList()) {
187+
groupbyBuilder.add(expressionAnalyzer.analyze(expr, context));
188+
}
189+
ImmutableList<Expression> groupBys = groupbyBuilder.build();
190+
191+
ImmutableList.Builder<Expression> fieldsBuilder = new ImmutableList.Builder<>();
192+
for (Field f : node.getFields()) {
193+
fieldsBuilder.add(expressionAnalyzer.analyze(f, context));
194+
}
195+
ImmutableList<Expression> fields = fieldsBuilder.build();
196+
197+
// new context
198+
context.push();
199+
TypeEnvironment newEnv = context.peek();
200+
groupBys.forEach(group -> newEnv.define(new Symbol(Namespace.FIELD_NAME,
201+
group.toString()), group.type()));
202+
fields.forEach(field -> newEnv.define(new Symbol(Namespace.FIELD_NAME,
203+
field.toString()), field.type()));
204+
205+
List<Argument> options = node.getNoOfResults();
206+
Integer noOfResults = (Integer) options.get(0).getValue().getValue();
207+
208+
return new LogicalRareTopN(child, node.getCommandType(), noOfResults, fields, groupBys);
209+
}
210+
169211
/**
170212
* Build {@link LogicalProject} or {@link LogicalRemove} from {@link Field}.
171213
*

core/src/main/java/com/amazon/opendistroforelasticsearch/sql/analysis/ExpressionAnalyzer.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,13 @@
1919
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Symbol;
2020
import com.amazon.opendistroforelasticsearch.sql.ast.AbstractNodeVisitor;
2121
import com.amazon.opendistroforelasticsearch.sql.ast.expression.AggregateFunction;
22-
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Alias;
2322
import com.amazon.opendistroforelasticsearch.sql.ast.expression.And;
2423
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Compare;
2524
import com.amazon.opendistroforelasticsearch.sql.ast.expression.EqualTo;
2625
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Field;
2726
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Function;
27+
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Interval;
28+
import com.amazon.opendistroforelasticsearch.sql.ast.expression.IntervalUnit;
2829
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Literal;
2930
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Not;
3031
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Or;
@@ -86,6 +87,13 @@ public Expression visitLiteral(Literal node, AnalysisContext context) {
8687
.literal(ExprValueUtils.fromObjectValue(node.getValue(), node.getType().getCoreType()));
8788
}
8889

90+
@Override
91+
public Expression visitInterval(Interval node, AnalysisContext context) {
92+
Expression value = node.getValue().accept(this, context);
93+
Expression unit = DSL.literal(node.getUnit().name());
94+
return dsl.interval(value, unit);
95+
}
96+
8997
@Override
9098
public Expression visitAnd(And node, AnalysisContext context) {
9199
Expression left = node.getLeft().accept(this, context);
@@ -155,13 +163,8 @@ public Expression visitField(Field node, AnalysisContext context) {
155163

156164
@Override
157165
public Expression visitQualifiedName(QualifiedName node, AnalysisContext context) {
158-
// Name with qualifier (index.field, index_alias.field, object/nested.inner_field
159-
// text.keyword) is not supported for now
160-
if (node.getParts().size() > 1) {
161-
throw new SyntaxCheckException(String.format(
162-
"Qualified name [%s] is not supported yet", node));
163-
}
164-
return visitIdentifier(node.toString(), context);
166+
QualifierAnalyzer qualifierAnalyzer = new QualifierAnalyzer(context);
167+
return visitIdentifier(qualifierAnalyzer.unqualified(node), context);
165168
}
166169

167170
private Expression visitIdentifier(String ident, AnalysisContext context) {
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License").
5+
* You may not use this file except in compliance with the License.
6+
* A copy of the License is located at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* or in the "license" file accompanying this file. This file is distributed
11+
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12+
* express or implied. See the License for the specific language governing
13+
* permissions and limitations under the License.
14+
*
15+
*/
16+
17+
package com.amazon.opendistroforelasticsearch.sql.analysis;
18+
19+
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Namespace;
20+
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Symbol;
21+
import com.amazon.opendistroforelasticsearch.sql.ast.expression.QualifiedName;
22+
import com.amazon.opendistroforelasticsearch.sql.common.antlr.SyntaxCheckException;
23+
import com.amazon.opendistroforelasticsearch.sql.exception.SemanticCheckException;
24+
import java.util.Arrays;
25+
import java.util.Optional;
26+
import lombok.RequiredArgsConstructor;
27+
28+
/**
29+
* Analyzer that analyzes qualifier(s) in a full field name.
30+
*/
31+
@RequiredArgsConstructor
32+
public class QualifierAnalyzer {
33+
34+
private final AnalysisContext context;
35+
36+
public String unqualified(String... parts) {
37+
return unqualified(QualifiedName.of(Arrays.asList(parts)));
38+
}
39+
40+
/**
41+
* Get unqualified name if its qualifier symbol found is in index namespace
42+
* on type environment. Unqualified name means name with qualifier removed.
43+
* For example, unqualified name of "accounts.age" or "acc.age" is "age".
44+
*
45+
* @return unqualified name if criteria met above, otherwise original name
46+
*/
47+
public String unqualified(QualifiedName fullName) {
48+
return isQualifierIndexOrAlias(fullName) ? fullName.rest().toString() : fullName.toString();
49+
}
50+
51+
private boolean isQualifierIndexOrAlias(QualifiedName fullName) {
52+
Optional<String> qualifier = fullName.first();
53+
if (qualifier.isPresent()) {
54+
resolveQualifierSymbol(fullName, qualifier.get());
55+
return true;
56+
}
57+
return false;
58+
}
59+
60+
private void resolveQualifierSymbol(QualifiedName fullName, String qualifier) {
61+
try {
62+
context.peek().resolve(new Symbol(Namespace.INDEX_NAME, qualifier));
63+
} catch (SemanticCheckException e) {
64+
// Throw syntax check intentionally to indicate fall back to old engine.
65+
// Need change to semantic check exception in future.
66+
throw new SyntaxCheckException(String.format(
67+
"The qualifier [%s] of qualified name [%s] must be an index name or its alias",
68+
qualifier, fullName));
69+
}
70+
}
71+
72+
}

core/src/main/java/com/amazon/opendistroforelasticsearch/sql/analysis/SelectExpressionAnalyzer.java

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,17 @@
1818
package com.amazon.opendistroforelasticsearch.sql.analysis;
1919

2020
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Namespace;
21+
import com.amazon.opendistroforelasticsearch.sql.analysis.symbol.Symbol;
2122
import com.amazon.opendistroforelasticsearch.sql.ast.AbstractNodeVisitor;
2223
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Alias;
2324
import com.amazon.opendistroforelasticsearch.sql.ast.expression.AllFields;
2425
import com.amazon.opendistroforelasticsearch.sql.ast.expression.Field;
26+
import com.amazon.opendistroforelasticsearch.sql.ast.expression.QualifiedName;
2527
import com.amazon.opendistroforelasticsearch.sql.ast.expression.UnresolvedExpression;
2628
import com.amazon.opendistroforelasticsearch.sql.data.type.ExprType;
29+
import com.amazon.opendistroforelasticsearch.sql.exception.SemanticCheckException;
2730
import com.amazon.opendistroforelasticsearch.sql.expression.DSL;
31+
import com.amazon.opendistroforelasticsearch.sql.expression.Expression;
2832
import com.amazon.opendistroforelasticsearch.sql.expression.NamedExpression;
2933
import com.amazon.opendistroforelasticsearch.sql.expression.ReferenceExpression;
3034
import com.google.common.collect.ImmutableList;
@@ -63,11 +67,26 @@ public List<NamedExpression> visitField(Field node, AnalysisContext context) {
6367

6468
@Override
6569
public List<NamedExpression> visitAlias(Alias node, AnalysisContext context) {
66-
return Collections.singletonList(DSL.named(node.getName(),
67-
node.getDelegated().accept(expressionAnalyzer, context),
70+
Expression expr = referenceIfSymbolDefined(node.getDelegated(), context);
71+
return Collections.singletonList(DSL.named(
72+
unqualifiedNameIfFieldOnly(node, context),
73+
expr,
6874
node.getAlias()));
6975
}
7076

77+
private Expression referenceIfSymbolDefined(UnresolvedExpression expr,
78+
AnalysisContext context) {
79+
try {
80+
// Since resolved aggregator.toString() is used as symbol name, unresolved expression
81+
// needs to be analyzed too to get toString() name for consistency
82+
String symbolName = expressionAnalyzer.analyze(expr, context).toString();
83+
ExprType type = context.peek().resolve(new Symbol(Namespace.FIELD_NAME, symbolName));
84+
return DSL.ref(symbolName, type);
85+
} catch (SemanticCheckException e) {
86+
return expr.accept(expressionAnalyzer, context);
87+
}
88+
}
89+
7190
@Override
7291
public List<NamedExpression> visitAllFields(AllFields node,
7392
AnalysisContext context) {
@@ -76,4 +95,23 @@ public List<NamedExpression> visitAllFields(AllFields node,
7695
return lookupAllFields.entrySet().stream().map(entry -> DSL.named(entry.getKey(),
7796
new ReferenceExpression(entry.getKey(), entry.getValue()))).collect(Collectors.toList());
7897
}
98+
99+
/**
100+
* Get unqualified name if select item is just a field. For example, suppose an index
101+
* named "accounts", return "age" for "SELECT accounts.age". But do nothing for expression
102+
* in "SELECT ABS(accounts.age)".
103+
* Note that an assumption is made implicitly that original name field in Alias must be
104+
* the same as the values in QualifiedName. This is true because AST builder does this.
105+
* Otherwise, what unqualified() returns will override Alias's name as NamedExpression's name
106+
* even though the QualifiedName doesn't have qualifier.
107+
*/
108+
private String unqualifiedNameIfFieldOnly(Alias node, AnalysisContext context) {
109+
UnresolvedExpression selectItem = node.getDelegated();
110+
if (selectItem instanceof QualifiedName) {
111+
QualifierAnalyzer qualifierAnalyzer = new QualifierAnalyzer(context);
112+
return qualifierAnalyzer.unqualified((QualifiedName) selectItem);
113+
}
114+
return node.getName();
115+
}
116+
79117
}

core/src/main/java/com/amazon/opendistroforelasticsearch/sql/analysis/symbol/Namespace.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
*/
2121
public enum Namespace {
2222

23+
INDEX_NAME("Index"),
2324
FIELD_NAME("Field"),
2425
FUNCTION_NAME("Function");
2526

0 commit comments

Comments
 (0)