Skip to content

Commit 0ffdd7b

Browse files
committed
add Expression type, replace Int value with Long, fix numeric values defined within elasticsearch queries, add type for sql between
1 parent d7f736e commit 0ffdd7b

File tree

9 files changed

+491
-110
lines changed

9 files changed

+491
-110
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ case class ElasticQuery(filter: ElasticFilter) {
6464
case isNull: SQLIsNull => isNull
6565
case isNotNull: SQLIsNotNull => isNotNull
6666
case in: SQLIn[_, _] => in
67-
case between: SQLBetween => between
67+
case between: SQLBetween[String] => between
68+
case between: SQLBetween[Long] => between
69+
case between: SQLBetween[Double] => between
6870
case geoDistance: ElasticGeoDistance => geoDistance
6971
case matchExpression: ElasticMatch => matchExpression
7072
case other =>

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

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -105,56 +105,97 @@ package object bridge {
105105
)
106106
}
107107

108+
def applyNumericOp[A](n: SQLNumeric[_])(
109+
longOp: Long => A,
110+
doubleOp: Double => A
111+
): A = n.toEither.fold(longOp, doubleOp)
112+
108113
implicit def expressionToQuery(expression: SQLExpression): Query = {
109114
import expression._
110115
value match {
111-
case n: SQLNumeric[Any] @unchecked =>
116+
case n: SQLNumeric[_] if !aggregation =>
112117
operator match {
113118
case _: Ge.type =>
114119
maybeNot match {
115120
case Some(_) =>
116-
rangeQuery(identifier.name) lt n.sql
121+
applyNumericOp(n)(
122+
l => rangeQuery(identifier.name) lt l,
123+
d => rangeQuery(identifier.name) lt d
124+
)
117125
case _ =>
118-
rangeQuery(identifier.name) gte n.sql
126+
applyNumericOp(n)(
127+
l => rangeQuery(identifier.name) gte l,
128+
d => rangeQuery(identifier.name) gte d
129+
)
119130
}
120131
case _: Gt.type =>
121132
maybeNot match {
122133
case Some(_) =>
123-
rangeQuery(identifier.name) lte n.sql
134+
applyNumericOp(n)(
135+
l => rangeQuery(identifier.name) lte l,
136+
d => rangeQuery(identifier.name) lte d
137+
)
124138
case _ =>
125-
rangeQuery(identifier.name) gt n.sql
139+
applyNumericOp(n)(
140+
l => rangeQuery(identifier.name) gt l,
141+
d => rangeQuery(identifier.name) gt d
142+
)
126143
}
127144
case _: Le.type =>
128145
maybeNot match {
129146
case Some(_) =>
130-
rangeQuery(identifier.name) gt n.sql
147+
applyNumericOp(n)(
148+
l => rangeQuery(identifier.name) gt l,
149+
d => rangeQuery(identifier.name) gt d
150+
)
131151
case _ =>
132-
rangeQuery(identifier.name) lte n.sql
152+
applyNumericOp(n)(
153+
l => rangeQuery(identifier.name) lte l,
154+
d => rangeQuery(identifier.name) lte d
155+
)
133156
}
134157
case _: Lt.type =>
135158
maybeNot match {
136159
case Some(_) =>
137-
rangeQuery(identifier.name) gte n.sql
160+
applyNumericOp(n)(
161+
l => rangeQuery(identifier.name) gte l,
162+
d => rangeQuery(identifier.name) gte d
163+
)
138164
case _ =>
139-
rangeQuery(identifier.name) lt n.sql
165+
applyNumericOp(n)(
166+
l => rangeQuery(identifier.name) lt l,
167+
d => rangeQuery(identifier.name) lt d
168+
)
140169
}
141170
case _: Eq.type =>
142171
maybeNot match {
143172
case Some(_) =>
144-
not(termQuery(identifier.name, n.sql))
173+
applyNumericOp(n)(
174+
l => not(termQuery(identifier.name, l)),
175+
d => not(termQuery(identifier.name, d))
176+
)
145177
case _ =>
146-
termQuery(identifier.name, n.sql)
178+
applyNumericOp(n)(
179+
l => termQuery(identifier.name, l),
180+
d => termQuery(identifier.name, d)
181+
)
147182
}
148183
case _: Ne.type =>
149184
maybeNot match {
150185
case Some(_) =>
151-
termQuery(identifier.name, n.sql)
186+
applyNumericOp(n)(
187+
l => termQuery(identifier.name, l),
188+
d => termQuery(identifier.name, d)
189+
)
152190
case _ =>
153-
not(termQuery(identifier.name, n.sql))
191+
applyNumericOp(n)(
192+
l => not(termQuery(identifier.name, l)),
193+
d => not(termQuery(identifier.name, d))
194+
)
154195
}
155196
case _ => matchAllQuery()
156197
}
157-
case l: SQLLiteral =>
198+
case l: SQLLiteral if !aggregation =>
158199
operator match {
159200
case _: Like.type =>
160201
maybeNot match {
@@ -207,7 +248,7 @@ package object bridge {
207248
}
208249
case _ => matchAllQuery()
209250
}
210-
case b: SQLBoolean =>
251+
case b: SQLBoolean if !aggregation =>
211252
operator match {
212253
case _: Eq.type =>
213254
maybeNot match {
@@ -263,10 +304,32 @@ package object bridge {
263304
}
264305

265306
implicit def betweenToQuery(
266-
between: SQLBetween
307+
between: SQLBetween[String]
308+
): Query = {
309+
import between._
310+
val r = rangeQuery(identifier.name) gte fromTo.from.value lte fromTo.to.value
311+
maybeNot match {
312+
case Some(_) => not(r)
313+
case _ => r
314+
}
315+
}
316+
317+
implicit def betweenLongsToQuery(
318+
between: SQLBetween[Long]
319+
): Query = {
320+
import between._
321+
val r = rangeQuery(identifier.name) gte fromTo.from.value lte fromTo.to.value
322+
maybeNot match {
323+
case Some(_) => not(r)
324+
case _ => r
325+
}
326+
}
327+
328+
implicit def betweenDoublesToQuery(
329+
between: SQLBetween[Double]
267330
): Query = {
268331
import between._
269-
val r = rangeQuery(identifier.name) gte from.value lte to.value
332+
val r = rangeQuery(identifier.name) gte fromTo.from.value lte fromTo.to.value
270333
maybeNot match {
271334
case Some(_) => not(r)
272335
case _ => r

es6/sql-bridge/src/test/scala/app/softnetwork/elastic/sql/SQLQuerySpec.scala

Lines changed: 91 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ class SQLQuerySpec extends AnyFlatSpec with Matchers {
456456
| {
457457
| "range": {
458458
| "profiles.birthYear": {
459-
| "lte": "2000"
459+
| "lte": 2000
460460
| }
461461
| }
462462
| }
@@ -516,6 +516,93 @@ class SQLQuerySpec extends AnyFlatSpec with Matchers {
516516
|}""".stripMargin.replaceAll("\\s+", "")
517517
}
518518

519+
it should "perform query with group by and having" in {
520+
val select: ElasticSearchRequest =
521+
SQLQuery(groupByWithHaving)
522+
val query = select.query
523+
println(query)
524+
query shouldBe
525+
"""{
526+
| "query": {
527+
| "match_all": {}
528+
| },
529+
| "size": 0,
530+
| "sort": [
531+
| {
532+
| "customerid": {
533+
| "order": "desc"
534+
| }
535+
| },
536+
| {
537+
| "country": {
538+
| "order": "asc"
539+
| }
540+
| }
541+
| ],
542+
| "_source": true,
543+
| "aggs": {
544+
| "filtered_agg": {
545+
| "filter": {
546+
| "bool": {
547+
| "filter": [
548+
| {
549+
| "bool": {
550+
| "must_not": [
551+
| {
552+
| "term": {
553+
| "country": {
554+
| "value": "usa"
555+
| }
556+
| }
557+
| }
558+
| ]
559+
| }
560+
| },
561+
| {
562+
| "bool": {
563+
| "must_not": [
564+
| {
565+
| "term": {
566+
| "city": {
567+
| "value": "berlin"
568+
| }
569+
| }
570+
| }
571+
| ]
572+
| }
573+
| },
574+
| {
575+
| "match_all": {}
576+
| }
577+
| ]
578+
| }
579+
| },
580+
| "aggs": {
581+
| "country": {
582+
| "terms": {
583+
| "field": "country.keyword"
584+
| },
585+
| "aggs": {
586+
| "city": {
587+
| "terms": {
588+
| "field": "city.keyword"
589+
| },
590+
| "aggs": {
591+
| "cnt": {
592+
| "value_count": {
593+
| "field": "customerid"
594+
| }
595+
| }
596+
| }
597+
| }
598+
| }
599+
| }
600+
| }
601+
| }
602+
| }
603+
|}""".stripMargin.replaceAll("\\s+", "")
604+
}
605+
519606
it should "perform complex query" in {
520607
val select: ElasticSearchRequest =
521608
SQLQuery(
@@ -581,14 +668,14 @@ class SQLQuerySpec extends AnyFlatSpec with Matchers {
581668
| {
582669
| "range": {
583670
| "preparationTime": {
584-
| "lte": "120"
671+
| "lte": 120
585672
| }
586673
| }
587674
| },
588675
| {
589676
| "term": {
590677
| "deliveryPeriods.dayOfWeek": {
591-
| "value": "6"
678+
| "value": 6
592679
| }
593680
| }
594681
| },
@@ -690,7 +777,7 @@ class SQLQuerySpec extends AnyFlatSpec with Matchers {
690777
| {
691778
| "range": {
692779
| "products.stock": {
693-
| "gt": "0"
780+
| "gt": 0
694781
| }
695782
| }
696783
| },

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ case class ElasticQuery(filter: ElasticFilter) {
6464
case isNull: SQLIsNull => isNull
6565
case isNotNull: SQLIsNotNull => isNotNull
6666
case in: SQLIn[_, _] => in
67-
case between: SQLBetween => between
67+
case between: SQLBetween[String] => between
68+
case between: SQLBetween[Long] => between
69+
case between: SQLBetween[Double] => between
6870
case geoDistance: ElasticGeoDistance => geoDistance
6971
case matchExpression: ElasticMatch => matchExpression
7072
case other =>

0 commit comments

Comments
 (0)