@@ -13,12 +13,12 @@ class PplNull(val flavor: "NULL" | "MISSING"):
13
13
*/
14
14
type PplBoolean = PplNull | Boolean
15
15
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).
18
18
*
19
19
* @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`.
22
22
*/
23
23
sealed trait Expr [T ]:
24
24
def serialize (): String
@@ -35,11 +35,24 @@ case class UnaryOp[A, B](op: String, arg: Expr[A]) extends Expr[B]:
35
35
36
36
case class BinaryOp [A , B ](left : Expr [A ], op : String , right : Expr [A ])
37
37
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
+
39
52
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))
43
56
44
57
/** `ExprGen` constructs ScalaCheck generators for `Expr`s.
45
58
*
0 commit comments