Skip to content

Commit 38b2268

Browse files
committed
Implement offline evaluation of map
1 parent 59eb4ae commit 38b2268

File tree

2 files changed

+21
-1
lines changed

2 files changed

+21
-1
lines changed

firebase-firestore/src/main/java/com/google/firebase/firestore/pipeline/evaluation.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
@file:JvmName("Evaluation")
12
package com.google.firebase.firestore.pipeline
23

34
import com.google.common.math.LongMath
@@ -7,6 +8,7 @@ import com.google.common.math.LongMath.checkedSubtract
78
import com.google.firebase.firestore.UserDataReader
89
import com.google.firebase.firestore.model.MutableDocument
910
import com.google.firebase.firestore.model.Values
11+
import com.google.firebase.firestore.model.Values.encodeValue
1012
import com.google.firebase.firestore.model.Values.isNanValue
1113
import com.google.firebase.firestore.util.Assert
1214
import com.google.firestore.v1.Value
@@ -393,6 +395,24 @@ internal val evaluateUnixSecondsToTimestamp = unaryFunction { seconds: Long ->
393395
EvaluateResult.timestamp(seconds, 0)
394396
}
395397

398+
// === Map Functions ===
399+
400+
internal val evaluateMap: EvaluateFunction = { params ->
401+
if (params.size % 2 != 0)
402+
throw Assert.fail("Function should have even number of params, but %d were given.", params.size)
403+
else block@{ input: MutableDocument ->
404+
val map: MutableMap<String, Value> = HashMap(params.size / 2)
405+
for (i in params.indices step 2) {
406+
val k = params[i](input).value ?: return@block EvaluateResultError
407+
if (!k.hasStringValue()) return@block EvaluateResultError
408+
val v = params[i + 1](input).value ?: return@block EvaluateResultError
409+
// It is against the API contract to include a key more than once.
410+
if (map.put(k.stringValue, v) != null) return@block EvaluateResultError
411+
}
412+
EvaluateResultValue(encodeValue(map))
413+
}
414+
}
415+
396416
// === Helper Functions ===
397417

398418
private inline fun catch(f: () -> EvaluateResult): EvaluateResult =

firebase-firestore/src/main/java/com/google/firebase/firestore/pipeline/expressions.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1786,7 +1786,7 @@ abstract class Expr internal constructor() {
17861786
FunctionExpr("str_concat", evaluateStrConcat, fieldName, *otherStrings)
17871787

17881788
internal fun map(elements: Array<out Expr>): Expr =
1789-
FunctionExpr("map", notImplemented, elements)
1789+
FunctionExpr("map", evaluateMap, elements)
17901790

17911791
/**
17921792
* Creates an expression that creates a Firestore map value from an input object.

0 commit comments

Comments
 (0)