Skip to content

Commit 6c85817

Browse files
committed
add trait Identifier, add / subtract interval as an arithmetic function, update parser
1 parent 6137001 commit 6c85817

File tree

13 files changed

+185
-172
lines changed

13 files changed

+185
-172
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ ThisBuild / organization := "app.softnetwork"
1919

2020
name := "softclient4es"
2121

22-
ThisBuild / version := "0.4.0"
22+
ThisBuild / version := "0.5.0"
2323

2424
ThisBuild / scalaVersion := scala213
2525

es6/sql-bridge/src/main/scala/app/softnetwork/elastic/sql/bridge/ElasticAggregation.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -89,10 +89,7 @@ object ElasticAggregation {
8989

9090
var aggPath = Seq[String]()
9191

92-
val (aggFuncs, transformFuncs) = identifier.functions.partition {
93-
case _: AggregateFunction => true
94-
case _ => false
95-
}
92+
val (aggFuncs, transformFuncs) = SQLFunctionUtils.aggregateAndTransformFunctions(identifier)
9693

9794
require(aggFuncs.size == 1, s"Multiple aggregate functions not supported: $aggFuncs")
9895

@@ -101,7 +98,7 @@ object ElasticAggregation {
10198
buildScript: (String, Script) => Aggregation
10299
): Aggregation = {
103100
if (transformFuncs.nonEmpty) {
104-
val scriptSrc = SQLFunctionUtils.buildPainless(Option(identifier), transformFuncs)
101+
val scriptSrc = SQLFunctionUtils.buildPainless(identifier)
105102
val script = Script(scriptSrc).lang("painless")
106103
buildScript(aggName, script)
107104
} else {

es6/sql-bridge/src/main/scala/app/softnetwork/elastic/sql/bridge/package.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ package object bridge {
101101
case _ =>
102102
_search scriptfields scriptFields.map { field =>
103103
scriptField(
104-
field.name,
104+
field.scriptName,
105105
Script(script = field.painless).lang("painless").scriptType("source")
106106
)
107107
}

sql/bridge/src/main/scala/app/softnetwork/elastic/sql/bridge/ElasticAggregation.scala

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -88,19 +88,16 @@ object ElasticAggregation {
8888

8989
var aggPath = Seq[String]()
9090

91-
val (aggFuncs, transformFuncs) = identifier.functions.partition {
92-
case _: AggregateFunction => true
93-
case _ => false
94-
}
91+
val (aggFuncs, transformFuncs) = SQLFunctionUtils.aggregateAndTransformFunctions(identifier)
9592

9693
require(aggFuncs.size == 1, s"Multiple aggregate functions not supported: $aggFuncs")
9794

9895
def aggWithFieldOrScript(
99-
buildField: (String, String) => Aggregation,
100-
buildScript: (String, Script) => Aggregation
101-
): Aggregation = {
96+
buildField: (String, String) => Aggregation,
97+
buildScript: (String, Script) => Aggregation
98+
): Aggregation = {
10299
if (transformFuncs.nonEmpty) {
103-
val scriptSrc = SQLFunctionUtils.buildPainless(Option(identifier), transformFuncs)
100+
val scriptSrc = SQLFunctionUtils.buildPainless(identifier)
104101
val script = Script(scriptSrc).lang("painless")
105102
buildScript(aggName, script)
106103
} else {

sql/bridge/src/main/scala/app/softnetwork/elastic/sql/bridge/package.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ package object bridge {
102102
case _ =>
103103
_search scriptfields scriptFields.map { field =>
104104
scriptField(
105-
field.name,
105+
field.scriptName,
106106
Script(script = field.painless).lang("painless").scriptType("source")
107107
)
108108
}

sql/src/main/scala/app/softnetwork/elastic/sql/SQLFunction.scala

Lines changed: 46 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,31 @@ package app.softnetwork.elastic.sql
33
import scala.util.matching.Regex
44

55
sealed trait SQLFunction extends SQLRegex {
6-
def toSQL(base: String): String = s"$sql($base)"
6+
def toSQL(base: String): String = if (base.nonEmpty) s"$sql($base)" else sql
77
}
88

99
object SQLFunctionUtils {
10-
def buildPainless(functions: List[SQLFunction]): String =
11-
buildPainless(None, functions)
10+
def aggregateAndTransformFunctions(
11+
identifier: Identifier
12+
): (List[SQLFunction], List[SQLFunction]) = {
13+
identifier.functions.partition {
14+
case _: AggregateFunction => true
15+
case _ => false
16+
}
17+
}
18+
19+
def transformFunctions(identifier: Identifier): List[SQLFunction] = {
20+
aggregateAndTransformFunctions(identifier)._2
21+
}
1222

1323
def buildPainless(
14-
painless: Option[PainlessScript] = None,
15-
functions: List[SQLFunction]
24+
identifier: Identifier
1625
): String = {
17-
val base = painless.map(_.painless).getOrElse("")
18-
val orderedFunctions = functions.reverse
26+
val base = identifier.painless
27+
val orderedFunctions = transformFunctions(identifier).reverse
1928
orderedFunctions.foldLeft(base) {
2029
case (expr, f: SQLTransformFunction[_, _]) => f.toPainless(expr)
21-
case (_, f: PainlessScript) => f.painless
30+
case (expr, f: PainlessScript) => s"$expr${f.painless}"
2231
case (expr, f) => f.toSQL(expr) // fallback
2332
}
2433
}
@@ -50,7 +59,7 @@ sealed trait SQLUnaryFunction[In <: SQLType, Out <: SQLType]
5059
def outputType: Out
5160
}
5261

53-
trait SQLBinaryFunction[In1 <: SQLType, In2 <: SQLType, Out <: SQLType]
62+
sealed trait SQLBinaryFunction[In1 <: SQLType, In2 <: SQLType, Out <: SQLType]
5463
extends SQLUnaryFunction[SQLAny, Out] { self: SQLFunction =>
5564

5665
override def inputType: SQLAny = SQLTypes.Any
@@ -64,6 +73,12 @@ sealed trait SQLTransformFunction[In <: SQLType, Out <: SQLType] extends SQLUnar
6473
def toPainless(base: String): String = s"$base$painless"
6574
}
6675

76+
sealed trait SQLArithmeticFunction[In <: SQLType, Out <: SQLType]
77+
extends SQLTransformFunction[In, Out] {
78+
def operator: ArithmeticOperator
79+
override def toSQL(base: String): String = s"$base$operator$sql"
80+
}
81+
6782
sealed trait ParametrizedFunction extends SQLFunction {
6883
def params: Seq[String]
6984
override def toSQL(base: String): String = {
@@ -155,6 +170,28 @@ object TimeInterval {
155170
}
156171
}
157172

173+
case class SQLAddInterval(interval: TimeInterval)
174+
extends SQLExpr(interval.sql)
175+
with SQLArithmeticFunction[SQLDateTime, SQLDateTime]
176+
with MathScript {
177+
override def operator: ArithmeticOperator = Add
178+
override def inputType: SQLDateTime = SQLTypes.DateTime
179+
override def outputType: SQLDateTime = SQLTypes.DateTime
180+
override def painless: String = s".plus(${interval.painless})"
181+
override def script: String = s"${operator.script}${interval.script}"
182+
}
183+
184+
case class SQLSubstractInterval(interval: TimeInterval)
185+
extends SQLExpr(interval.sql)
186+
with SQLArithmeticFunction[SQLDateTime, SQLDateTime]
187+
with MathScript {
188+
override def operator: ArithmeticOperator = Subtract
189+
override def inputType: SQLDateTime = SQLTypes.DateTime
190+
override def outputType: SQLDateTime = SQLTypes.DateTime
191+
override def painless: String = s".minus(${interval.painless})"
192+
override def script: String = s"${operator.script}${interval.script}"
193+
}
194+
158195
sealed trait DateTimeFunction extends SQLFunction
159196

160197
sealed trait DateFunction extends DateTimeFunction

sql/src/main/scala/app/softnetwork/elastic/sql/SQLGroupBy.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,9 @@ object BucketSelectorScript {
129129

130130
// build the RHS as a Painless ZonedDateTime (apply +/- interval using TimeInterval.painless)
131131
val rightBase = (arithOp, interval) match {
132-
case (Some(Plus), Some(i)) => s"$now.plus(${i.painless})"
133-
case (Some(Minus), Some(i)) => s"$now.minus(${i.painless})"
134-
case _ => now
132+
case (Some(Add), Some(i)) => s"$now.plus(${i.painless})"
133+
case (Some(Subtract), Some(i)) => s"$now.minus(${i.painless})"
134+
case _ => now
135135
}
136136

137137
val rightZdt = dateFunc match {

sql/src/main/scala/app/softnetwork/elastic/sql/SQLOperator.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,12 @@ package app.softnetwork.elastic.sql
22

33
trait SQLOperator extends SQLToken
44

5-
sealed trait ArithmeticOperator extends SQLOperator {
5+
sealed trait ArithmeticOperator extends SQLOperator with MathScript {
66
override def toString: String = s" $sql "
7+
override def script: String = sql
78
}
8-
case object Plus extends SQLExpr("+") with ArithmeticOperator
9-
case object Minus extends SQLExpr("-") with ArithmeticOperator
9+
case object Add extends SQLExpr("+") with ArithmeticOperator
10+
case object Subtract extends SQLExpr("-") with ArithmeticOperator
1011
case object Multiply extends SQLExpr("*") with ArithmeticOperator
1112
case object Divide extends SQLExpr("/") with ArithmeticOperator
1213
case object Modulo extends SQLExpr("%") with ArithmeticOperator

0 commit comments

Comments
 (0)