Skip to content

Commit 988ab2e

Browse files
authored
Support full expression in WHERE clauses (#3849)
* Support full expression in WHERE clauses Signed-off-by: Lantao Jin <ltjin@amazon.com> * add unit tests Signed-off-by: Lantao Jin <ltjin@amazon.com> * revert typo Signed-off-by: Lantao Jin <ltjin@amazon.com> * Fix IT Signed-off-by: Lantao Jin <ltjin@amazon.com> * Fix IT Signed-off-by: Lantao Jin <ltjin@amazon.com> * Address comment Signed-off-by: Lantao Jin <ltjin@amazon.com> --------- Signed-off-by: Lantao Jin <ltjin@amazon.com>
1 parent 0b4423e commit 988ab2e

7 files changed

Lines changed: 271 additions & 155 deletions

File tree

integ-test/src/test/java/org/opensearch/sql/ppl/WhereCommandIT.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public void testWhereWithMultiLogicalExpr() throws IOException {
4444
executeQuery(
4545
String.format(
4646
"source=%s "
47-
+ "| where firstname='Amber' lastname='Duke' age=32 "
47+
+ "| where firstname='Amber' and lastname='Duke' and age=32 "
4848
+ "| fields firstname, lastname, age",
4949
TEST_INDEX_ACCOUNT));
5050
verifyDataRows(result, rows("Amber", "Duke", 32));

ppl/src/main/antlr/OpenSearchPPLParser.g4

Lines changed: 43 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,8 @@ root
1414

1515
// statement
1616
pplStatement
17-
: dmlStatement
18-
;
19-
20-
dmlStatement
21-
: queryStatement
22-
| explainStatement
17+
: explainStatement
18+
| queryStatement
2319
;
2420

2521
queryStatement
@@ -43,9 +39,9 @@ subSearch
4339

4440
// commands
4541
pplCommands
46-
: searchCommand
47-
| describeCommand
42+
: describeCommand
4843
| showDataSourcesCommand
44+
| searchCommand
4945
;
5046

5147
commands
@@ -106,9 +102,7 @@ commandName
106102
;
107103

108104
searchCommand
109-
: (SEARCH)? fromClause # searchFrom
110-
| (SEARCH)? fromClause logicalExpression # searchFromFilter
111-
| (SEARCH)? logicalExpression fromClause # searchFilterFrom
105+
: (SEARCH)? (logicalExpression)* fromClause (logicalExpression)* # searchFrom
112106
;
113107

114108
describeCommand
@@ -373,7 +367,7 @@ sortbyClause
373367
;
374368

375369
evalClause
376-
: fieldExpression EQUAL expression
370+
: fieldExpression EQUAL logicalExpression
377371
;
378372

379373
eventstatsAggTerm
@@ -447,68 +441,52 @@ numericLiteral
447441
| floatLiteral
448442
;
449443

450-
// expressions
451-
expression
452-
: logicalExpression
453-
| comparisonExpression
454-
| valueExpression
455-
;
456-
457444
// predicates
458445
logicalExpression
459-
: LT_PRTHS logicalExpression RT_PRTHS # parentheticLogicalExpr
460-
| NOT logicalExpression # logicalNot
461-
| left = logicalExpression (AND)? right = logicalExpression # logicalAnd
446+
: NOT logicalExpression # logicalNot
447+
| left = logicalExpression AND right = logicalExpression # logicalAnd
462448
| left = logicalExpression XOR right = logicalExpression # logicalXor
463449
| left = logicalExpression OR right = logicalExpression # logicalOr
464-
| comparisonExpression # comparsion
465-
| booleanExpression # booleanExpr
466-
| relevanceExpression # relevanceExpr
467-
;
468-
469-
comparisonExpression
470-
: left = valueExpression comparisonOperator right = valueExpression # compareExpr
471-
| valueExpression NOT? IN valueList # inExpr
472-
| valueExpression NOT? BETWEEN valueExpression AND valueExpression # between
450+
| expression # logicalExpr
473451
;
474452

475-
valueExpressionList
476-
: valueExpression
477-
| LT_PRTHS valueExpression (COMMA valueExpression)* RT_PRTHS
453+
expression
454+
: valueExpression # valueExpr
455+
| relevanceExpression # relevanceExpr
456+
| left = expression comparisonOperator right = expression # compareExpr
457+
| expression NOT? IN valueList # inExpr
458+
| expression NOT? BETWEEN expression AND expression # between
478459
;
479460

480461
valueExpression
481-
: left = valueExpression binaryOperator = (STAR | DIVIDE | MODULE) right = valueExpression # binaryArithmetic
482-
| left = valueExpression binaryOperator = (PLUS | MINUS) right = valueExpression # binaryArithmetic
483-
| primaryExpression # valueExpressionDefault
484-
| positionFunction # positionFunctionCall
485-
| caseFunction # caseExpr
486-
| extractFunction # extractFunctionCall
487-
| getFormatFunction # getFormatFunctionCall
488-
| timestampFunction # timestampFunctionCall
489-
| LT_PRTHS valueExpression RT_PRTHS # parentheticValueExpr
490-
| LT_SQR_PRTHS subSearch RT_SQR_PRTHS # scalarSubqueryExpr
491-
| lambda # lambdaExpr
492-
;
493-
494-
primaryExpression
462+
: left = valueExpression binaryOperator = (STAR | DIVIDE | MODULE) right = valueExpression # binaryArithmetic
463+
| left = valueExpression binaryOperator = (PLUS | MINUS) right = valueExpression # binaryArithmetic
464+
| literalValue # literalValueExpr
465+
| functionCall # functionCallExpr
466+
| lambda # lambdaExpr
467+
| LT_SQR_PRTHS subSearch RT_SQR_PRTHS # scalarSubqueryExpr
468+
| valueExpression NOT? IN LT_SQR_PRTHS subSearch RT_SQR_PRTHS # inSubqueryExpr
469+
| LT_PRTHS valueExpression (COMMA valueExpression)* RT_PRTHS NOT? IN LT_SQR_PRTHS subSearch RT_SQR_PRTHS # inSubqueryExpr
470+
| EXISTS LT_SQR_PRTHS subSearch RT_SQR_PRTHS # existsSubqueryExpr
471+
| fieldExpression # fieldExpr
472+
| LT_PRTHS logicalExpression RT_PRTHS # nestedValueExpr
473+
;
474+
475+
functionCall
495476
: evalFunctionCall
496477
| dataTypeFunctionCall
497-
| fieldExpression
498-
| literalValue
478+
| positionFunctionCall
479+
| caseFunctionCall
480+
| timestampFunctionCall
481+
| extractFunctionCall
482+
| getFormatFunctionCall
499483
;
500484

501-
positionFunction
485+
positionFunctionCall
502486
: positionFunctionName LT_PRTHS functionArg IN functionArg RT_PRTHS
503487
;
504488

505-
booleanExpression
506-
: booleanFunctionCall # booleanFunctionCallExpr
507-
| valueExpressionList NOT? IN LT_SQR_PRTHS subSearch RT_SQR_PRTHS # inSubqueryExpr
508-
| EXISTS LT_SQR_PRTHS subSearch RT_SQR_PRTHS # existsSubqueryExpr
509-
;
510-
511-
caseFunction
489+
caseFunctionCall
512490
: CASE LT_PRTHS logicalExpression COMMA valueExpression (COMMA logicalExpression COMMA valueExpression)* (ELSE valueExpression)? RT_PRTHS
513491
;
514492

@@ -573,12 +551,7 @@ evalFunctionCall
573551

574552
// cast function
575553
dataTypeFunctionCall
576-
: CAST LT_PRTHS expression AS convertedDataType RT_PRTHS
577-
;
578-
579-
// boolean functions
580-
booleanFunctionCall
581-
: conditionFunctionName LT_PRTHS functionArgs RT_PRTHS
554+
: CAST LT_PRTHS logicalExpression AS convertedDataType RT_PRTHS
582555
;
583556

584557
convertedDataType
@@ -621,12 +594,12 @@ functionArg
621594

622595
functionArgExpression
623596
: lambda
624-
| expression
597+
| logicalExpression
625598
;
626599

627600
lambda
628-
: ident ARROW expression
629-
| LT_PRTHS ident (COMMA ident)+ RT_PRTHS ARROW expression
601+
: ident ARROW logicalExpression
602+
| LT_PRTHS ident (COMMA ident)+ RT_PRTHS ARROW logicalExpression
630603
;
631604

632605
relevanceArg
@@ -837,7 +810,7 @@ dateTimeFunctionName
837810
| YEARWEEK
838811
;
839812

840-
getFormatFunction
813+
getFormatFunctionCall
841814
: GET_FORMAT LT_PRTHS getFormatType COMMA functionArg RT_PRTHS
842815
;
843816

@@ -848,7 +821,7 @@ getFormatType
848821
| TIMESTAMP
849822
;
850823

851-
extractFunction
824+
extractFunctionCall
852825
: EXTRACT LT_PRTHS datetimePart FROM functionArg RT_PRTHS
853826
;
854827

@@ -883,7 +856,7 @@ datetimePart
883856
| complexDateTimePart
884857
;
885858

886-
timestampFunction
859+
timestampFunctionCall
887860
: timestampFunctionName LT_PRTHS simpleDateTimePart COMMA firstArg = functionArg COMMA secondArg = functionArg RT_PRTHS
888861
;
889862

ppl/src/main/java/org/opensearch/sql/ppl/parser/AstBuilder.java

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@
1515
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.FieldsCommandContext;
1616
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.HeadCommandContext;
1717
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.RenameCommandContext;
18-
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.SearchFilterFromContext;
1918
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.SearchFromContext;
20-
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.SearchFromFilterContext;
2119
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.SortCommandContext;
2220
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.StatsCommandContext;
2321
import static org.opensearch.sql.ppl.antlr.parser.OpenSearchPPLParser.TableFunctionContext;
@@ -42,6 +40,7 @@
4240
import org.opensearch.sql.ast.dsl.AstDSL;
4341
import org.opensearch.sql.ast.expression.Alias;
4442
import org.opensearch.sql.ast.expression.AllFieldsExcludeMeta;
43+
import org.opensearch.sql.ast.expression.And;
4544
import org.opensearch.sql.ast.expression.EqualTo;
4645
import org.opensearch.sql.ast.expression.Field;
4746
import org.opensearch.sql.ast.expression.Let;
@@ -139,19 +138,16 @@ public UnresolvedPlan visitSubSearch(OpenSearchPPLParser.SubSearchContext ctx) {
139138
/** Search command. */
140139
@Override
141140
public UnresolvedPlan visitSearchFrom(SearchFromContext ctx) {
142-
return visitFromClause(ctx.fromClause());
143-
}
144-
145-
@Override
146-
public UnresolvedPlan visitSearchFromFilter(SearchFromFilterContext ctx) {
147-
return new Filter(internalVisitExpression(ctx.logicalExpression()))
148-
.attach(visit(ctx.fromClause()));
149-
}
150-
151-
@Override
152-
public UnresolvedPlan visitSearchFilterFrom(SearchFilterFromContext ctx) {
153-
return new Filter(internalVisitExpression(ctx.logicalExpression()))
154-
.attach(visit(ctx.fromClause()));
141+
if (ctx.logicalExpression().isEmpty()) {
142+
return visitFromClause(ctx.fromClause());
143+
} else {
144+
return new Filter(
145+
ctx.logicalExpression().stream()
146+
.map(this::internalVisitExpression)
147+
.reduce(And::new)
148+
.get())
149+
.attach(visit(ctx.fromClause()));
150+
}
155151
}
156152

157153
/**

0 commit comments

Comments
 (0)