Skip to content

Commit

Permalink
core: allow comma to be escaped for exprs (#1688)
Browse files Browse the repository at this point in the history
Update stacklang parsing to allow comma and whitespace to
be preserved by using unicode escape sequences.
  • Loading branch information
brharrington authored Aug 21, 2024
1 parent 1872ec2 commit 0303c27
Show file tree
Hide file tree
Showing 8 changed files with 115 additions and 54 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
*/
package com.netflix.atlas.core.model

import com.netflix.atlas.core.stacklang.Interpreter

/** Base type for event expressions. */
sealed trait EventExpr extends Expr {

Expand Down Expand Up @@ -47,6 +49,6 @@ object EventExpr {

require(columns.nonEmpty, "set of columns cannot be empty")

override def toString: String = s"$query,(,${columns.mkString(",")},),:table"
override def toString: String = Interpreter.toString(query, columns, ":table")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.netflix.atlas.core.model

import com.netflix.atlas.core.stacklang.Interpreter
import com.netflix.atlas.core.util.BoundedPriorityBuffer
import com.netflix.atlas.core.util.Math

Expand Down Expand Up @@ -112,7 +113,7 @@ object FilterExpr {

if (!expr1.isGrouped) require(!expr2.isGrouped, "filter grouping must match expr grouping")

override def toString: String = s"$expr1,$expr2,:filter"
override def toString: String = Interpreter.toString(expr1, expr2, ":filter")

def dataExprs: List[DataExpr] = expr1.dataExprs ::: expr2.dataExprs

Expand Down Expand Up @@ -182,7 +183,7 @@ object FilterExpr {

require(k > 0, s"k must be positive ($k <= 0)")

override def toString: String = s"$expr,$stat,$k,:$opName"
override def toString: String = Interpreter.toString(expr, stat, k, s":$opName")

def dataExprs: List[DataExpr] = expr.dataExprs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import java.time.ZoneId
import java.time.ZoneOffset
import java.time.ZonedDateTime
import java.time.temporal.ChronoField

import com.netflix.atlas.core.model.DataExpr.AggregateFunction
import com.netflix.atlas.core.stacklang.Context
import com.netflix.atlas.core.stacklang.Interpreter
import com.netflix.atlas.core.util.ArrayHelper
import com.netflix.atlas.core.util.Hash
import com.netflix.atlas.core.util.Math
Expand All @@ -49,7 +49,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = expr.dataExprs

override def toString: String = s"$expr,$original,$replacement,:as"
override def toString: String = Interpreter.toString(expr, original, replacement, ":as")

def isGrouped: Boolean = expr.isGrouped

Expand Down Expand Up @@ -83,7 +83,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = Nil

override def toString: String = s"$v,:const"
override def toString: String = Interpreter.toString(v, ":const")

def isGrouped: Boolean = false

Expand All @@ -107,7 +107,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = Nil

override def toString: String = s":random"
override def toString: String = ":random"

def isGrouped: Boolean = false

Expand Down Expand Up @@ -135,7 +135,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = Nil

override def toString: String = s"$seed,:srandom"
override def toString: String = Interpreter.toString(seed, ":srandom")

def isGrouped: Boolean = false

Expand Down Expand Up @@ -215,7 +215,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = Nil

override def toString: String = s"$s,$e,:time-span"
override def toString: String = Interpreter.toString(s, e, ":time-span")

def isGrouped: Boolean = false

Expand Down Expand Up @@ -286,7 +286,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = expr.dataExprs

override def toString: String = s"$expr,$min,:$name"
override def toString: String = Interpreter.toString(expr, min, s":$name")

def isGrouped: Boolean = expr.isGrouped

Expand Down Expand Up @@ -314,7 +314,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = expr.dataExprs

override def toString: String = s"$expr,$max,:$name"
override def toString: String = Interpreter.toString(expr, max, s":$name")

def isGrouped: Boolean = expr.isGrouped

Expand Down Expand Up @@ -344,7 +344,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = expr.dataExprs

override def toString: String = s"$expr,:$name"
override def toString: String = Interpreter.toString(expr, s":$name")

def isGrouped: Boolean = expr.isGrouped

Expand Down Expand Up @@ -455,7 +455,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = expr1.dataExprs ::: expr2.dataExprs

override def toString: String = s"$expr1,$expr2,:$name"
override def toString: String = Interpreter.toString(expr1, expr2, s":$name")

def isGrouped: Boolean = expr1.isGrouped || expr2.isGrouped

Expand Down Expand Up @@ -679,7 +679,7 @@ object MathExpr {

def dataExprs: List[DataExpr] = expr.dataExprs

override def toString: String = s"$expr,:$name"
override def toString: String = Interpreter.toString(expr, s":$name")

def isGrouped: Boolean = false

Expand Down Expand Up @@ -765,7 +765,7 @@ object MathExpr {
}
}

override def toString: String = s"$expr,(,${keys.mkString(",")},),:by"
override def toString: String = Interpreter.toString(expr, keys, ":by")

def dataExprs: List[DataExpr] = expr.dataExprs

Expand Down Expand Up @@ -832,7 +832,7 @@ object MathExpr {
if (evalGroupKeys.isEmpty)
expr.af.query.toString
else
s"${expr.af.query},(,${evalGroupKeys.mkString(",")},),:by"
Interpreter.toString(expr.af.query, evalGroupKeys, ":by")
if (expr.offset.isZero)
s"$baseExpr,(,${pcts.mkString(",")},),:percentiles"
else
Expand Down
25 changes: 13 additions & 12 deletions atlas-core/src/main/scala/com/netflix/atlas/core/model/Query.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package com.netflix.atlas.core.model

import com.netflix.atlas.core.stacklang.Interpreter
import com.netflix.atlas.core.util.SmallHashMap
import com.netflix.spectator.impl.PatternMatcher

Expand Down Expand Up @@ -323,7 +324,7 @@ object Query {

def labelString: String = s"has($k)"

override def toString: String = s"$k,:has"
override def toString: String = Interpreter.toString(k, ":has")
}

case class Equal(k: String, v: String) extends KeyValueQuery {
Expand All @@ -332,7 +333,7 @@ object Query {

def labelString: String = s"$k=$v"

override def toString: String = s"$k,$v,:eq"
override def toString: String = Interpreter.toString(k, v, ":eq")
}

case class LessThan(k: String, v: String) extends KeyValueQuery {
Expand All @@ -341,7 +342,7 @@ object Query {

def labelString: String = s"$k<$v"

override def toString: String = s"$k,$v,:lt"
override def toString: String = Interpreter.toString(k, v, ":lt")
}

case class LessThanEqual(k: String, v: String) extends KeyValueQuery {
Expand All @@ -350,7 +351,7 @@ object Query {

def labelString: String = s"$k<=$v"

override def toString: String = s"$k,$v,:le"
override def toString: String = Interpreter.toString(k, v, ":le")
}

case class GreaterThan(k: String, v: String) extends KeyValueQuery {
Expand All @@ -359,7 +360,7 @@ object Query {

def labelString: String = s"$k>$v"

override def toString: String = s"$k,$v,:gt"
override def toString: String = Interpreter.toString(k, v, ":gt")
}

case class GreaterThanEqual(k: String, v: String) extends KeyValueQuery {
Expand All @@ -368,7 +369,7 @@ object Query {

def labelString: String = s"$k>=$v"

override def toString: String = s"$k,$v,:ge"
override def toString: String = Interpreter.toString(k, v, ":ge")
}

sealed trait PatternQuery extends KeyValueQuery {
Expand All @@ -384,7 +385,7 @@ object Query {

def labelString: String = s"$k~/^$v/"

override def toString: String = s"$k,$v,:re"
override def toString: String = Interpreter.toString(k, v, ":re")
}

case class RegexIgnoreCase(k: String, v: String) extends PatternQuery {
Expand All @@ -395,7 +396,7 @@ object Query {

def labelString: String = s"$k~/^$v/i"

override def toString: String = s"$k,$v,:reic"
override def toString: String = Interpreter.toString(k, v, ":reic")
}

case class In(k: String, vs: List[String]) extends KeyValueQuery {
Expand All @@ -406,7 +407,7 @@ object Query {

def labelString: String = s"$k in (${vs.mkString(",")})"

override def toString: String = s"$k,(,${vs.mkString(",")},),:in"
override def toString: String = Interpreter.toString(k, vs, ":in")

/** Convert this to a sequence of OR'd together equal queries. */
def toOrQuery: Query = {
Expand All @@ -428,7 +429,7 @@ object Query {

def labelString: String = s"(${q1.labelString}) and (${q2.labelString})"

override def toString: String = s"$q1,$q2,:and"
override def toString: String = Interpreter.toString(q1, q2, ":and")
}

case class Or(q1: Query, q2: Query) extends Query {
Expand All @@ -442,7 +443,7 @@ object Query {

def labelString: String = s"(${q1.labelString}) or (${q2.labelString})"

override def toString: String = s"$q1,$q2,:or"
override def toString: String = Interpreter.toString(q1, q2, ":or")
}

case class Not(q: Query) extends Query {
Expand All @@ -455,6 +456,6 @@ object Query {

def labelString: String = s"not(${q.labelString})"

override def toString: String = s"$q,:not"
override def toString: String = Interpreter.toString(q, ":not")
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
package com.netflix.atlas.core.model

import java.time.Duration

import com.netflix.atlas.core.algorithm.OnlineAlgorithm
import com.netflix.atlas.core.algorithm.OnlineDelay
import com.netflix.atlas.core.algorithm.OnlineDes
Expand All @@ -32,6 +31,7 @@ import com.netflix.atlas.core.algorithm.OnlineRollingCount
import com.netflix.atlas.core.algorithm.OnlineRollingMean
import com.netflix.atlas.core.algorithm.OnlineRollingSum
import com.netflix.atlas.core.algorithm.OnlineTrend
import com.netflix.atlas.core.stacklang.Interpreter

trait StatefulExpr extends TimeSeriesExpr {}

Expand All @@ -52,7 +52,7 @@ object StatefulExpr {
if (period <= 1) OnlineIgnoreN(0) else OnlineTrend(period)
}

override def toString: String = s"$expr,$window,:trend"
override def toString: String = Interpreter.toString(expr, window, ":trend")
}

/**
Expand All @@ -69,7 +69,7 @@ object StatefulExpr {
OnlineIntegral(Double.NaN)
}

override def toString: String = s"$expr,:integral"
override def toString: String = Interpreter.toString(expr, s":$name")
}

/**
Expand All @@ -83,7 +83,7 @@ object StatefulExpr {
OnlineDerivative(Double.NaN)
}

override def toString: String = s"$expr,:derivative"
override def toString: String = Interpreter.toString(expr, s":$name")
}

/**
Expand All @@ -98,7 +98,7 @@ object StatefulExpr {
OnlineDelay(n)
}

override def toString: String = s"$expr,$n,:delay"
override def toString: String = Interpreter.toString(expr, n, s":$name")
}

/**
Expand All @@ -112,7 +112,7 @@ object StatefulExpr {
OnlineRollingCount(n)
}

override def toString: String = s"$expr,$n,:rolling-count"
override def toString: String = Interpreter.toString(expr, n, s":$name")
}

/**
Expand All @@ -126,7 +126,7 @@ object StatefulExpr {
OnlineRollingMin(n)
}

override def toString: String = s"$expr,$n,:rolling-min"
override def toString: String = Interpreter.toString(expr, n, s":$name")
}

/**
Expand All @@ -140,7 +140,7 @@ object StatefulExpr {
OnlineRollingMax(n)
}

override def toString: String = s"$expr,$n,:rolling-max"
override def toString: String = Interpreter.toString(expr, n, s":$name")
}

/**
Expand All @@ -154,7 +154,7 @@ object StatefulExpr {
OnlineRollingMean(n, minNumValues)
}

override def toString: String = s"$expr,$n,$minNumValues,:rolling-mean"
override def toString: String = Interpreter.toString(expr, n, minNumValues, s":$name")
}

/**
Expand All @@ -168,7 +168,7 @@ object StatefulExpr {
OnlineRollingSum(n)
}

override def toString: String = s"$expr,$n,:rolling-sum"
override def toString: String = Interpreter.toString(expr, n, s":$name")
}

/**
Expand All @@ -184,7 +184,9 @@ object StatefulExpr {
OnlineDes(trainingSize, alpha, beta)
}

override def toString: String = s"$expr,$trainingSize,$alpha,$beta,:des"
override def toString: String = {
Interpreter.toString(expr, trainingSize, alpha, beta, s":$name")
}
}

/**
Expand Down Expand Up @@ -216,7 +218,9 @@ object StatefulExpr {
context.start / trainingStep * trainingStep + trainingStep
}

override def toString: String = s"$expr,$trainingSize,$alpha,$beta,:sdes"
override def toString: String = {
Interpreter.toString(expr, trainingSize, alpha, beta, s":$name")
}
}

/**
Expand Down
Loading

0 comments on commit 0303c27

Please sign in to comment.