44 */
55package org .opensearch .sql .opensearch .planner .physical ;
66
7+ import static org .opensearch .sql .calcite .utils .PlanUtils .ROW_NUMBER_COLUMN_FOR_DEDUP ;
8+
79import java .util .List ;
810import java .util .function .Predicate ;
911import org .apache .calcite .plan .RelOptRuleCall ;
1012import org .apache .calcite .plan .RelRule ;
1113import org .apache .calcite .rel .logical .LogicalFilter ;
1214import org .apache .calcite .rel .logical .LogicalProject ;
15+ import org .apache .calcite .rex .RexCall ;
16+ import org .apache .calcite .rex .RexInputRef ;
1317import org .apache .calcite .rex .RexLiteral ;
18+ import org .apache .calcite .rex .RexNode ;
1419import org .apache .calcite .rex .RexWindow ;
1520import org .apache .calcite .sql .SqlKind ;
1621import org .apache .logging .log4j .LogManager ;
@@ -33,14 +38,7 @@ public void onMatch(RelOptRuleCall call) {
3338 final LogicalFilter numOfDedupFilter = call .rel (1 );
3439 final LogicalProject projectWithWindow = call .rel (2 );
3540 final CalciteLogicalIndexScan scan = call .rel (3 );
36- RexLiteral numLiteral =
37- PlanUtils .findLiterals (numOfDedupFilter .getCondition (), true ).getFirst ();
38- Integer num = numLiteral .getValueAs (Integer .class );
39- if (num == null || num > 1 ) {
40- // TODO leverage inner_hits for num > 1
41- if (LOG .isDebugEnabled ()) {
42- LOG .debug ("Cannot pushdown the dedup since number of duplicate events is larger than 1" );
43- }
41+ if (!validFilter (numOfDedupFilter )) {
4442 return ;
4543 }
4644 List <RexWindow > windows = PlanUtils .getRexWindowFromProject (projectWithWindow );
@@ -61,6 +59,43 @@ public void onMatch(RelOptRuleCall call) {
6159 }
6260 }
6361
62+ private static boolean validFilter (LogicalFilter filter ) {
63+ // The condition kind is LESS_THAN_OR_EQUAL, safe to convert to RexCall
64+ List <RexNode > operandsOfCondition = ((RexCall ) filter .getCondition ()).getOperands ();
65+ RexNode leftOperand = operandsOfCondition .getFirst ();
66+ if (!(leftOperand instanceof RexInputRef ref )) {
67+ if (LOG .isDebugEnabled ()) {
68+ LOG .debug ("Cannot pushdown the dedup since the left operand is not RexInputRef" );
69+ }
70+ return false ;
71+ }
72+ String referenceName = filter .getRowType ().getFieldNames ().get (ref .getIndex ());
73+ if (!referenceName .equals (ROW_NUMBER_COLUMN_FOR_DEDUP )) {
74+ if (LOG .isDebugEnabled ()) {
75+ LOG .debug (
76+ "Cannot pushdown the dedup since the left operand is not {}" ,
77+ ROW_NUMBER_COLUMN_FOR_DEDUP );
78+ }
79+ return false ;
80+ }
81+ RexNode rightOperand = operandsOfCondition .getLast ();
82+ if (!(rightOperand instanceof RexLiteral numLiteral )) {
83+ if (LOG .isDebugEnabled ()) {
84+ LOG .debug ("Cannot pushdown the dedup since the right operand is not RexLiteral" );
85+ }
86+ return false ;
87+ }
88+ Integer num = numLiteral .getValueAs (Integer .class );
89+ if (num == null || num > 1 ) {
90+ // TODO leverage inner_hits for num > 1
91+ if (LOG .isDebugEnabled ()) {
92+ LOG .debug ("Cannot pushdown the dedup since number of duplicate events is larger than 1" );
93+ }
94+ return false ;
95+ }
96+ return true ;
97+ }
98+
6499 /**
65100 * Match fixed pattern:<br>
66101 * LogicalProject(remove _row_number_dedup_) <br>
0 commit comments