@@ -243,15 +243,63 @@ internal val evaluateSubtract = arithmeticPrimitive(Math::subtractExact, Double:
243
243
244
244
internal val evaluateArray = variadicNullableValueFunction(EvaluateResult .Companion ::list)
245
245
246
- internal val evaluateEqAny = notImplemented
246
+ internal val evaluateEqAny = binaryFunction { list: List <Value >, value: Value ->
247
+ eqAny(value, list)
248
+ }
247
249
248
250
internal val evaluateNotEqAny = notImplemented
249
251
250
- internal val evaluateArrayContains = notImplemented
252
+ internal val evaluateArrayContains = binaryFunction { array: Value , value: Value ->
253
+ if (array.hasArrayValue()) eqAny(value, array.arrayValue.valuesList) else EvaluateResultError
254
+ }
251
255
252
- internal val evaluateArrayContainsAny = notImplemented
256
+ internal val evaluateArrayContainsAny =
257
+ binaryFunction { array: List <Value >, searchValues: List <Value > ->
258
+ var foundNull = false
259
+ for (value in array) for (search in searchValues) when (strictEquals(value, search)) {
260
+ true -> return @binaryFunction EvaluateResult .TRUE
261
+ false -> {}
262
+ null -> foundNull = true
263
+ }
264
+ return @binaryFunction if (foundNull) EvaluateResult .NULL else EvaluateResult .FALSE
265
+ }
253
266
254
- internal val evaluateArrayLength = notImplemented
267
+ internal val evaluateArrayContainsAll =
268
+ binaryFunction { array: List <Value >, searchValues: List <Value > ->
269
+ var foundNullAtLeastOnce = false
270
+ for (search in searchValues) {
271
+ var found = false
272
+ var foundNull = false
273
+ for (value in array) when (strictEquals(value, search)) {
274
+ true -> {
275
+ found = true
276
+ break
277
+ }
278
+ false -> {}
279
+ null -> foundNull = true
280
+ }
281
+ if (foundNull) {
282
+ foundNullAtLeastOnce = true
283
+ } else if (! found) {
284
+ return @binaryFunction EvaluateResult .FALSE
285
+ }
286
+ }
287
+ return @binaryFunction if (foundNullAtLeastOnce) EvaluateResult .NULL else EvaluateResult .TRUE
288
+ }
289
+
290
+ internal val evaluateArrayLength = unaryFunction { array: List <Value > ->
291
+ EvaluateResult .long(array.size)
292
+ }
293
+
294
+ private fun eqAny (value : Value , list : List <Value >): EvaluateResult {
295
+ var foundNull = false
296
+ for (element in list) when (strictEquals(value, element)) {
297
+ true -> return EvaluateResult .TRUE
298
+ false -> {}
299
+ null -> foundNull = true
300
+ }
301
+ return if (foundNull) EvaluateResult .NULL else EvaluateResult .FALSE
302
+ }
255
303
256
304
// === String Functions ===
257
305
@@ -490,6 +538,14 @@ private inline fun unaryFunction(crossinline timestampOp: (Timestamp) -> Evaluat
490
538
timestampOp,
491
539
)
492
540
541
+ @JvmName(" unaryArrayFunction" )
542
+ private inline fun unaryFunction (crossinline longOp : (List <Value >) -> EvaluateResult ) =
543
+ unaryFunctionType(
544
+ Value .ValueTypeCase .ARRAY_VALUE ,
545
+ { it.arrayValue.valuesList },
546
+ longOp,
547
+ )
548
+
493
549
private inline fun unaryFunction (
494
550
crossinline byteOp : (ByteString ) -> EvaluateResult ,
495
551
crossinline stringOp : (String ) -> EvaluateResult
@@ -559,6 +615,20 @@ private inline fun binaryFunction(
559
615
}
560
616
}
561
617
618
+ @JvmName(" binaryValueArrayFunction" )
619
+ private inline fun binaryFunction (
620
+ crossinline function : (Value , List <Value >) -> EvaluateResult
621
+ ): EvaluateFunction = binaryFunction { v1: Value , v2: Value ->
622
+ if (v2.hasArrayValue()) function(v1, v2.arrayValue.valuesList) else EvaluateResultError
623
+ }
624
+
625
+ @JvmName(" binaryArrayValueFunction" )
626
+ private inline fun binaryFunction (
627
+ crossinline function : (List <Value >, Value ) -> EvaluateResult
628
+ ): EvaluateFunction = binaryFunction { v1: Value , v2: Value ->
629
+ if (v1.hasArrayValue()) function(v1.arrayValue.valuesList, v2) else EvaluateResultError
630
+ }
631
+
562
632
@JvmName(" binaryStringStringFunction" )
563
633
private inline fun binaryFunction (crossinline function : (String , String ) -> EvaluateResult ) =
564
634
binaryFunctionType(
@@ -569,6 +639,18 @@ private inline fun binaryFunction(crossinline function: (String, String) -> Eval
569
639
function
570
640
)
571
641
642
+ @JvmName(" binaryArrayArrayFunction" )
643
+ private inline fun binaryFunction (
644
+ crossinline function : (List <Value >, List <Value >) -> EvaluateResult
645
+ ) =
646
+ binaryFunctionType(
647
+ Value .ValueTypeCase .ARRAY_VALUE ,
648
+ { it.arrayValue.valuesList },
649
+ Value .ValueTypeCase .ARRAY_VALUE ,
650
+ { it.arrayValue.valuesList },
651
+ function
652
+ )
653
+
572
654
private inline fun ternaryTimestampFunction (
573
655
crossinline function : (Timestamp , String , Long ) -> EvaluateResult
574
656
): EvaluateFunction = ternaryNullableValueFunction { timestamp: Value , unit: Value , number: Value ->
0 commit comments