Skip to content

Commit 548fdbb

Browse files
committed
Reduce parentheses produced by PPL expression generator
- Found opensearch-project/sql#3272 (comment) - Found opensearch-project/sql#3273 Signed-off-by: Simeon Widdis <[email protected]>
1 parent c113e07 commit 548fdbb

File tree

2 files changed

+23
-18
lines changed

2 files changed

+23
-18
lines changed

src/main/scala/queries/ppl/Expr.scala

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@ class PplNull(val flavor: "NULL" | "MISSING"):
1313
*/
1414
type PplBoolean = PplNull | Boolean
1515

16-
/** The `Expr` trait represents the top-level type for SQL expressions (e.g. the
17-
* argument to a `WHERE` clause, or a variable used in a `SELECT` clause).
16+
/** The `Expr` trait represents the top-level type for PPL expressions (e.g. the
17+
* argument to a `WHERE` clause, or a variable used in a `FIELDS` clause).
1818
*
1919
* @tparam T
20-
* The type that the expression evaluates to, used to avoid cases like
21-
* `SELECT * WHERE -NULL`.
20+
* The type that the expression evaluates to, used to avoid cases like `WHERE
21+
* -NULL`.
2222
*/
2323
sealed trait Expr[T]:
2424
def serialize(): String
@@ -35,11 +35,24 @@ case class UnaryOp[A, B](op: String, arg: Expr[A]) extends Expr[B]:
3535

3636
case class BinaryOp[A, B](left: Expr[A], op: String, right: Expr[A])
3737
extends Expr[B]:
38-
// We always wrap binary ops in parentheses to make precedence "just work"
38+
/** To avoid generating too many redundant parentheses, we only add
39+
* parentheses around the sides of binary operations where order is more
40+
* likely to matter.
41+
*
42+
* @see
43+
* https://github.com/opensearch-project/sql/issues/3272
44+
*/
45+
private def serializeWithMaybeParens(ex: Expr[A]): String = {
46+
ex match {
47+
case BinaryOp(left, op, right) => "(" + ex.serialize() + ")"
48+
case _ => ex.serialize()
49+
}
50+
}
51+
3952
override def serialize(): String =
40-
"(" + op
41-
.replace("$1", left.serialize())
42-
.replace("$2", right.serialize()) + ")"
53+
op
54+
.replace("$1", serializeWithMaybeParens(left))
55+
.replace("$2", serializeWithMaybeParens(right))
4356

4457
/** `ExprGen` constructs ScalaCheck generators for `Expr`s.
4558
*

src/main/scala/queries/ppl/SourceQuery.scala

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,8 @@ case class SourceQuery(
1010
) extends QuerySerializable {
1111
override def serialize(): String = {
1212
val whereClause = where match {
13-
case None => ""
14-
case Some(ex) => {
15-
val ser = ex.serialize()
16-
// PPL can't handle outer-level parentheses for WHERE clauses, so we remove them if we're using a binary
17-
// operator which generates them by default
18-
// Tracking: https://github.com/opensearch-project/sql/issues/3272
19-
if ex.isInstanceOf[BinaryOp[?, ?]] then
20-
"| WHERE " + ser.substring(1, ser.length - 1)
21-
else "| WHERE " + ser
22-
}
13+
case None => ""
14+
case Some(ex) => "| WHERE " + ex.serialize()
2315
}
2416
s"SOURCE = $index $whereClause"
2517
}

0 commit comments

Comments
 (0)