@@ -23,29 +23,22 @@ import org.elasticsearch.action.{ActionResponse, CompositeIndicesRequest}
23
23
import org .joor .Reflect .*
24
24
import tech .beshu .ror .accesscontrol .___domain .FieldLevelSecurity
25
25
import tech .beshu .ror .accesscontrol .___domain .FieldLevelSecurity .FieldsRestrictions
26
+ import tech .beshu .ror .es .EsVersion
26
27
import tech .beshu .ror .es .handler .response .FieldsFiltering
27
28
import tech .beshu .ror .es .handler .response .FieldsFiltering .NonMetadataDocumentFields
28
- import tech .beshu .ror .es .utils .*
29
+ import tech .beshu .ror .es .utils .EsqlRequestHelper . *
29
30
import tech .beshu .ror .syntax .*
30
31
import tech .beshu .ror .utils .ReflecUtils
31
32
import tech .beshu .ror .utils .ScalaOps .*
32
33
33
34
import java .lang .reflect .Modifier
34
- import java .util .List as JList
35
+ import java .time .ZoneOffset
36
+ import java .util .{Locale , List as JList }
35
37
import java .util .regex .Pattern
36
38
import scala .jdk .CollectionConverters .*
37
39
import scala .util .{Failure , Success , Try }
38
40
39
- object EsqlRequestHelper {
40
-
41
- final case class IndexTable (tableStringInQuery : String , indices : NonEmptyList [String ])
42
-
43
- sealed trait ModificationError
44
- object ModificationError {
45
- final case class UnexpectedException (ex : Throwable ) extends ModificationError
46
-
47
- implicit val show : Show [ModificationError ] = Show .show(_.toString)
48
- }
41
+ class EsqlRequestHelper (esVersion : EsVersion ) {
49
42
50
43
def modifyIndicesOf (request : CompositeIndicesRequest ,
51
44
requestTables : NonEmptyList [IndexTable ],
@@ -61,37 +54,21 @@ object EsqlRequestHelper {
61
54
.toEither.left.map(ModificationError .UnexpectedException .apply)
62
55
}
63
56
64
- sealed trait EsqlRequestClassification
65
- object EsqlRequestClassification {
66
- final case class IndicesRelated (tables : NonEmptyList [IndexTable ]) extends EsqlRequestClassification {
67
- lazy val indices : Set [String ] = tables.toCovariantSet.flatMap(_.indices.toIterable)
68
- }
69
- case object NonIndicesRelated extends EsqlRequestClassification
70
- }
71
-
72
- sealed trait ClassificationError
73
- object ClassificationError {
74
- final case class UnexpectedException (ex : Throwable ) extends ClassificationError
75
- case object ParsingException extends ClassificationError
76
- }
77
-
78
- import EsqlRequestClassification ._
57
+ import EsqlRequestClassification .*
79
58
80
59
def classifyEsqlRequest (request : CompositeIndicesRequest ): Either [ClassificationError , EsqlRequestClassification ] = {
81
- val result = Try {
82
- val query = getQuery(request)
83
- val params = ReflecUtils .invokeMethodCached(request, request.getClass, " params" )
84
-
85
- implicit val classLoader : ClassLoader = request.getClass.getClassLoader
86
- Try (new EsqlParser ().createStatement(query, params)) match {
87
- case Success (statement : IndicesRelatedStatement ) => Right (IndicesRelated (statement.indices))
88
- case Success (command : OtherCommand ) => Right (NonIndicesRelated )
89
- case Failure (_) => Left (ClassificationError .ParsingException : ClassificationError )
90
- }
60
+ createStatement(request) match {
61
+ case Right (statement : IndicesRelatedStatement ) => Right (IndicesRelated (statement.indices))
62
+ case Right (command : OtherCommand ) => Right (NonIndicesRelated )
63
+ case Left (error) => Left (error)
91
64
}
92
- result match {
93
- case Success (value) => value
94
- case Failure (exception) => Left (ClassificationError .UnexpectedException (exception))
65
+ }
66
+
67
+ private def createStatement (request : CompositeIndicesRequest ): Either [ClassificationError , Statement ] = {
68
+ implicit val classLoader : ClassLoader = request.getClass.getClassLoader
69
+ Try (new EsqlParser (esVersion)) match {
70
+ case Success (parser) => parser.createStatementBasedOn(request)
71
+ case Failure (ex) => Left (ClassificationError .UnexpectedException (ex))
95
72
}
96
73
}
97
74
@@ -106,6 +83,30 @@ object EsqlRequestHelper {
106
83
request
107
84
}
108
85
86
+ private def getParams (request : CompositeIndicesRequest ): AnyRef = {
87
+ ReflecUtils .invokeMethodCached(request, request.getClass, " params" )
88
+ }
89
+
90
+ private def createConfiguration (request : CompositeIndicesRequest ): AnyRef = {
91
+ val classLoader = request.getClass.getClassLoader
92
+ onClass(classLoader.loadClass(" org.elasticsearch.xpack.esql.session.Configuration" ))
93
+ .create(
94
+ ZoneOffset .UTC ,
95
+ Option (on(request).call(" locale" ).get[Locale ]).getOrElse(Locale .US ),
96
+ null , // at the moment it's not used anywhere, so it's null here - probably to be fixed in the future
97
+ " ROR" , // at the moment it's not used anywhere, so it's placeholder here - probably to be fixed in the future
98
+ on(request).call(" pragmas" ).get[AnyRef ],
99
+ Int .MaxValue ,
100
+ Int .MaxValue ,
101
+ getQuery(request),
102
+ on(request).call(" profile" ).get[AnyRef ],
103
+ on(request).call(" tables" ).get[AnyRef ],
104
+ System .nanoTime(),
105
+ Option (on(request).call(" allowPartialResults" ).get[Any ]).getOrElse(true )
106
+ )
107
+ .get[AnyRef ]()
108
+ }
109
+
109
110
private def newQueryFrom (oldQuery : String , requestTables : NonEmptyList [IndexTable ], finalIndices : Set [String ]) = {
110
111
requestTables.toList.foldLeft(oldQuery) {
111
112
case (currentQuery, table) =>
@@ -123,18 +124,43 @@ object EsqlRequestHelper {
123
124
currentQuery.replaceAll(Pattern .quote(originTable), finalIndices.mkString(" ," ))
124
125
}
125
126
126
- private final class EsqlParser (implicit classLoader : ClassLoader ) {
127
+ private final class EsqlParser (esVersion : EsVersion )
128
+ (implicit classLoader : ClassLoader ) {
127
129
128
130
private val underlyingObject =
129
131
onClass(classLoader.loadClass(" org.elasticsearch.xpack.esql.parser.EsqlParser" ))
130
132
.create().get[Any ]()
131
133
132
- def createStatement (query : String , params : AnyRef ): Statement = {
133
- val statement = on(underlyingObject).call(" createStatement" , query, params).get[Any ]
134
- NonEmptyList .fromList(indicesFrom(statement)) match {
135
- case Some (indices) => new IndicesRelatedStatement (statement, indices)
136
- case None => OtherCommand (statement)
134
+ def createStatementBasedOn (request : CompositeIndicesRequest ): Either [ClassificationError , Statement ] = {
135
+ val statement = esVersion match {
136
+ case v if v >= EsVersion (8 , 19 , 0 ) => createStatementForEsEqualOrAbove8190(request)
137
+ case v => createStatementForEsBelow8190(request)
137
138
}
139
+ statement.map { s =>
140
+ NonEmptyList .fromList(indicesFrom(s)) match {
141
+ case Some (indices) => new IndicesRelatedStatement (statement, indices)
142
+ case None => OtherCommand (statement)
143
+ }
144
+ }
145
+ }
146
+
147
+ private def createStatementForEsBelow8190 (request : CompositeIndicesRequest ) = {
148
+ for {
149
+ query <- Try (getQuery(request)).toEither.left.map(ClassificationError .UnexpectedException .apply)
150
+ params <- Try (getParams(request)).toEither.left.map(ClassificationError .UnexpectedException .apply)
151
+ statement <- Try (on(underlyingObject).call(" createStatement" , query, params).get[Any ])
152
+ .toEither.left.map(_ => ClassificationError .ParsingException )
153
+ } yield statement
154
+ }
155
+
156
+ private def createStatementForEsEqualOrAbove8190 (request : CompositeIndicesRequest ) = {
157
+ for {
158
+ query <- Try (getQuery(request)).toEither.left.map(ClassificationError .UnexpectedException .apply)
159
+ params <- Try (getParams(request)).toEither.left.map(ClassificationError .UnexpectedException .apply)
160
+ configuration <- Try (createConfiguration(request)).toEither.left.map(ClassificationError .UnexpectedException .apply)
161
+ statement <- Try (on(underlyingObject).call(" createStatement" , query, params, configuration).get[Any ])
162
+ .toEither.left.map(_ => ClassificationError .ParsingException )
163
+ } yield statement
138
164
}
139
165
140
166
private def indicesFrom (statement : Any ) = {
@@ -273,3 +299,29 @@ object EsqlRequestHelper {
273
299
}
274
300
}
275
301
}
302
+ object EsqlRequestHelper {
303
+
304
+ final case class IndexTable (tableStringInQuery : String , indices : NonEmptyList [String ])
305
+
306
+ sealed trait ModificationError
307
+ object ModificationError {
308
+ final case class UnexpectedException (ex : Throwable ) extends ModificationError
309
+
310
+ implicit val show : Show [ModificationError ] = Show .show(_.toString)
311
+ }
312
+
313
+ sealed trait EsqlRequestClassification
314
+ object EsqlRequestClassification {
315
+ final case class IndicesRelated (tables : NonEmptyList [IndexTable ]) extends EsqlRequestClassification {
316
+ lazy val indices : Set [String ] = tables.toCovariantSet.flatMap(_.indices.toIterable)
317
+ }
318
+ case object NonIndicesRelated extends EsqlRequestClassification
319
+ }
320
+
321
+ sealed trait ClassificationError
322
+ object ClassificationError {
323
+ final case class UnexpectedException (ex : Throwable ) extends ClassificationError
324
+ case object ParsingException extends ClassificationError
325
+ }
326
+
327
+ }
0 commit comments