Skip to content

Commit

Permalink
Add BETWEEN expression in v2 engine (opensearch-project#1163)
Browse files Browse the repository at this point in the history
* Add between grammar and in-memory impl

Signed-off-by: Chen Dai <[email protected]>

* Add comparison test for between

Signed-off-by: Chen Dai <[email protected]>

* Add doctest for between

Signed-off-by: Chen Dai <[email protected]>

* Add not between support

Signed-off-by: Chen Dai <[email protected]>

* Fix doctest failure

Signed-off-by: Chen Dai <[email protected]>

* Refactor to rewrite to basic comparison expression

Signed-off-by: Chen Dai <[email protected]>

* Clean up unused code

Signed-off-by: Chen Dai <[email protected]>

* Prepare to publish PR

Signed-off-by: Chen Dai <[email protected]>

Signed-off-by: Chen Dai <[email protected]>
  • Loading branch information
dai-chen authored Dec 16, 2022
1 parent 8cbd70b commit 6c0af83
Show file tree
Hide file tree
Showing 9 changed files with 169 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@

package org.opensearch.sql.analysis;

import static org.opensearch.sql.ast.dsl.AstDSL.and;
import static org.opensearch.sql.ast.dsl.AstDSL.compare;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.GTE;
import static org.opensearch.sql.expression.function.BuiltinFunctionName.LTE;

import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
Expand All @@ -22,6 +27,7 @@
import org.opensearch.sql.ast.expression.AggregateFunction;
import org.opensearch.sql.ast.expression.AllFields;
import org.opensearch.sql.ast.expression.And;
import org.opensearch.sql.ast.expression.Between;
import org.opensearch.sql.ast.expression.Case;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
Expand Down Expand Up @@ -229,6 +235,14 @@ public Expression visitCompare(Compare node, AnalysisContext context) {
functionName, Arrays.asList(left, right));
}

@Override
public Expression visitBetween(Between node, AnalysisContext context) {
return and(
compare(">=", node.getValue(), node.getLowerBound()),
compare("<=", node.getValue(), node.getUpperBound())
).accept(this, context);
}

@Override
public Expression visitCase(Case node, AnalysisContext context) {
List<WhenClause> whens = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.opensearch.sql.ast.expression.And;
import org.opensearch.sql.ast.expression.Argument;
import org.opensearch.sql.ast.expression.AttributeList;
import org.opensearch.sql.ast.expression.Between;
import org.opensearch.sql.ast.expression.Case;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
Expand Down Expand Up @@ -173,6 +174,10 @@ public T visitCompare(Compare node, C context) {
return visitChildren(node, context);
}

public T visitBetween(Between node, C context) {
return visitChildren(node, context);
}

public T visitArgument(Argument node, C context) {
return visitChildren(node, context);
}
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/java/org/opensearch/sql/ast/dsl/AstDSL.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import org.opensearch.sql.ast.expression.AllFields;
import org.opensearch.sql.ast.expression.And;
import org.opensearch.sql.ast.expression.Argument;
import org.opensearch.sql.ast.expression.Between;
import org.opensearch.sql.ast.expression.Case;
import org.opensearch.sql.ast.expression.Cast;
import org.opensearch.sql.ast.expression.Compare;
Expand Down Expand Up @@ -59,6 +60,7 @@
import org.opensearch.sql.ast.tree.TableFunction;
import org.opensearch.sql.ast.tree.UnresolvedPlan;
import org.opensearch.sql.ast.tree.Values;
import org.opensearch.sql.expression.function.BuiltinFunctionName;

/**
* Class of static methods to create specific node instances.
Expand Down Expand Up @@ -320,6 +322,12 @@ public static UnresolvedExpression compare(
return new Compare(operator, left, right);
}

public static UnresolvedExpression between(UnresolvedExpression value,
UnresolvedExpression lowerBound,
UnresolvedExpression upperBound) {
return new Between(value, lowerBound, upperBound);
}

public static Argument argument(String argName, Literal argValue) {
return new Argument(argName, argValue);
}
Expand Down
40 changes: 40 additions & 0 deletions core/src/main/java/org/opensearch/sql/ast/expression/Between.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

package org.opensearch.sql.ast.expression;

import java.util.Arrays;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.opensearch.sql.ast.AbstractNodeVisitor;
import org.opensearch.sql.ast.Node;

/**
* Unresolved expression for BETWEEN.
*/
@Data
@EqualsAndHashCode(callSuper = false)
public class Between extends UnresolvedExpression {

/** Value for range check. */
private final UnresolvedExpression value;

/** Lower bound of the range (inclusive). */
private final UnresolvedExpression lowerBound;

/** Upper bound of the range (inclusive). */
private final UnresolvedExpression upperBound;

@Override
public List<? extends Node> getChild() {
return Arrays.asList(value, lowerBound, upperBound);
}

@Override
public <T, C> T accept(AbstractNodeVisitor<T, C> nodeVisitor, C context) {
return nodeVisitor.visitBetween(this, context);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,22 @@ public void qualified_name() {
);
}

@Test
public void between() {
assertAnalyzeEqual(
DSL.and(
DSL.gte(
DSL.ref("integer_value", INTEGER),
DSL.literal(20)),
DSL.lte(
DSL.ref("integer_value", INTEGER),
DSL.literal(30))),
AstDSL.between(
qualifiedName("integer_value"),
AstDSL.intLiteral(20),
AstDSL.intLiteral(30)));
}

@Test
public void case_value() {
assertAnalyzeEqual(
Expand Down
21 changes: 21 additions & 0 deletions docs/user/dql/expressions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ Operators
+----------------+----------------------------------------+
| NOT IN | NOT IN value list test |
+----------------+----------------------------------------+
| BETWEEN | Between a range (endpoint inclusive) |
+----------------+----------------------------------------+
| NOT BETWEEN | Not between a range (BETWEEN negation) |
+----------------+----------------------------------------+

Basic Comparison Operator
-------------------------
Expand Down Expand Up @@ -199,6 +203,23 @@ Here is an example for IN value test::
| True | True |
+---------------+-------------------+

BETWEEN range test
------------------

Here is an example for range test by BETWEEN expression::

os> SELECT
... 1 BETWEEN 1 AND 3,
... 4 BETWEEN 1 AND 3,
... 4 NOT BETWEEN 1 AND 3;
fetched rows / total rows = 1/1
+---------------------+---------------------+-------------------------+
| 1 BETWEEN 1 AND 3 | 4 BETWEEN 1 AND 3 | 4 NOT BETWEEN 1 AND 3 |
|---------------------+---------------------+-------------------------|
| True | False | True |
+---------------------+---------------------+-------------------------+


Function Call
=============

Expand Down
1 change: 1 addition & 0 deletions sql/src/main/antlr/OpenSearchSQLParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ predicate
: expressionAtom #expressionAtomPredicate
| left=predicate comparisonOperator right=predicate #binaryComparisonPredicate
| predicate IS nullNotnull #isNullPredicate
| predicate NOT? BETWEEN predicate AND predicate #betweenPredicate
| left=predicate NOT? LIKE right=predicate #likePredicate
| left=predicate REGEXP right=predicate #regexpPredicate
| predicate NOT? IN '(' expressions ')' #inPredicate
Expand Down
Loading

0 comments on commit 6c0af83

Please sign in to comment.