Skip to content

Commit

Permalink
Merge branch '2.x' into Spotless_Backport_6_pt2
Browse files Browse the repository at this point in the history
Signed-off-by: Mitchell Gale <Mitchell.gale@improving.com>
  • Loading branch information
MitchellGale authored Aug 22, 2023
2 parents c7c41cc + d205bd6 commit 6d38ab2
Show file tree
Hide file tree
Showing 14 changed files with 106 additions and 44 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,17 @@
import org.opensearch.sql.planner.logical.LogicalWindow;

/**
* The optimizer used to replace the expression referred in the SelectClause e.g. The query SELECT
* abs(name), sum(age)-avg(age) FROM test GROUP BY abs(name). will be translated the AST
* Project[abs(age), sub(sum(age), avg(age)) Agg(agg=[sum(age), avg(age)], group=[abs(age)]]
* Relation The sum(age) and avg(age) in the Project could be replace by the analyzed reference, the
* LogicalPlan should be LogicalProject[Ref("abs(age)"), sub(Ref("sum(age)"), Ref("avg(age)"))
* LogicalAgg(agg=[sum(age), avg(age)], group=[abs(age)]] LogicalRelation
* The optimizer used to replace the expression referred in the SelectClause</br> e.g. The query
* SELECT abs(name), sum(age)-avg(age) FROM test GROUP BY abs(name).<br>
* will be translated the AST<br>
* Project[abs(age), sub(sum(age), avg(age))<br>
* &ensp Agg(agg=[sum(age), avg(age)], group=[abs(age)]]<br>
* &emsp Relation<br>
* The sum(age) and avg(age) in the Project could be replaced by the analyzed reference, the
* LogicalPlan should be<br>
* LogicalProject[Ref("abs(age)"), sub(Ref("sum(age)"), Ref("avg(age)"))<br>
* &ensp LogicalAgg(agg=[sum(age), avg(age)], group=[abs(age)]]<br>
* &emsp LogicalRelation
*/
public class ExpressionReferenceOptimizer
extends ExpressionNodeVisitor<Expression, AnalysisContext> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,17 @@ public List<NamedExpression> visitAlias(Alias node, AnalysisContext context) {
}

/**
* The Alias could be 1. SELECT name, AVG(age) FROM s BY name -> Project(Alias("name", expr),
* Alias("AVG(age)", aggExpr)) Agg(Alias("AVG(age)", aggExpr)) 2. SELECT length(name), AVG(age)
* FROM s BY length(name) Project(Alias("name", expr), Alias("AVG(age)", aggExpr))
* Agg(Alias("AVG(age)", aggExpr)) 3. SELECT length(name) as l, AVG(age) FROM s BY l
* Project(Alias("name", expr, l), Alias("AVG(age)", aggExpr)) Agg(Alias("AVG(age)", aggExpr),
* Alias("length(name)", groupExpr))
* The Alias could be
*
* <ol>
* <li>SELECT name, AVG(age) FROM s BY name -> Project(Alias("name", expr), Alias("AVG(age)",
* aggExpr)) Agg(Alias("AVG(age)", aggExpr))
* <li>SELECT length(name), AVG(age) FROM s BY length(name) Project(Alias("name", expr),
* Alias("AVG(age)", aggExpr)) Agg(Alias("AVG(age)", aggExpr))
* <li>SELECT length(name) as l, AVG(age) FROM s BY l Project(Alias("name", expr, l),
* Alias("AVG(age)", aggExpr)) Agg(Alias("AVG(age)", aggExpr), Alias("length(name)",
* groupExpr))
* </ol>
*/
private Expression referenceIfSymbolDefined(Alias expr, AnalysisContext context) {
UnresolvedExpression delegatedExpr = expr.getDelegated();
Expand Down
18 changes: 14 additions & 4 deletions core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -247,16 +247,26 @@ public static Function function(String funcName, UnresolvedExpression... funcArg
}

/**
* CASE WHEN search_condition THEN result_expr [WHEN search_condition THEN result_expr] ... [ELSE
* result_expr] END
* <pre>
* CASE
* WHEN search_condition THEN result_expr<br>
* [WHEN search_condition THEN result_expr] ...
* [ELSE result_expr]
* END
* </pre>
*/
public UnresolvedExpression caseWhen(UnresolvedExpression elseClause, When... whenClauses) {
return caseWhen(null, elseClause, whenClauses);
}

/**
* CASE case_value_expr WHEN compare_expr THEN result_expr [WHEN compare_expr THEN result_expr]
* ... [ELSE result_expr] END
* <pre>
* CASE case_value_expr
* WHEN compare_expr THEN result_expr
* [WHEN compare_expr THEN result_expr] ...
* [ELSE result_expr]
* END
* </pre>
*/
public UnresolvedExpression caseWhen(
UnresolvedExpression caseValueExpr, UnresolvedExpression elseClause, When... whenClauses) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ public Optional<String> first() {

/**
* Get rest parts of the qualified name. Assume that there must be remaining parts so caller is
* responsible for the check (first() or size() must be called first). For example: {@code
* QualifiedName name = ... Optional<String> first = name.first(); if (first.isPresent()) {
* name.rest() ... } }
*
* responsible for the check (first() or size() must be called first).<br>
* For example:<br>
* {@code<br>
* &nbsp; QualifiedName name = ...<br>
* &nbsp; Optional<String> first = name.first();<br>
* &nbsp; if (first.isPresent()) {<br>
* &ensp; name.rest() ...<br>
* &nbsp; }<br>
* }
* @return rest part(s)
*/
public QualifiedName rest() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
import lombok.RequiredArgsConstructor;
import org.opensearch.sql.ast.AbstractNodeVisitor;

/** An unresolved plan that represents fetching the next batch in paginationed plan. */
/** An unresolved plan that represents fetching the next batch in paginated plan. */

@RequiredArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class FetchCursor extends UnresolvedPlan {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import org.opensearch.sql.ast.expression.QualifiedName;
import org.opensearch.sql.ast.expression.UnresolvedExpression;


/** ASTNode for Table Function. */
@ToString
@EqualsAndHashCode(callSuper = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,35 @@ public int compareTo(ExprValue other) {
}

/**
* The customize equals logic. The table below list the NULL and MISSING handling logic. A B A ==
* B NULL NULL TRUE NULL MISSING FALSE MISSING NULL FALSE MISSING MISSING TRUE
* The customize equals logic.
* The table below list the NULL and MISSING handling logic.
* <table>
* <tr>
* <th>A</th>
* <th>B</th>
* <th>A == B</th>
* </tr>
* <tr>
* <td>NULL</td>
* <td>NULL</td>
* <td>TRUE</td>
* </tr>
* <tr>
* <td>NULL</td>
* <td>MISSING</td>
* <td>FALSE</td>
* </tr>
* <tr>
* <td>MISSING</td>
* <td>NULL</td>
* <td>FALSE</td>
* </tr>
* <tr>
* <td>MISSING</td>
* <td>MISSING</td>
* <td>TRUE</td>
* </tr>
* </table>
*/
@Override
public boolean equals(Object o) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public ExprDateValue(String date) {
this.date = LocalDate.parse(date, DATE_TIME_FORMATTER_VARIABLE_NANOS_OPTIONAL);
} catch (DateTimeParseException e) {
throw new SemanticCheckException(
String.format("date:%s in unsupported format, please use " + "yyyy-MM-dd", date));
String.format("date:%s in unsupported format, please use 'yyyy-MM-dd'", date));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public ExprDatetimeValue(String datetime) {
} catch (DateTimeParseException e) {
throw new SemanticCheckException(
String.format(
"datetime:%s in unsupported format, please " + "use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
"datetime:%s in unsupported format, please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
datetime));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,7 @@ public LocalDateTime datetimeValue() {
} catch (SemanticCheckException exception) {
throw new SemanticCheckException(
String.format(
"datetime:%s in unsupported format, please "
+ "use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
"datetime:%s in unsupported format, please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
value));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public ExprTimeValue(String time) {
} catch (DateTimeParseException e) {
throw new SemanticCheckException(
String.format(
"time:%s in unsupported format, please use " + "HH:mm:ss[.SSSSSSSSS]", time));
"time:%s in unsupported format, please use 'HH:mm:ss[.SSSSSSSSS]'", time));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public ExprTimestampValue(String timestamp) {
} catch (DateTimeParseException e) {
throw new SemanticCheckException(
String.format(
"timestamp:%s in unsupported format, please " + "use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
"timestamp:%s in unsupported format, please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
timestamp));
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,18 @@
import org.opensearch.sql.exception.ExpressionEvaluationException;

/**
* The definition of widening type rule for expression value. ExprType Widens to data types INTEGER
* LONG, FLOAT, DOUBLE LONG FLOAT, DOUBLE FLOAT DOUBLE DOUBLE DOUBLE STRING STRING BOOLEAN BOOLEAN
* ARRAY ARRAY STRUCT STRUCT
* The definition of widening type rule for expression value.
* <table border="3">
* <tr><th>ExprType</th><th>Widens to data types</th></tr>
* <tr><td>INTEGER</td><td>LONG, FLOAT, DOUBLE</td></tr>
* <tr><td>LONG</td><td>FLOAT, DOUBLE</td></tr>
* <tr><td>FLOAT</td><td>DOUBLE</td></tr>
* <tr><td>DOUBLE</td><td>DOUBLE</td></tr>
* <tr><td>STRING</td><td>STRING</td></tr>
* <tr><td>BOOLEAN</td><td>BOOLEAN</td></tr>
* <tr><td>ARRAY</td><td>ARRAY</td></tr>
* <tr><td>STRUCT</td><td>STRUCT</td></tr>
* </table>
*/
@UtilityClass
public class WideningTypeRule {
Expand Down Expand Up @@ -47,7 +56,7 @@ private static int distance(ExprType type1, ExprType type2, int distance) {

/**
* The max type among two types. The max is defined as follow if type1 could widen to type2, then
* max is type2, vice versa if type1 could't widen to type2 and type2 could't widen to type1, then
* max is type2, vice versa if type1 couldn't widen to type2 and type2 could't widen to type1, then
* throw {@link ExpressionEvaluationException}.
*
* @param type1 type1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,15 +113,15 @@ public void dateInUnsupportedFormat() {
SemanticCheckException exception =
assertThrows(SemanticCheckException.class, () -> new ExprDateValue("2020-07-07Z"));
assertEquals(
"date:2020-07-07Z in unsupported format, please use yyyy-MM-dd", exception.getMessage());
"date:2020-07-07Z in unsupported format, please use 'yyyy-MM-dd'", exception.getMessage());
}

@Test
public void timeInUnsupportedFormat() {
SemanticCheckException exception =
assertThrows(SemanticCheckException.class, () -> new ExprTimeValue("01:01:0"));
assertEquals(
"time:01:01:0 in unsupported format, please use HH:mm:ss[.SSSSSSSSS]",
"time:01:01:0 in unsupported format, please use 'HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand All @@ -132,7 +132,7 @@ public void timestampInUnsupportedFormat() {
SemanticCheckException.class, () -> new ExprTimestampValue("2020-07-07T01:01:01Z"));
assertEquals(
"timestamp:2020-07-07T01:01:01Z in unsupported format, "
+ "please use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
+ "please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand All @@ -143,7 +143,7 @@ public void datetimeInUnsupportedFormat() {
SemanticCheckException.class, () -> new ExprDatetimeValue("2020-07-07T01:01:01Z"));
assertEquals(
"datetime:2020-07-07T01:01:01Z in unsupported format, "
+ "please use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
+ "please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand All @@ -162,7 +162,7 @@ public void stringDateTimeValue() {
() -> new ExprStringValue("2020-07-07T01:01:01Z").datetimeValue());
assertEquals(
"datetime:2020-07-07T01:01:01Z in unsupported format, "
+ "please use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
+ "please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand All @@ -178,7 +178,7 @@ public void stringDateValue() {
assertThrows(
SemanticCheckException.class, () -> new ExprStringValue("2020-07-07Z").dateValue());
assertEquals(
"date:2020-07-07Z in unsupported format, please use yyyy-MM-dd", exception.getMessage());
"date:2020-07-07Z in unsupported format, please use 'yyyy-MM-dd'", exception.getMessage());
}

@Test
Expand All @@ -192,7 +192,7 @@ public void stringTimeValue() {
assertThrows(
SemanticCheckException.class, () -> new ExprStringValue("01:01:0").timeValue());
assertEquals(
"time:01:01:0 in unsupported format, please use HH:mm:ss[.SSSSSSSSS]",
"time:01:01:0 in unsupported format, please use 'HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand Down Expand Up @@ -260,8 +260,8 @@ public void timestampOverMaxNanoPrecision() {
SemanticCheckException.class,
() -> new ExprTimestampValue("2020-07-07 01:01:01.1234567890"));
assertEquals(
"timestamp:2020-07-07 01:01:01.1234567890 in unsupported format, "
+ "please use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
"timestamp:2020-07-07 01:01:01.1234567890 in unsupported format, please use "
+ "'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand All @@ -273,7 +273,7 @@ public void datetimeOverMaxNanoPrecision() {
() -> new ExprDatetimeValue("2020-07-07 01:01:01.1234567890"));
assertEquals(
"datetime:2020-07-07 01:01:01.1234567890 in unsupported format, "
+ "please use yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]",
+ "please use 'yyyy-MM-dd HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}

Expand All @@ -282,7 +282,7 @@ public void timeOverMaxNanoPrecision() {
SemanticCheckException exception =
assertThrows(SemanticCheckException.class, () -> new ExprTimeValue("01:01:01.1234567890"));
assertEquals(
"time:01:01:01.1234567890 in unsupported format, please use HH:mm:ss[.SSSSSSSSS]",
"time:01:01:01.1234567890 in unsupported format, please use 'HH:mm:ss[.SSSSSSSSS]'",
exception.getMessage());
}
}

0 comments on commit 6d38ab2

Please sign in to comment.